Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
aa6dbec
fix(ci): redact sandboxed verification output
seonghobae Aug 5, 2026
06f1dcd
fix(ci): redact sandboxed web E2E output
seonghobae Aug 5, 2026
df52aa3
test(ci): cover secret-safe sandbox output
seonghobae Aug 5, 2026
014f30c
docs(doctoring): record sandbox log redaction boundary
seonghobae Aug 5, 2026
e165834
test(ci): require complete sandbox output redaction
seonghobae Aug 5, 2026
d71f133
fix(ci): redact every sandbox evidence publication sink
seonghobae Aug 5, 2026
27bb444
docs(ci): cover every sandbox evidence redaction sink
seonghobae Aug 5, 2026
f538053
test(ci): reject JSON-value credential disclosure
seonghobae Aug 5, 2026
4d61304
fix(ci): redact credential-shaped JSON values recursively
seonghobae Aug 5, 2026
03c9c94
test(ci): reject credential-shaped JSON object keys
seonghobae Aug 5, 2026
0fab425
fix(ci): redact credential-shaped JSON object keys
seonghobae Aug 5, 2026
87a6743
test(ci): bound assignment redaction scanning work
seonghobae Aug 5, 2026
5cf890b
perf(ci): make assignment redaction a bounded forward scan
seonghobae Aug 5, 2026
02d50bb
docs(ci): record recursive and bounded log redaction
seonghobae Aug 5, 2026
9f92c3d
build(security): align Strix dependency snapshots
seonghobae Aug 5, 2026
36f358d
docs(ci): record complete sandbox evidence redaction
seonghobae Aug 5, 2026
eb07d6b
test(ci): isolate provider-pattern JSON key coverage
seonghobae Aug 5, 2026
ea38588
test(ci): complete central redaction behavior coverage
seonghobae Aug 5, 2026
45dc74f
test(ci): require complete Authorization header redaction
seonghobae Aug 5, 2026
c832714
test(ci): preserve standalone auth scheme evidence safely
seonghobae Aug 5, 2026
13323b1
fix(ci): consume complete Authorization header values
seonghobae Aug 5, 2026
cb533a8
test(ci): cover complete redactor branch and entry contracts
seonghobae Aug 5, 2026
17d7d46
test(redaction): cover echoed separate secret options
seonghobae Aug 5, 2026
624403b
docs: design bounded sandbox output resources
seonghobae Aug 5, 2026
a7c5cca
docs: plan bounded sandbox output resources
seonghobae Aug 5, 2026
b301897
test(ci): require bounded sandbox subprocess output
seonghobae Aug 5, 2026
f6f0a07
feat(ci): bound child output with POSIX file limits
seonghobae Aug 5, 2026
d4065bf
fix(redaction): scrub echoed separate secret options
seonghobae Aug 5, 2026
4553a5a
test(ci): require bounded sandbox verification output
seonghobae Aug 5, 2026
43d5700
fix(ci): bound sandbox verification output
seonghobae Aug 5, 2026
b23fc23
test(ci): require bounded service and E2E output
seonghobae Aug 5, 2026
8461b7d
test(ci): require bounded pipe draining without child file limits
seonghobae Aug 5, 2026
23efe55
fix(ci): drain bounded subprocess pipes without limiting child files
seonghobae Aug 5, 2026
6f84d7f
fix(ci): bound sandbox service and E2E output
seonghobae Aug 5, 2026
93d2f00
test(ci): adapt redaction evidence to bounded output wrappers
seonghobae Aug 5, 2026
72b65e3
docs: correct bounded output design to pipe draining
seonghobae Aug 5, 2026
a978b20
docs: correct bounded output plan to continuous pipe drains
seonghobae Aug 5, 2026
f5cd2aa
docs(ci): record bounded sandbox output evidence
seonghobae Aug 5, 2026
091d27f
docs(ci): record bounded sandbox output behavior
seonghobae Aug 5, 2026
71f4c1f
Merge 091d27f13f873ea0af46cb33075eadc51465699c into d4065bf322279fae9…
seonghobae Aug 5, 2026
5ef4c52
fix(ci): separate bounded output from result evidence marker
seonghobae Aug 5, 2026
d4db1cd
fix(ci): separate E2E output from result evidence marker
seonghobae Aug 5, 2026
c00bd88
test(ci): complete bounded subprocess branch contracts
seonghobae Aug 5, 2026
c7b5515
test(ci): complete bounded web E2E branch contracts
seonghobae Aug 5, 2026
f12bb24
test(ci): finalize both bounded stream readers on failure
seonghobae Aug 5, 2026
3471bd9
test(ci): require service cleanup when capture startup fails
seonghobae Aug 5, 2026
915e281
fix(ci): finalize every bounded stream reader
seonghobae Aug 5, 2026
f7e2449
fix(ci): preserve sandbox result compatibility
seonghobae Aug 5, 2026
1f4e20f
fix(ci): reap failed service captures
seonghobae Aug 5, 2026
1924257
test(ci): align sandbox E2E doubles with bounded execution
seonghobae Aug 5, 2026
0faa3a8
test(ci): isolate readiness log-limit fixtures
seonghobae Aug 5, 2026
32c2738
fix(ci): align scheduled CodeQL action revisions
seonghobae Aug 5, 2026
945709b
test(ci): require capture startup cleanup
seonghobae Aug 5, 2026
41630d4
fix(ci): close service pipes when capture startup fails
seonghobae Aug 5, 2026
9ca0db5
test(ci): reproduce bounded capture startup orphaning
seonghobae Aug 5, 2026
2c9d405
ci: execute bounded capture startup regression
seonghobae Aug 5, 2026
7934b9a
ci: apply PR 767 capture-startup fix after red proof
seonghobae Aug 5, 2026
6e22bcc
fix(ci): make PR 767 repair exact-head and ref-safe
seonghobae Aug 5, 2026
b695ddd
fix(ci): make capture repair anchor-independent
seonghobae Aug 5, 2026
96018a7
fix(ci): reap partial bounded capture startup
github-actions[bot] Aug 5, 2026
c8a86dc
test(ci): repair capture-startup cleanup from verified red cases
seonghobae Aug 5, 2026
f44ec98
chore(ci): remove completed PR 767 branch writer
seonghobae Aug 5, 2026
17336a1
ci: verify PR 767 completed-process polling fix
seonghobae Aug 5, 2026
08ac103
ci: retry PR 767 completed-process polling repair
seonghobae Aug 5, 2026
97e22d7
ci: verify PR 767 polling and hermetic Git regressions
seonghobae Aug 5, 2026
a950818
ci(pr767): harden and rerun completed-process repair
seonghobae Aug 5, 2026
7eb5188
ci: finalize PR 767 polling and Git isolation repair
seonghobae Aug 5, 2026
e4ddf70
ci: run final PR 767 polling repair verification
seonghobae Aug 5, 2026
edb328e
test(coverage): expose sandbox entrypoint and cleanup gaps
seonghobae Aug 5, 2026
1420c6b
ci: stage exact-head PR 767 coverage timeout repair
seonghobae Aug 5, 2026
9b9d984
ci(pr767): bound and clean completed-process repair
seonghobae Aug 5, 2026
0bd3d88
fix(opencode): reap completed model attempts
github-actions[bot] Aug 5, 2026
36afcf8
chore(ci): remove superseded PR 767 timeout experiment
seonghobae Aug 5, 2026
a2475af
ci: trigger exact-head PR 767 review repairs
seonghobae Aug 5, 2026
16e1b61
ci(pr767): verify current review fixes
seonghobae Aug 5, 2026
1dee6d3
test(ci): isolate Git ownership contract from runner config
seonghobae Aug 5, 2026
dc05f73
ci: rerun PR 767 review repairs hermetically
seonghobae Aug 5, 2026
0d1c792
test(ci): reproduce unbounded capture join
seonghobae Aug 5, 2026
e5cdf11
test(ci): reproduce bare token over-redaction
seonghobae Aug 5, 2026
a91bc84
test(ci): prove service overflow blocks E2E execution
seonghobae Aug 5, 2026
ac1fa27
fix(ci): bound normal-path capture joins
seonghobae Aug 5, 2026
8f4dd8e
fix(ci): require dash prefix for option-value redaction
seonghobae Aug 5, 2026
8657f36
fix(test): use the real backend readiness option
seonghobae Aug 5, 2026
1e2f9b4
docs(ci): record final sandbox review repairs
seonghobae Aug 5, 2026
5fc9b64
docs(ci): bound inherited-pipe finalization evidence
seonghobae Aug 5, 2026
16143d1
docs(ci): preserve ordinary command operands during redaction
seonghobae Aug 5, 2026
24a1378
chore(pr767): remove superseded repair script
seonghobae Aug 5, 2026
0dc1979
chore(pr767): remove superseded isolation helper
seonghobae Aug 5, 2026
3bc52ff
chore(pr767): remove superseded repair workflow v2
seonghobae Aug 5, 2026
28a86e2
chore(pr767): remove superseded repair workflow
seonghobae Aug 5, 2026
a4674c4
chore(pr767): remove duplicate review-fix workflow
seonghobae Aug 5, 2026
3a04c83
ci(pr767): verify final sandbox evidence repairs
seonghobae Aug 5, 2026
45e4929
chore(ci): remove completed PR 767 cleanup workflow
seonghobae Aug 5, 2026
37e6f61
ci(pr767): focus sandbox evidence bounds on current main
seonghobae Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 221 additions & 0 deletions .github/workflows/one-shot-pr767-focus-current-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
name: One-shot PR 767 focused current-main rebuild

