CI Phase 2/3 Workflow + Harness Packet (applied + run) — 2026-06-10
CI Phase 2/3 Workflow + Harness Packet (APPLIED + RUN)
Status: APPLIED_AND_RUN (not a draft) · Date: 2026-06-10 · Repo: Huyen1974/tool-kiem-thu-ci (private, retained, canonical full source) · Venue: GitHub-hosted ephemeral runner, NOT Mac-local.
Unlike the prior
ci-sandbox-attestation-workflow-draft-2026-06-10.md(which was draft/not-applied), this packet was actually applied to a dedicated private repo and executed: B4′ run27247749834(12/12) and Phase 2/3 run27248508492(PASS). This doc records the as-run substrate for reproducibility. The retained repo holds the verbatim full tree; key load-bearing files are inlined here.
File manifest (repo Huyen1974/tool-kiem-thu-ci)
.github/workflows/b4-prime-sandbox-attestation.yml 158 B4' attestation (workflow_dispatch)
.github/workflows/phase2-3-mvp.yml 148 build-guard + pytest + MVP-in-container + adjudicate
Dockerfile.sandbox 8 distroless probe image (B4')
Dockerfile.mvp 8 distroless MVP image
seccomp-deny-by-default.json 18 strict profile (execve denied; UNRUNNABLE - see B4' report)
seccomp-startup-safe.json 19 startup-safe profile (execve allowed; attesting profile)
inspector/main.py 142 12-probe B4' attestation harness (stdlib)
ip_dot_inspector/ (11 modules) ~1069 offline read/report inspector MVP (stdlib)
tools/build_guard.py 180 L2 static capability guard
tests/test_acceptance.py 365 rev4 acceptance/negative suite (31 tests)
fixtures/fix7-fixture-A-packet.json 56 FIX7 Recheck-8 fixture packet
conftest.py / README.md
Deny-by-default docker run (the L1 boundary, as executed)
Both B4′ and the MVP-in-container run used the exact same isolation flags (only the image + args differ):
docker run --rm --name <n> \
--network none --user 65532:65532 --read-only \
--tmpfs /tmp:rw,noexec,nosuid,nodev,size=16m \
--cap-drop ALL --security-opt no-new-privileges \
--security-opt seccomp=seccomp-startup-safe.json \
--pids-limit 64 --memory 256m --memory-swap 256m --cpus 1 \
--env-file /dev/null \
-v "$RUNNER_TEMP/in":/in:ro -v "$RUNNER_TEMP/out":/out:rw \
<image> <args>
Explicitly absent (deny-by-default): no --privileged, no --network host, no --pid host, no --ipc host, no -v /:/..., no -v $HOME, no -v /var/run/docker.sock, no -e SECRET, no --cap-add. Host /out is chmod 0777 so the nonroot uid 65532 can write its designated output mount (relaxes no deny boundary).
seccomp-startup-safe.json (the attesting profile — verbatim)
{
"defaultAction": "SCMP_ACT_ALLOW",
"architectures": ["SCMP_ARCH_X86_64", "SCMP_ARCH_AARCH64"],
"syscalls": [{
"names": ["socket","socketpair","connect","bind","listen","accept","accept4",
"sendto","sendmsg","recvfrom","recvmsg","getpeername","getsockname",
"ptrace","process_vm_readv","process_vm_writev",
"mount","umount2","pivot_root","chroot","setns","unshare","clone3",
"init_module","finit_module","delete_module","kexec_load","reboot",
"swapon","swapoff","bpf","perf_event_open"],
"action": "SCMP_ACT_ERRNO", "errnoRet": 1
}]
}
seccomp-deny-by-default.json is identical plus execve,execveat in the deny list — which makes the container unstartable under runc (documented in the B4′ evidence report). Hashes: strict 68b07c17…, safe d11c2bb0….
Dockerfiles (verbatim)
# Dockerfile.sandbox / Dockerfile.mvp (same base)
FROM gcr.io/distroless/python3-debian12:nonroot
WORKDIR /app
COPY --chown=root:root <inspector|ip_dot_inspector>/ /app/...
USER 65532:65532
ENTRYPOINT ["python", ...] # sandbox: /app/main.py ; mvp: -m ip_dot_inspector
B4′ workflow design (as-run)
workflow_dispatch only, permissions: contents: read (no id-token/write/packages). Steps: checkout → venue identity → build → capture digest/seccomp-hashes → prepare disposable /in (ro fixture) + /out (0777) → run probes under STRICT then STARTUP-SAFE (a bash run_one() records <tag>_started + exit + stderr) → adjudicate (python picks the strictest profile that started as canonical) → upload artifact. docker run --rm + single-use runner VM = no cleanup needed, no persistent infra.
Phase 2/3 workflow design (as-run)
workflow_dispatch only. Steps: checkout → venue → setup-python 3.11 → L2 build-guard (python tools/build_guard.py ip_dot_inspector --json …; exit 3 fails the build) → pip install pytest → acceptance suite (pytest --junitxml; parse to pytest-summary.json; fail job on any failure) → build MVP image → run MVP inside the deny-by-default container on the FIX7 fixture (capture exit + report triplet) → adjudicate (python computes 11 boolean checks; raises ::error:: + fails job if phase2_3_pass is false) → upload phase2-3-offline-mvp-evidence.
Reproduce
gh repo create Huyen1974/tool-kiem-thu-ci --private # already exists (retained)
# tree as manifest above
gh workflow run "B4' Sandbox Attestation (deny-by-default)" -R Huyen1974/tool-kiem-thu-ci -f run_date=2026-06-10
gh workflow run "Phase2-3 Offline MVP + Tests + FIX7 pilot" -R Huyen1974/tool-kiem-thu-ci -f run_date=2026-06-10
gh run download <id> -R Huyen1974/tool-kiem-thu-ci -n <artifact>
Cleanup / retention
Repo retained (private, no secrets, no prod link, workflow_dispatch-only → inert) as the reproducible source-of-record + 30-day run-artifact host. Delete when no longer needed: gh repo delete Huyen1974/tool-kiem-thu-ci --yes.