From 0e2175036c95a8f502357a64cfd21dd31d664353 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Sat, 11 Jul 2026 06:36:37 +0800 Subject: [PATCH 1/3] fix: restore lifecycle preflight workspace layout Co-Authored-By: Codex --- .github/workflows/reusable-drift-check.yml | 2 +- tests/test_reusable_drift_workflow.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reusable-drift-check.yml b/.github/workflows/reusable-drift-check.yml index 1e772ac..6ac08ad 100644 --- a/.github/workflows/reusable-drift-check.yml +++ b/.github/workflows/reusable-drift-check.yml @@ -159,7 +159,7 @@ jobs: uses: actions/download-artifact@v4 with: name: ${{ inputs.lifecycle_preflight_artifact }} - path: ${{ env.LIFECYCLE_LOCAL_ROOT }} + path: ${{ github.workspace }} - name: Build lifecycle performance snapshots run: quant-lifecycle monitor --domain ${{ inputs.strategy_domain }} diff --git a/tests/test_reusable_drift_workflow.py b/tests/test_reusable_drift_workflow.py index 105bca9..8333d65 100644 --- a/tests/test_reusable_drift_workflow.py +++ b/tests/test_reusable_drift_workflow.py @@ -44,6 +44,7 @@ def test_reusable_drift_workflow_enforces_lifecycle_preflight() -> None: assert "Download lifecycle preflight artifact" in workflow assert "actions/download-artifact@v4" in workflow assert "name: ${{ inputs.lifecycle_preflight_artifact }}" in workflow + assert "path: ${{ github.workspace }}" in workflow assert 'GH_TOKEN: ${{ github.token }}' in workflow assert 'os.environ["CODEX_AUDIT_ORG"] = owner' in workflow assert 'os.environ["CODEX_AUDIT_ORCHESTRATOR_REPO"] = repository' in workflow From 80685627b27413dac725ba5fe3d47b4008c98cf8 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Sat, 11 Jul 2026 06:38:47 +0800 Subject: [PATCH 2/3] fix: isolate lifecycle preflight restore Co-Authored-By: Codex --- .github/workflows/reusable-drift-check.yml | 32 +++++++++++++++++++++- tests/test_reusable_drift_workflow.py | 6 +++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-drift-check.yml b/.github/workflows/reusable-drift-check.yml index 6ac08ad..99010d0 100644 --- a/.github/workflows/reusable-drift-check.yml +++ b/.github/workflows/reusable-drift-check.yml @@ -159,7 +159,37 @@ jobs: uses: actions/download-artifact@v4 with: name: ${{ inputs.lifecycle_preflight_artifact }} - path: ${{ github.workspace }} + path: ${{ runner.temp }}/lifecycle-preflight + + - name: Restore lifecycle preflight inputs + if: inputs.lifecycle_preflight_artifact != '' + env: + PREFLIGHT_BUNDLE_ROOT: ${{ runner.temp }}/lifecycle-preflight + SNAPSHOT_CHECKOUT_PATH: ${{ inputs.snapshot_checkout_path }} + shell: bash + run: | + set -euo pipefail + case "$SNAPSHOT_CHECKOUT_PATH" in + external/*) ;; + *) echo "::error::snapshot_checkout_path must remain under external/"; exit 1 ;; + esac + if [[ "$SNAPSHOT_CHECKOUT_PATH" == *".."* ]]; then + echo "::error::snapshot_checkout_path must not contain traversal segments" + exit 1 + fi + if find "$PREFLIGHT_BUNDLE_ROOT" -type l -print -quit | grep -q .; then + echo "::error::lifecycle preflight artifact must not contain symlinks" + exit 1 + fi + lifecycle_source="$PREFLIGHT_BUNDLE_ROOT/data/lifecycle_store" + snapshot_source="$PREFLIGHT_BUNDLE_ROOT/$SNAPSHOT_CHECKOUT_PATH/data/output" + if [ ! -d "$lifecycle_source" ] || [ ! -d "$snapshot_source" ]; then + echo "::error::lifecycle preflight artifact is missing required allowlisted directories" + exit 1 + fi + mkdir -p "$LIFECYCLE_LOCAL_ROOT" "$GITHUB_WORKSPACE/$SNAPSHOT_CHECKOUT_PATH/data/output" + cp -a "$lifecycle_source/." "$LIFECYCLE_LOCAL_ROOT/" + cp -a "$snapshot_source/." "$GITHUB_WORKSPACE/$SNAPSHOT_CHECKOUT_PATH/data/output/" - name: Build lifecycle performance snapshots run: quant-lifecycle monitor --domain ${{ inputs.strategy_domain }} diff --git a/tests/test_reusable_drift_workflow.py b/tests/test_reusable_drift_workflow.py index 8333d65..916bb41 100644 --- a/tests/test_reusable_drift_workflow.py +++ b/tests/test_reusable_drift_workflow.py @@ -44,7 +44,11 @@ def test_reusable_drift_workflow_enforces_lifecycle_preflight() -> None: assert "Download lifecycle preflight artifact" in workflow assert "actions/download-artifact@v4" in workflow assert "name: ${{ inputs.lifecycle_preflight_artifact }}" in workflow - assert "path: ${{ github.workspace }}" in workflow + assert "path: ${{ runner.temp }}/lifecycle-preflight" in workflow + assert "Restore lifecycle preflight inputs" in workflow + assert "snapshot_checkout_path must remain under external/" in workflow + assert "lifecycle preflight artifact must not contain symlinks" in workflow + assert 'cp -a "$lifecycle_source/." "$LIFECYCLE_LOCAL_ROOT/"' in workflow assert 'GH_TOKEN: ${{ github.token }}' in workflow assert 'os.environ["CODEX_AUDIT_ORG"] = owner' in workflow assert 'os.environ["CODEX_AUDIT_ORCHESTRATOR_REPO"] = repository' in workflow From 5ec132aa3c6480505dc0c2d47ccb7aca106a145b Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Sat, 11 Jul 2026 06:45:54 +0800 Subject: [PATCH 3/3] fix: validate lifecycle restore destinations Co-Authored-By: Codex --- .github/workflows/reusable-drift-check.yml | 14 +++++++++++++- tests/test_reusable_drift_workflow.py | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reusable-drift-check.yml b/.github/workflows/reusable-drift-check.yml index 99010d0..de248b0 100644 --- a/.github/workflows/reusable-drift-check.yml +++ b/.github/workflows/reusable-drift-check.yml @@ -187,9 +187,21 @@ jobs: echo "::error::lifecycle preflight artifact is missing required allowlisted directories" exit 1 fi + snapshot_root="$GITHUB_WORKSPACE/$SNAPSHOT_CHECKOUT_PATH" + resolved_snapshot_root="$(realpath "$snapshot_root")" + case "$resolved_snapshot_root" in + "$GITHUB_WORKSPACE"/external/*) ;; + *) echo "::error::snapshot checkout resolved outside the external workspace"; exit 1 ;; + esac + if find "$snapshot_root" -type l -print -quit | grep -q .; then + echo "::error::snapshot checkout must not contain symlinks" + exit 1 + fi + snapshot_target="$snapshot_root/data/output" + rm -rf -- "$LIFECYCLE_LOCAL_ROOT" "$snapshot_target" mkdir -p "$LIFECYCLE_LOCAL_ROOT" "$GITHUB_WORKSPACE/$SNAPSHOT_CHECKOUT_PATH/data/output" cp -a "$lifecycle_source/." "$LIFECYCLE_LOCAL_ROOT/" - cp -a "$snapshot_source/." "$GITHUB_WORKSPACE/$SNAPSHOT_CHECKOUT_PATH/data/output/" + cp -a "$snapshot_source/." "$snapshot_target/" - name: Build lifecycle performance snapshots run: quant-lifecycle monitor --domain ${{ inputs.strategy_domain }} diff --git a/tests/test_reusable_drift_workflow.py b/tests/test_reusable_drift_workflow.py index 916bb41..a5231ac 100644 --- a/tests/test_reusable_drift_workflow.py +++ b/tests/test_reusable_drift_workflow.py @@ -48,6 +48,9 @@ def test_reusable_drift_workflow_enforces_lifecycle_preflight() -> None: assert "Restore lifecycle preflight inputs" in workflow assert "snapshot_checkout_path must remain under external/" in workflow assert "lifecycle preflight artifact must not contain symlinks" in workflow + assert "snapshot checkout resolved outside the external workspace" in workflow + assert "snapshot checkout must not contain symlinks" in workflow + assert 'rm -rf -- "$LIFECYCLE_LOCAL_ROOT" "$snapshot_target"' in workflow assert 'cp -a "$lifecycle_source/." "$LIFECYCLE_LOCAL_ROOT/"' in workflow assert 'GH_TOKEN: ${{ github.token }}' in workflow assert 'os.environ["CODEX_AUDIT_ORG"] = owner' in workflow