on:
push:
branches:
- fix/sandboxed-output-resource-bounds
paths:
- .github/workflows/one-shot-pr767-focus-current-main.yml

permissions:
contents: read

concurrency:
group: one-shot-pr767-focused-current-main
cancel-in-progress: true

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
focus-and-verify:
if: >-
github.repository == 'ContextualWisdomLab/.github'
&& github.ref == 'refs/heads/fix/sandboxed-output-resource-bounds'
runs-on: ubuntu-24.04
timeout-minutes: 60
permissions:
contents: write
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

- name: Checkout exact legacy head
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
fetch-depth: 0
persist-credentials: false

- name: Set up current stable Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
cache: pip
cache-dependency-path: requirements-opencode-review-ci-hashes.txt

- name: Rebuild focused sandbox security slice on protected main
env:
EXPECTED_HEAD: ${{ github.sha }}
shell: bash --noprofile --norc -e -o pipefail {0}
run: |
test "$(git rev-parse HEAD)" = "$EXPECTED_HEAD"
git fetch --no-tags origin main
legacy_tree="$EXPECTED_HEAD"
git checkout --detach origin/main
git checkout "$legacy_tree" -- \
docs/doctoring/sandboxed-command-log-redaction.md \
docs/doctoring/sandboxed-output-resource-bounds.md \
docs/superpowers/plans/2026-08-05-sandboxed-output-resource-bounds.md \
docs/superpowers/specs/2026-08-05-sandboxed-output-resource-bounds-design.md \
scripts/ci/bounded_subprocess.py \
scripts/ci/redact_sensitive_log.py \
scripts/ci/run_opencode_review_model_pool.sh \
scripts/ci/sandboxed_verify.py \
scripts/ci/sandboxed_web_e2e.py \
tests/test_bounded_subprocess.py \
tests/test_bounded_subprocess_capture_startup.py \
tests/test_bounded_subprocess_contract.py \
tests/test_opencode_model_pool_runner.py \
tests/test_redact_json_key_boundary.py \
tests/test_redact_sensitive_log_contract.py \
tests/test_sandboxed_entrypoint_and_cleanup_coverage.py \
tests/test_sandboxed_output_redaction.py \
tests/test_sandboxed_service_capture_startup.py \
tests/test_sandboxed_verify_output_limits.py \
tests/test_sandboxed_web_e2e.py \
tests/test_sandboxed_web_e2e_branch_contract.py \
tests/test_sandboxed_web_e2e_output_limits.py

