name: ci on: pull_request: push: branches: [main] jobs: trust-layer: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - run: cargo test --workspace - run: cargo clippy --workspace --all-targets -- -D warnings - run: cargo fmt --all --check # Phase 1: target gates run mechanically, and the bench workload # executes inside a NO-NETWORK container (SPEC §3.1/§10). The runner # is a shared VM — fine for gates; bench numbers for verdicts come # from calibrated hardware, not this job. target-gates-no-net: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: Toolchains for C/C++ targets run: sudo apt-get update -qq && sudo apt-get install -y -qq clang cmake - name: Fetch pinned targets run: | sh targets/fetch.sh comrak sh targets/fetch.sh tokei sh targets/fetch.sh cjson - name: Generate + verify pinned corpora run: | sh corpora/comrak/gen-corpus.sh sh corpora/tokei/gen-corpus.sh sh corpora/cjson/gen-corpus.sh - name: Build tokei baseline run: cargo build --release --manifest-path targets/tokei/workspace/Cargo.toml - name: Gates — tokei (Rust; corpus pin -> upstream tests -> golden replay) run: cargo run -p diff-test -- tokei - name: Gates — cjson (C; clang build -> Unity/CTest -> golden replay) run: cargo run -p diff-test -- cjson - name: Bench workload inside no-network container run: | docker run --rm --network=none \ -v "$PWD:/w" -w /w \ debian:bookworm-slim \ sh -c "targets/tokei/workspace/target/release/tokei --sort code corpora/tokei/input | sha256sum" # Informational: measure THIS runner's noise floor with the A/A + # injection harness and archive the evidence. A shared VM failing the # bars is expected — the artifact is the point (trust layer judges # environments empirically; verdict benches belong on bench-metal). runner-calibration: runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: Calibrate (reduced sessions, synthetic CPU-bound workload) run: | mkdir -p calib cargo run -p bench-runner -- calibrate \ --cmd "head -c 3000000 /dev/urandom | sha256sum" \ --sessions 20 --out calib/gh-runner-calibration.json \ | tee calib/summary.txt - uses: actions/upload-artifact@v4 if: always() with: name: runner-calibration path: calib/ # Informational: does perf work here, and with which event sources? perf-probe: runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v4 - name: Probe perf availability run: | sudo apt-get -qq update && sudo apt-get -qq install -y linux-tools-common linux-tools-generic || true PERF=$(ls /usr/lib/linux-tools/*/perf 2>/dev/null | head -1 || command -v perf || true) echo "perf binary: ${PERF:-none}" [ -n "$PERF" ] || exit 0 sudo sysctl -w kernel.perf_event_paranoid=1 || true echo "--- software clock sampling:" $PERF record -e cpu-clock -o /tmp/p.data -- sh -c 'i=0; while [ $i -lt 2000000 ]; do i=$((i+1)); done' && $PERF report -i /tmp/p.data --stdio | head -5 || echo "cpu-clock sampling unavailable" echo "--- hardware cycle counter:" $PERF stat -e cycles true 2>&1 | tail -3 || true # The peltier skill's contract: preflight must resolve the trust layer when # one is reachable, and REFUSE when it is not. The refusal is the # safety-critical path — a skill that silently degrades to a hand-rolled # timing loop is worse than no skill — so it is asserted here, not assumed. # Statistical outcomes are NOT asserted: a shared runner is too noisy for # that, which is the whole reason the skill calibrates before it claims. skill-preflight: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: SKILL.md conforms to the Agent Skills spec (both copies) run: | python3 - <<'PY' import re, sys, yaml, pathlib for skill in (".claude/skills/peltier", ".agents/skills/peltier"): p = pathlib.Path(skill) / "SKILL.md" text = p.read_text(encoding="utf-8") if not text.startswith("---\n"): sys.exit(f"{p}: must open with a --- frontmatter block") fm = yaml.safe_load(text.split("---", 2)[1]) # raises on malformed YAML body = text.split("---", 2)[2] for key in ("name", "description"): if not isinstance(fm.get(key), str) or not fm[key].strip(): sys.exit(f"{p}: frontmatter '{key}' must be a non-empty string") # agentskills.io spec: 1-64 chars, [a-z0-9-], no edge/double hyphens, # name == parent dir; description <= 1024 chars; body <= 500 lines. n = fm["name"] if not re.fullmatch(r"[a-z0-9]+(-[a-z0-9]+)*", n) or len(n) > 64: sys.exit(f"{p}: name '{n}' violates the Agent Skills name rules") if n != p.parent.name: sys.exit(f"{p}: name '{n}' != directory '{p.parent.name}'") if len(fm["description"]) > 1024: sys.exit(f"{p}: description exceeds 1024 chars") if len(body.splitlines()) > 500: sys.exit(f"{p}: body exceeds 500 lines") if "metadata" in fm and not ( isinstance(fm["metadata"], dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in fm["metadata"].items()) ): sys.exit(f"{p}: metadata must be a string-to-string map") print(f"{p}: spec OK (name={n}, description={len(fm['description'])} chars)") PY - name: .agents mirror is byte-identical to .claude canonical run: | diff -r .claude/skills/peltier .agents/skills/peltier echo "mirror identical" - name: Installer stamps both layouts + the ZeroClaw variant correctly run: | if sh scripts/install-skill.sh /tmp/no-such-dir 2>/dev/null; then echo "FAIL: installer accepted a nonexistent target"; exit 1 fi mkdir -p /tmp/consumer && sh scripts/install-skill.sh /tmp/consumer diff -r .claude/skills/peltier /tmp/consumer/.claude/skills/peltier diff -r .claude/skills/peltier /tmp/consumer/.agents/skills/peltier sh scripts/install-skill.sh --zeroclaw-variant /tmp/zc-variant test ! -e /tmp/zc-variant/scripts # script-less: ZeroClaw blocks script files test -f /tmp/zc-variant/SKILL.md diff -r .claude/skills/peltier/references /tmp/zc-variant/references echo "installer OK: both layouts identical to canonical; zeroclaw variant has no scripts/" - name: Preflight resolves inside a peltier checkout run: | sh .claude/skills/peltier/scripts/preflight.sh | tee /tmp/pf.txt grep -q '^STATUS=ok$' /tmp/pf.txt grep -q "^PELTIER_HOME=$PWD$" /tmp/pf.txt BR=$(sed -n 's/^BENCH_RUNNER=//p' /tmp/pf.txt); test -x "$BR" - name: Preflight REFUSES with no trust layer reachable run: | # The skill must be copied OUT of the checkout: preflight also walks # up from its own location, so running it in-place would find this # very repo and (correctly) resolve — testing nothing. cp -r .claude/skills/peltier /tmp/skillcopy cd /tmp && mkdir -p not-a-repo && cd not-a-repo set +e env -u PELTIER_HOME sh /tmp/skillcopy/scripts/preflight.sh > out.txt 2>&1 rc=$? set -e cat out.txt test "$rc" -ne 0 || { echo "FAIL: preflight did not refuse"; exit 1; } grep -q '^STATUS=refuse$' out.txt - name: Preflight works when consumed from another repo (PELTIER_HOME) run: | cd /tmp && mkdir -p other-project && cd other-project PELTIER_HOME="$GITHUB_WORKSPACE" \ sh "$GITHUB_WORKSPACE/.claude/skills/peltier/scripts/preflight.sh" | tee pf.txt grep -q '^STATUS=ok$' pf.txt - name: sh and ps1 preflights are byte-equivalent (two entry points, one contract) run: | # preflight.ps1 exists for hosts with no POSIX shell. Two # implementations of the same contract can drift, so both run here # on the same host and their stdout is byte-diffed on every path. # 1. in-checkout resolve sh .claude/skills/peltier/scripts/preflight.sh > /tmp/eq-sh.txt pwsh -NoProfile -File .claude/skills/peltier/scripts/preflight.ps1 > /tmp/eq-ps.txt diff /tmp/eq-sh.txt /tmp/eq-ps.txt # 2. refusal with no checkout reachable (copied out of the repo) cp -r .claude/skills/peltier /tmp/eqskill mkdir -p /tmp/eq-not-a-repo && cd /tmp/eq-not-a-repo set +e env -u PELTIER_HOME sh /tmp/eqskill/scripts/preflight.sh > sh.txt 2>&1; shrc=$? env -u PELTIER_HOME pwsh -NoProfile -File /tmp/eqskill/scripts/preflight.ps1 > ps.txt 2>&1; psrc=$? set -e test "$shrc" -ne 0 && test "$psrc" -ne 0 diff sh.txt ps.txt # 3. resolve via PELTIER_HOME from a foreign repo mkdir -p /tmp/eq-foreign && cd /tmp/eq-foreign PELTIER_HOME="$GITHUB_WORKSPACE" sh /tmp/eqskill/scripts/preflight.sh > sh2.txt PELTIER_HOME="$GITHUB_WORKSPACE" pwsh -NoProfile -File /tmp/eqskill/scripts/preflight.ps1 > ps2.txt diff sh2.txt ps2.txt echo "equivalence holds on all three paths" - name: The harness the skill drives actually runs (plumbing, not verdict) run: | BR=$(sed -n 's/^BENCH_RUNNER=//p' /tmp/pf.txt) cp .claude/skills/peltier/assets/accept.template.toml /tmp/accept.toml "$BR" --config /tmp/accept.toml compare \ --baseline 'sleep 0.02' --candidate 'sleep 0.02' | tee /tmp/cmp.txt grep -q 'speedup (baseline/candidate): median .*95% CI \[' /tmp/cmp.txt grep -q '^verdict: ' /tmp/cmp.txt - name: Noise floor of this runner (informational — A/A must find nothing) continue-on-error: true run: | BR=$(sed -n 's/^BENCH_RUNNER=//p' /tmp/pf.txt) "$BR" --config /tmp/accept.toml aa --cmd 'sleep 0.02' # The refusal doctrine must survive hosts with no POSIX shell: on a real # Windows runner, BOTH preflight entry points must refuse with a structured # STATUS=refuse — never a launch failure an agent could misread as license # to hand-roll a timing loop. Windows PowerShell 5.1 is tested separately # from pwsh because 5.1 misdecodes BOM-less UTF-8 (the ps1 source is pure # ASCII for exactly that reason). skill-preflight-windows: runs-on: windows-latest steps: - uses: actions/checkout@v4 - name: ps1 refuses natively (Windows PowerShell 5.1) shell: powershell run: | $out = & powershell -NoProfile -ExecutionPolicy Bypass -File .claude\skills\peltier\scripts\preflight.ps1 $out | Write-Output if ($LASTEXITCODE -eq 0) { throw "preflight did not refuse on Windows" } $joined = $out -join "`n" if ($joined -notlike "*STATUS=refuse*") { throw "no STATUS=refuse in output" } if ($joined -notlike "*unsupported host 'Windows'*") { throw "missing refusal reason" } - name: ps1 refuses natively (pwsh) shell: pwsh run: | $out = & pwsh -NoProfile -File .claude\skills\peltier\scripts\preflight.ps1 $out | Write-Output if ($LASTEXITCODE -eq 0) { throw "preflight did not refuse under pwsh" } if (($out -join "`n") -notlike "*STATUS=refuse*") { throw "no STATUS=refuse in output" } - name: sh entry point also refuses here (Git Bash) shell: bash run: | set +e sh .claude/skills/peltier/scripts/preflight.sh > out.txt 2>&1 rc=$? set -e cat out.txt test "$rc" -ne 0 grep -q '^STATUS=refuse$' out.txt