Skip to content

Commit 30e0e48

Browse files
committed
Enforce repository I/O security boundary
1 parent 155ce60 commit 30e0e48

76 files changed

Lines changed: 41828 additions & 3693 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/validate.yml

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,22 @@ jobs:
4444
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
4545
with:
4646
fetch-depth: 0
47+
persist-credentials: false
4748
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
4849
with:
4950
python-version: ${{ matrix.python-version }}
51+
- name: Harden ephemeral Linux runner home chain
52+
if: runner.os == 'Linux'
53+
shell: bash
54+
run: |
55+
set -euo pipefail
56+
mapfile -d '' -t account_home_chain < <(python -I -S -B -c 'import os, pathlib, pwd; home = pathlib.Path(pwd.getpwuid(os.geteuid()).pw_dir); current = pathlib.Path(home.anchor); chain = [current]; [(chain.append(current := current / component)) for component in home.parts[1:]]; print(*(str(path) for path in chain), sep="\0", end="\0")')
57+
sudo setfacl --remove-all --remove-default -- "${account_home_chain[@]}"
58+
sudo chmod go-w -- "${account_home_chain[@]}"
59+
account_home="${account_home_chain[${#account_home_chain[@]}-1]}"
60+
private_tmp="$account_home/codexqb-ci-tmp"
61+
install -d -m 0700 -- "$private_tmp"
62+
printf 'TMPDIR=%s\n' "$private_tmp" >> "$GITHUB_ENV"
5063
- name: Run the short dependency-free gate
5164
run: make check-fast
5265
- name: Run dependency-free unit contracts
@@ -72,9 +85,22 @@ jobs:
7285
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
7386
with:
7487
fetch-depth: 0
88+
persist-credentials: false
7589
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
7690
with:
7791
python-version: ${{ matrix.python-version }}
92+
- name: Harden ephemeral Linux runner home chain
93+
if: runner.os == 'Linux'
94+
shell: bash
95+
run: |
96+
set -euo pipefail
97+
mapfile -d '' -t account_home_chain < <(python -I -S -B -c 'import os, pathlib, pwd; home = pathlib.Path(pwd.getpwuid(os.geteuid()).pw_dir); current = pathlib.Path(home.anchor); chain = [current]; [(chain.append(current := current / component)) for component in home.parts[1:]]; print(*(str(path) for path in chain), sep="\0", end="\0")')
98+
sudo setfacl --remove-all --remove-default -- "${account_home_chain[@]}"
99+
sudo chmod go-w -- "${account_home_chain[@]}"
100+
account_home="${account_home_chain[${#account_home_chain[@]}-1]}"
101+
private_tmp="$account_home/codexqb-ci-tmp"
102+
install -d -m 0700 -- "$private_tmp"
103+
printf 'TMPDIR=%s\n' "$private_tmp" >> "$GITHUB_ENV"
78104
- name: Run Goal and Apply behavior gates
79105
run: make check-behavior
80106

@@ -85,9 +111,22 @@ jobs:
85111
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
86112
with:
87113
fetch-depth: 0
114+
persist-credentials: false
88115
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
89116
with:
90117
python-version: "3.13"
118+
- name: Harden ephemeral Linux runner home chain
119+
if: runner.os == 'Linux'
120+
shell: bash
121+
run: |
122+
set -euo pipefail
123+
mapfile -d '' -t account_home_chain < <(python -I -S -B -c 'import os, pathlib, pwd; home = pathlib.Path(pwd.getpwuid(os.geteuid()).pw_dir); current = pathlib.Path(home.anchor); chain = [current]; [(chain.append(current := current / component)) for component in home.parts[1:]]; print(*(str(path) for path in chain), sep="\0", end="\0")')
124+
sudo setfacl --remove-all --remove-default -- "${account_home_chain[@]}"
125+
sudo chmod go-w -- "${account_home_chain[@]}"
126+
account_home="${account_home_chain[${#account_home_chain[@]}-1]}"
127+
private_tmp="$account_home/codexqb-ci-tmp"
128+
install -d -m 0700 -- "$private_tmp"
129+
printf 'TMPDIR=%s\n' "$private_tmp" >> "$GITHUB_ENV"
91130
- name: Run package contract and extraction gates
92131
run: make check-package
93132
- name: Run public release privacy validation
@@ -129,10 +168,13 @@ jobs:
129168
test -f "$tmpdir/plugin/.codex-plugin/plugin.json"
130169
test ! -e "$tmpdir/plugin/tests"
131170
test ! -e "$tmpdir/source/CodexQB/.git"
132-
cd "$tmpdir/source/CodexQB"
133-
CODEXQB_VALIDATE_SKIP_UNITTESTS=1 \
134-
CODEXQB_VALIDATE_SKIP_BEHAVIOR_SMOKE=1 \
135-
bash scripts/validate.sh
171+
python3 -I -S -B scripts/run_extracted_validation.py \
172+
--expected-head "$GITHUB_SHA" \
173+
--zip "$tmpdir/CodexQB-source-worktree.zip" \
174+
--root "$tmpdir/source/CodexQB" \
175+
--profile static \
176+
--skip-unit-tests \
177+
--skip-behavior-smoke
136178
137179
required:
138180
name: required / CodexQB
@@ -161,9 +203,22 @@ jobs:
161203
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
162204
with:
163205
fetch-depth: 0
206+
persist-credentials: false
164207
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
165208
with:
166209
python-version: "3.13"
210+
- name: Harden ephemeral Linux runner home chain
211+
if: runner.os == 'Linux'
212+
shell: bash
213+
run: |
214+
set -euo pipefail
215+
mapfile -d '' -t account_home_chain < <(python -I -S -B -c 'import os, pathlib, pwd; home = pathlib.Path(pwd.getpwuid(os.geteuid()).pw_dir); current = pathlib.Path(home.anchor); chain = [current]; [(chain.append(current := current / component)) for component in home.parts[1:]]; print(*(str(path) for path in chain), sep="\0", end="\0")')
216+
sudo setfacl --remove-all --remove-default -- "${account_home_chain[@]}"
217+
sudo chmod go-w -- "${account_home_chain[@]}"
218+
account_home="${account_home_chain[${#account_home_chain[@]}-1]}"
219+
private_tmp="$account_home/codexqb-ci-tmp"
220+
install -d -m 0700 -- "$private_tmp"
221+
printf 'TMPDIR=%s\n' "$private_tmp" >> "$GITHUB_ENV"
167222
- name: Install release validation dependencies
168223
run: python -m pip install --requirement requirements-ci.txt
169224
- name: Run strict release validation