cat >.github/workflows/sandboxed-evidence-quality-ci.yml <<'YAML'
name: Sandboxed Evidence Quality CI

on:
pull_request:
branches: [main]
paths:
- ".github/workflows/sandboxed-evidence-quality-ci.yml"
- "scripts/ci/bounded_subprocess.py"
- "scripts/ci/redact_sensitive_log.py"
- "scripts/ci/run_opencode_review_model_pool.sh"
- "scripts/ci/sandboxed_verify.py"
- "scripts/ci/sandboxed_web_e2e.py"
- "tests/test_bounded_subprocess*.py"
- "tests/test_opencode_model_pool_runner.py"
- "tests/test_redact*.py"
- "tests/test_sandboxed*.py"
- "requirements-opencode-review-ci-hashes.txt"
push:
branches: [main]
paths:
- ".github/workflows/sandboxed-evidence-quality-ci.yml"
- "scripts/ci/bounded_subprocess.py"
- "scripts/ci/redact_sensitive_log.py"
- "scripts/ci/run_opencode_review_model_pool.sh"
- "scripts/ci/sandboxed_verify.py"
- "scripts/ci/sandboxed_web_e2e.py"
- "tests/test_bounded_subprocess*.py"
- "tests/test_opencode_model_pool_runner.py"
- "tests/test_redact*.py"
- "tests/test_sandboxed*.py"
- "requirements-opencode-review-ci-hashes.txt"

concurrency:
group: sandboxed-evidence-quality-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
quality:
runs-on: ubuntu-24.04
timeout-minutes: 40
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout exact head
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
cache: pip
cache-dependency-path: requirements-opencode-review-ci-hashes.txt
- name: Install exact hash-locked tooling
run: >-
python -m pip install --disable-pip-version-check --require-hashes
-r requirements-opencode-review-ci-hashes.txt
- name: Run focused and repository-wide quality contracts
shell: bash --noprofile --norc -e -o pipefail {0}
run: |
python -m coverage erase
python -m coverage run --branch -m pytest -q
python -m coverage report --show-missing --fail-under=100
python -m interrogate --fail-under=100 scripts/ci
python -m compileall -q scripts tests
bash -n scripts/ci/run_opencode_review_model_pool.sh
git diff --check
YAML

python3 - <<'PY'
from pathlib import Path

changelog = Path("CHANGELOG.md")
source = changelog.read_text(encoding="utf-8")
entries = (
"- Redact credentials from every sandbox command, timeout, service-tail, "
"JSON, and review-evidence sink while preserving ordinary diagnostics.\n",
"- Bound command and long-running service output, terminate isolated process "
"groups on overflow, and emit deterministic resource-limit evidence without "
"capping unrelated repository artifacts.\n",
"- Add a permanent exact-head quality workflow enforcing 100% production "
"statement, branch, and docstring coverage for sandbox evidence controls.\n",
)
marker = "## [Unreleased]\n"
if marker not in source:
raise SystemExit("CHANGELOG is missing the Unreleased section")
missing = "".join(entry for entry in entries if entry not in source)
if missing:
source = source.replace(marker, marker + "\n" + missing, 1)
changelog.write_text(source, encoding="utf-8")
PY
rm -f .github/workflows/one-shot-pr767-focus-current-main.yml
git diff --check

- name: Install exact hash-locked tooling
shell: bash --noprofile --norc -e -o pipefail {0}
run: >-
python -m pip install --disable-pip-version-check --require-hashes
-r requirements-opencode-review-ci-hashes.txt

- name: Verify complete integrated quality contract
shell: bash --noprofile --norc -e -o pipefail {0}
run: |
python -m coverage erase
python -m coverage run --branch -m pytest -q
python -m coverage report --show-missing --fail-under=100
python -m interrogate --fail-under=100 scripts/ci
python -m compileall -q scripts tests
bash -n scripts/ci/run_opencode_review_model_pool.sh
git diff --check