Makefile

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ SHELL := /bin/bash
22
PYTHON ?= python3
33
NO_BYTECODE = PYTHONDONTWRITEBYTECODE=1
44
PLATFORM_POLICY ?= auto
5+
CODEXQB_SKILL_ROOT := $(abspath plugins/codexqb/skills/codexqb)
6+
CODEXQB_LAUNCHER := $(CODEXQB_SKILL_ROOT)/scripts/skill_launcher.py
57

68
.PHONY: check check-fast check-static check-unit check-platform check-schema check-behavior check-package check-public-privacy check-release test export-plugin export-source export-plugin-worktree export-source-worktree export-source-package export-sanitized export-sanitized-worktree export-sanitized-source-package
79

@@ -27,8 +29,8 @@ check-platform:
2729
@set -euo pipefail; \
2830
tmpdir="$$(mktemp -d)"; \
2931
trap 'rm -rf "$$tmpdir"' EXIT; \
30-
$(NO_BYTECODE) $(PYTHON) plugins/codexqb/skills/codexqb/scripts/doctor.py --json > "$$tmpdir/doctor.json"; \
31-
$(NO_BYTECODE) $(PYTHON) plugins/codexqb/skills/codexqb/scripts/doctor.py; \
32+
$(NO_BYTECODE) $(PYTHON) -I -S -B "$(CODEXQB_LAUNCHER)" --active-skill-md "$(CODEXQB_SKILL_ROOT)/SKILL.md" --controller doctor -- --json > "$$tmpdir/doctor.json"; \
33+
$(NO_BYTECODE) $(PYTHON) -I -S -B "$(CODEXQB_LAUNCHER)" --active-skill-md "$(CODEXQB_SKILL_ROOT)/SKILL.md" --controller doctor --; \
3234
probe_output="$$( $(NO_BYTECODE) $(PYTHON) tests/platform/run_mount_identity_probe.py )"; \
3335
echo "$$probe_output"; \
3436
if [[ "$(PLATFORM_POLICY)" == "required" && "$$probe_output" != *"status=ready "* ]]; then \
@@ -71,7 +73,7 @@ check-release:
7173
$(NO_BYTECODE) $(PYTHON) scripts/verify_package_manifest.py --root "$$tmpdir/plugin" --strict-artifact --expected-artifact-type plugin; \
7274
test -f "$$tmpdir/plugin/.codex-plugin/plugin.json"; \
7375
$(NO_BYTECODE) $(PYTHON) scripts/verify_package_manifest.py --root "$$tmpdir/source/CodexQB" --strict-artifact --expected-artifact-type source; \
74-
cd "$$tmpdir/source/CodexQB" && CODEXQB_VALIDATE_SKIP_UNITTESTS=1 CODEXQB_VALIDATE_SKIP_BEHAVIOR_SMOKE=1 bash scripts/validate.sh
76+
$(NO_BYTECODE) $(PYTHON) -I -S -B scripts/run_extracted_validation.py --expected-head "$$(git rev-parse --verify HEAD)" --zip "$$tmpdir/CodexQB-source-release.zip" --root "$$tmpdir/source/CodexQB" --profile static --skip-unit-tests --skip-behavior-smoke
7577

7678
# Legacy full discovery remains available for maintainers. Gate-aware CI uses
7779
# the explicit targets above so schema/package/platform behavior cannot drift.

0 commit comments

Comments
 (0)