- name: Publish focused current-main replacement
env:
EXPECTED_HEAD: ${{ github.sha }}
HEAD_BRANCH: ${{ github.ref_name }}
PUSH_TOKEN: ${{ github.token }}
shell: bash --noprofile --norc -e -o pipefail {0}
run: |
remote_head="$(git ls-remote origin "refs/heads/${HEAD_BRANCH}" | cut -f1)"
test "$remote_head" = "$EXPECTED_HEAD"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add --all
git diff --cached --quiet && { echo "No focused replacement generated" >&2; exit 1; }
git commit -m "fix(ci): secure and bound sandbox evidence streams"
auth_header="$(printf 'x-access-token:%s' "$PUSH_TOKEN" | base64 | tr -d '\n')"
echo "::add-mask::$auth_header"
git -c http.https://github.com/.extraheader="AUTHORIZATION: basic ${auth_header}" \
push --force-with-lease="refs/heads/${HEAD_BRANCH}:${EXPECTED_HEAD}" \
origin "HEAD:refs/heads/${HEAD_BRANCH}"
6 changes: 3 additions & 3 deletions .github/workflows/scheduled-security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ jobs:
with:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/init@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- name: Perform CodeQL Analysis
continue-on-error: true
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
category: "/language:${{ matrix.language }}-scheduled"

Expand Down Expand Up @@ -131,7 +131,7 @@ jobs:
- name: Upload Trivy SARIF to code scanning
if: always() && hashFiles('trivy-results.sarif') != ''
continue-on-error: true
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
uses: github/codeql-action/upload-sarif@d1ba80a13dd99fba24a470575428917156a28b43 # v4.37.5
with:
sarif_file: trivy-results.sarif
category: trivy-fs-scheduled
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Changelog

All notable changes to the ContextualWisdomLab central GitHub control plane are documented in this file.

The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versioned releases follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Security

- Upgrade the central Strix dependency snapshots to `aiohttp==3.14.3`, `cryptography==50.0.0`, and the compatible `pyOpenSSL==26.4.0` closure so the hard dependency gates contain no known affected releases.
- Redact credentials from every sandbox evidence publication sink, including completed and timed-out process output, service log tails, commands, reviewer notes, nested JSON values, and JSON object keys.
- Continuously drain sandbox child stdout/stderr into fixed-size final-suffix buffers, terminate isolated process groups on overflow, and persist only bounded service evidence so repository output cannot exhaust parent memory or runner log storage before redaction.

### Changed

- Add explicit 1 MiB per-stream command and 4 MiB per-service log budgets, stable output-limit exit code `123`, result-envelope limit evidence, and bounded seek-from-end service tails while preserving timeout `124` and readiness `125` semantics.

### Fixed

- Apply a finite 30-second bound to every normal-path output-reader join, finalize sibling captures before re-raising the first failure, and surface a stuck inherited pipe descriptor as `bounded output drain did not finish` instead of waiting until the outer CI timeout.
- Require a dash prefix before a sensitive command-line option consumes the following argument, while preserving redaction for `TOKEN=value`, `--token=value`, separate dashed credential options, and provider-shaped values.
- Prove with a sentinel-file regression that a service-log overflow is detected during readiness and prevents the E2E command from executing.
- Replace quadratic sensitive-assignment rescanning with a bounded forward scan so one long ordinary diagnostic token cannot cause disproportionate log-processing work.
- Avoid process-wide file-size limits that would incorrectly constrain coverage databases, compiled assets, archives, and other legitimate repository artifacts unrelated to stdout/stderr evidence.

### Documentation

- Add APA 7 doctoring for the sandbox command/output redaction boundary, structured diagnostics, availability controls, verification evidence, limitations, and rollback requirements.
- Add APA 7 doctoring for bounded subprocess pipe draining, process-group termination, bounded service evidence, exit-code precedence, realistic flood tests, limitations, and rollback requirements.
Loading
Loading