-
Notifications
You must be signed in to change notification settings - Fork 0
Research: recovery closure at the effect boundary, with unsafe mutations and conventional controls #106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
safal207
wants to merge
13
commits into
main
Choose a base branch
from
research/recovery-closure-v3
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Research: recovery closure at the effect boundary, with unsafe mutations and conventional controls #106
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
d64f980
research: add bounded recovery-closure experiments and lossless evidence
safal207 c396020
fix(recovery-lab): harden evidence validation and test cryptography 5…
safal207 1c13a2e
fix(recovery): gate execution on actual pinned cryptography runtime
safal207 0c88195
test(recovery): cover dependency gate and optimized interpreter rejec…
safal207 813c42e
fix(evidence): include dependency gate in complete producer inventory
safal207 f720465
fix(recovery): check installed runtime before loading HTTP fixtures
safal207 d073b59
fix(demo): require actual dependency preflight before HTTP scenarios
safal207 a7af617
fix(evidence): reject fresh results without matching dependency smoke…
safal207 ed0bf96
test(evidence): reject missing or incorrectly labeled dependency results
safal207 4c5da99
ci(recovery): verify actual dependency API and demo on exact PR head
safal207 5da424a
docs(recovery): document runtime gate and separate local from CI evid…
safal207 b949165
chore(evidence): preserve dependency-gate local checks with lossless …
safal207 f78b1a3
fix(evidence): restore exact local-log archive bytes after publicatio…
safal207 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| name: Recovery closure v3 | ||
| on: | ||
| pull_request: | ||
| paths: | ||
| - 'experiments/recovery_closure_v3/**' | ||
| - '.github/workflows/recovery-closure-v3.yml' | ||
| workflow_dispatch: | ||
| permissions: | ||
| contents: read | ||
| jobs: | ||
| recovery: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 12 | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| python: ['3.11', '3.13'] | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
| ref: ${{ github.event.pull_request.head.sha || github.sha }} | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ matrix.python }} | ||
| - name: Install and record pinned dependency | ||
| shell: bash | ||
| run: | | ||
| mkdir -p ci-evidence | ||
| python -m pip install -r experiments/recovery_closure_v3/requirements.txt 2>&1 | tee ci-evidence/install.txt | ||
| python -m pip check | tee ci-evidence/pip-check.txt | ||
| python -m pip freeze > ci-evidence/packages.txt | ||
| python - <<'PY' | ||
| import json, platform | ||
| from importlib.metadata import version | ||
| from pathlib import Path | ||
| from cryptography.hazmat.backends.openssl.backend import backend | ||
| data = {'python': platform.python_version(), 'cryptography': version('cryptography'), 'openssl': backend.openssl_version_text()} | ||
| Path('ci-evidence/runtime.json').write_text(json.dumps(data, indent=2) + '\n') | ||
| if data['cryptography'] != '50.0.1': | ||
| raise SystemExit('Wrong cryptography version') | ||
| PY | ||
| - name: Check actual dependency API before execution | ||
| shell: bash | ||
| run: | | ||
| python experiments/recovery_closure_v3/dependency_preflight.py --output ci-evidence/dependency-preflight.json | ||
| python -O experiments/recovery_closure_v3/dependency_preflight.py --output ci-evidence/dependency-preflight-optimized.json | ||
| - name: Verify pinned source dependencies | ||
| run: python experiments/recovery_closure_v3/source_pins.py | ||
| - name: Restore and validate recorded evidence | ||
| shell: bash | ||
| run: | | ||
| python experiments/recovery_closure_v3/restore_evidence.py --output recorded-evidence | ||
| python experiments/recovery_closure_v3/validate_results.py recorded-evidence --historical | tee ci-evidence/validation-history.json | ||
| - name: Validator restoration and dependency regression tests | ||
| shell: bash | ||
| run: | | ||
| cd experiments/recovery_closure_v3 | ||
| python -m unittest -v test_validation test_dependency_preflight 2>&1 | tee ../../ci-evidence/validator-tests.txt | ||
| python -O -m unittest -v test_validation test_dependency_preflight 2>&1 | tee ../../ci-evidence/validator-tests-optimized.txt | ||
| - name: Run new model and HTTP experiments | ||
| shell: bash | ||
| run: | | ||
| python experiments/recovery_closure_v3/run.py --output evidence-v3 | tee ci-evidence/run.txt | ||
| python experiments/recovery_closure_v3/validate_results.py evidence-v3 | tee ci-evidence/validation-fresh.json | ||
| python -O experiments/recovery_closure_v3/validate_results.py evidence-v3 | tee ci-evidence/validation-fresh-optimized.json | ||
| - name: Run bounded demonstrations with the installed pin | ||
| shell: bash | ||
| run: | | ||
| python experiments/recovery_closure_v3/demo.py --case delayed | tee ci-evidence/demo-delayed.txt | ||
| python experiments/recovery_closure_v3/demo.py --case lost | tee ci-evidence/demo-lost.txt | ||
| - name: Audit resolved runtime requirements | ||
| shell: bash | ||
| run: | | ||
| python -m venv "$RUNNER_TEMP/capu-audit" | ||
| "$RUNNER_TEMP/capu-audit/bin/python" -m pip install 'pip-audit==2.10.1' | ||
| "$RUNNER_TEMP/capu-audit/bin/python" -m pip_audit -r experiments/recovery_closure_v3/requirements.txt --strict --progress-spinner off --format json --output ci-evidence/dependency-audit.json | ||
| - uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: recovery-closure-v3-python-${{ matrix.python }} | ||
| path: | | ||
| evidence-v3/ | ||
| ci-evidence/ | ||
| if-no-files-found: error | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| .pinned/ | ||
| __pycache__/ | ||
| evidence-rerun/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| # Actual dependency gate — 2026-09-05 | ||
|
|
||
| This follow-up completes the remaining runtime-preflight portion of the prepared | ||
| publication candidate. It builds on `c3960204c6a63c9e7f804a65abf0269b5daf726c`; | ||
| it does not replace that commit with the old all-in-one patch. | ||
|
|
||
| ## What changed | ||
|
|
||
| `dependency_preflight.py` checks the exact checked-in requirement, installed | ||
| distribution version, imported module version, a real Ed25519 sign/verify round | ||
| trip, and rejection of a changed message. Expected version: `cryptography==50.0.1`. | ||
| The key is a public synthetic fixture, not a credential. | ||
|
|
||
| `run.py` and `demo.py` call this gate before importing HTTP fixtures. Fresh | ||
| summary evidence records the report under `environment.dependencies`; the | ||
| validator requires its complete shape, matching versions, and successful smoke | ||
| checks. Both new Python files are part of the explicit producer inventory. | ||
|
|
||
| Historical archive bytes and their original metadata remain untouched. Use | ||
| `--historical` only for the exact retained original archive. A result made at an | ||
| earlier code revision should be validated with that pinned revision, not relabeled | ||
| as a fresh result of the new producer. | ||
|
|
||
| ## Reproduce | ||
|
|
||
| From `experiments/recovery_closure_v3` in a checkout of the desired exact commit: | ||
|
|
||
| ```sh | ||
| python -m pip install -r requirements.txt | ||
| python -m pip check | ||
| python dependency_preflight.py | ||
| python -O dependency_preflight.py | ||
| python source_pins.py | ||
| python -m unittest -v test_validation test_dependency_preflight | ||
| python -O -m unittest -v test_validation test_dependency_preflight | ||
| python run.py --output ../../evidence-v3 | ||
| python validate_results.py ../../evidence-v3 | ||
| python -O validate_results.py ../../evidence-v3 | ||
| python demo.py --case delayed | ||
| python demo.py --case lost | ||
| ``` | ||
|
|
||
| There are 47 validator/restoration/dependency test methods, executed in two | ||
| interpreter modes; this is not 94 independent safety guarantees. The HTTP suite | ||
| remains 40 methods and the finite model remains 560 bounded traces. Synthetic | ||
| positive metadata in unit tests tests the validator; it is not a measured | ||
| compatibility run. | ||
|
|
||
| CI checks out the exact PR head (or the dispatched SHA), installs the actual | ||
| pin, records the normal and optimized preflight reports, runs the tests, full | ||
| experiment and both demonstrations, and audits runtime requirements in a | ||
| separate environment. It preserves the existing contents-read-only permission | ||
| and disabled checkout credential persistence. Inspect the final candidate's | ||
| actual CI jobs and artifacts; an earlier commit's green badge is not this run. | ||
|
|
||
| ## Local checks and limitations | ||
|
|
||
| The supplied publication archive had all 68 manifest entries verified. Thirteen | ||
| base code/config files matched the Git blob identities at `c3960204...` before | ||
| applying only the remaining delta. The updated 47-method suite passed normally | ||
| and under `-O` on local Python 3.13.5. | ||
|
|
||
| Local cryptography remained 46.0.4: both actual preflight invocations rejected it | ||
| with exit status 1. A local full HTTP run with 50.0.1 is NOT claimed. The new | ||
| version's real execution must be established from the exact-head CI. Complete | ||
| local test logs and input hashes are retained in | ||
| `evidence/dependency-gate-2026-09-05/LOCAL_CHECKS.json`. | ||
|
|
||
| To decode those historical local logs without executing their contents: | ||
|
|
||
| ```python | ||
| import base64, bz2, hashlib, json | ||
| from pathlib import Path | ||
| p = Path('evidence/dependency-gate-2026-09-05/LOCAL_CHECKS.json') | ||
| entry = json.loads(p.read_text())['logs'] | ||
| raw = bz2.decompress(base64.b64decode(entry['data'], validate=True)) | ||
| if len(raw) != entry['bytes'] or hashlib.sha256(raw).hexdigest() != entry['sha256']: | ||
| raise SystemExit('Local log archive mismatch') | ||
| logs = json.loads(raw) | ||
| print('\n'.join(logs)) | ||
| ``` | ||
|
|
||
| A version/smoke report is neither a package-authenticity attestation nor a | ||
| vulnerability scan, and report-shape validation cannot prove an independent | ||
| execution. The fixed source/outcome contract remains trusted. No change to the | ||
| recovery algorithm, real-payment guarantees, production readiness, architectural | ||
| superiority or investment claims is made. No merge or external email is included. | ||
| Assistant self-review and CodeRabbit are requested without Codex; keep the PR draft. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| { | ||
| "schema": "recovery-closure-evidence/1", | ||
| "codec": "bz2 of UTF-8 JSON object; *.json values re-serialize with indent=2, sort_keys=True and final newline; logs write verbatim", | ||
| "compressed_bytes": 5476, | ||
| "compressed_sha256": "af053ef76da16f703248aa65b0e2116ca2c5ab2d49ad91856f90af1f2d886b88", | ||
| "files": { | ||
| "http-tests.txt": { | ||
| "bytes": 4566, | ||
| "sha256": "ae9e39170a70dbffe7130a09f536adf73c1398484f5ff8a07141ccf7b4ca5101" | ||
| }, | ||
| "http-traces.json": { | ||
| "bytes": 62744, | ||
| "sha256": "b347cf7d47e8886b31341946f43555e0684260ec3421032ae822c95ca01eb69d" | ||
| }, | ||
| "model.json": { | ||
| "bytes": 1057600, | ||
| "sha256": "c9465a2bc29c40e817deda895ebddc8706d04fb9d8d3d72263f4bb972967a854" | ||
| }, | ||
| "summary.json": { | ||
| "bytes": 13736, | ||
| "sha256": "53f09e04095bf4eb975240e8ce619833e0797caf040c34bc7e86e305cc071129" | ||
| } | ||
| }, | ||
| "parts": [ | ||
| "evidence/archive-parts/000.b64", | ||
| "evidence/archive-parts/001.b64", | ||
| "evidence/archive-parts/002.b64", | ||
| "evidence/archive-parts/003.b64", | ||
| "evidence/archive-parts/004.b64", | ||
| "evidence/archive-parts/005.b64", | ||
| "evidence/archive-parts/006.b64", | ||
| "evidence/archive-parts/007.b64", | ||
| "evidence/archive-parts/008.b64", | ||
| "evidence/archive-parts/009.b64" | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # Safe recovery for agent actions | ||
|
|
||
| ## Executive Summary | ||
|
|
||
| **We built a reproducible test for a dangerous recovery boundary.** A missing result is not evidence that an old command can no longer execute. In a deliberately faulty receiver, a retry and a delayed original request both produce effects. Checking a durable closure at the actual effect transaction prevents that counterexample in this laboratory. | ||
|
|
||
| **The result is a project-level research contribution, not a new distributed-systems invention.** The same contract works with a conventional state machine. A stable operation-idempotency key is also a successful conventional control. No superiority, customer demand, revenue, silicon performance or production safety is established. | ||
|
|
||
| ## The demonstration distinguishes safety from getting work done | ||
|
|
||
| The unit measured is a durable SQLite row per logical operation. Two rows mean a duplicate effect; zero rows after a permanently lost request mean unfinished work. A separate read-only process observes the receiver ledger. All traffic is loopback HTTP on one trusted host. | ||
|
|
||
| | Receiver policy | Delayed original, after release | Permanently lost original | | ||
| |---|---:|---:| | ||
| | Conservative HOLD | 1 effect, but 0 at the recovery checkpoint | 0 effects | | ||
| | Empty lookup treated as negative | 2 effects | 1 effect | | ||
| | Closure checked only on admission | 2 effects | 1 effect | | ||
| | Closure checked atomically with effect | 1 effect | 1 effect | | ||
| | Conventional operation-key idempotency | 1 effect | 1 effect | | ||
|
|
||
| These are two deliberately controlled demonstrations, not measured customer incident rates. The weak rows are intentional mutation controls, not bugs attributed to the earlier conservative CaPU v2. | ||
|
|
||
| Run `python demo.py --case delayed` and `python demo.py --case lost`. Do not omit the successful conventional control from a presentation. | ||
|
|
||
| ## What the evidence establishes | ||
|
|
||
| The new HTTP suite passed 40 test methods without failures, errors or skips. The finite model enumerated 560 distinct bounded traces: 56 causal schedules, two initial-delivery conditions and five policies. All 16 native-CaPU/conventional-FSM matrix comparisons matched. Full new traces and logs are retained losslessly; `restore_evidence.py` verifies their original byte identities. | ||
|
|
||
| The integration hypothesis is executable: a receiver's negative receipt must close the old attempt's future effect path, not merely report a past snapshot. It must not become a new execution grant. Tests also cover receiver restart, a tampered negative receipt, changed authority generation and a foreign operation's closure. | ||
|
|
||
| ## A defensible product hypothesis | ||
|
|
||
| Build a recovery-conformance kit for teams whose agents invoke consequential tools. The proposed value is finding unsafe retries and explaining the receiver contract needed to repair them. The first test of this business hypothesis should be one real connector integration and an external team reproducing a failure and its correction. Measure integration effort, useful defects found and willingness to pay; do not infer those from this lab. | ||
|
|
||
| A usable introduction: “We test whether an agent workflow can recover from an ambiguous tool result without duplicating the action or silently using stale authority. Our current reference makes the boundary reproducible, including negative controls and conventional alternatives.” | ||
|
|
||
| ## Further questions before an investment claim | ||
|
|
||
| Can a real target service enforce a stable operation identity or close an old attempt? What happens when the receiver is unavailable, its storage is rolled back, or multiple regions disagree? Is the kit easier to integrate or more diagnostic than existing tests? Is there a paying owner for the failure mode? These questions remain unanswered. | ||
|
|
||
| ## Caveats and assumptions | ||
|
|
||
| SQLite insertion is the effect. Closure and effect share one database transaction; no atomicity with an arbitrary external payment or device is proved. Public fixture keys and synthetic A7 tags are not production authentication. No Byzantine protection, physical power-loss proof, deployment bypass resistance, unbounded exactly-once guarantee, hardware acceleration or full four-repository integration is claimed. Independent code review and external reproduction remain separate gates. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # Recovery closure experiment — protocol fixed before new trials | ||
|
|
||
| Date: 2026-09-05. Decision: whether CaPU/ATMAN supports a defensible investor-facing recovery demonstration, not whether it replaces a CPU. | ||
|
|
||
| Source: unchanged CaPU HTTP v2 at 8a2f2a37023a50aeac52cb8c8aed84b2eeceec88; CaPU A6/A7 and ATMAN authority pins from its bootstrap. Old HTTP behavior remains a safe HOLD control. New receiver/adapters below are experimental additions, NOT defects attributed to v2. | ||
|
|
||
| H1: Reinterpreting an empty result lookup as NOT_COMMITTED admits a duplicate when the original request is delayed. | ||
| H2: A persistent attempt tombstone checked only at request admission is insufficient if an already admitted handler is paused before its effect. | ||
| H3: Checking that tombstone in the SAME receiver transaction as the effect prevents this counterexample and permits retry after a permanently dropped first request. | ||
| H4: A conventional FSM given the same receiver guarantee matches native CaPU. Operation-key idempotency is a strong conventional control; no architectural superiority is presumed. | ||
|
|
||
| Arms: hold, snapshot_negative (deliberately unsafe), admission_fence (deliberately weak), atomic_fence (candidate), operation_idempotency (separate conventional control). | ||
|
|
||
| Primary outcome: number of durable effect rows per logical operation; >1 is unsafe. Completion after a permanently dropped initial request is measured separately from safety. No timing, throughput, energy, revenue or investor-interest claims from these trials. | ||
|
|
||
| Finite model: enumerate all interleavings preserving each local causal chain; two attempts, one closure query, one receipt application, one optional replay. Report exact bounded trace counts, NOT empirical incident probabilities or unbounded proof. | ||
|
|
||
| HTTP: real loopback sockets and a receiver subprocess; test-controlled gates before/after admission; SQLite insertion itself is the effect. Native/FSM use unchanged upstream authority and lifecycle logic. Use a separate read-only observer; do not hide duplicates behind operation dedup in the candidate. Candidate only deduplicates the same attempt. Closure and effect share one transactional database; no cross-system atomicity is claimed. | ||
|
|
||
| Non-claims: new distributed-systems theorem, patentability/priority, real external payment, production receipt cryptography, Byzantine protection, physical power loss, unavailable receiver recovery, complete ATMAN/Bardo/COSMIC integration, silicon acceleration, market validation. Public deterministic fixture keys only, no expenditure or deployment. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # PR #106: validator fixes and dependency follow-up | ||
|
|
||
| This follow-up applies the locally reviewed validator/restoration patch to the | ||
| existing `research/recovery-closure-v3` branch. The parent is | ||
| `d64f9809f90532d52c2992174e63c1a216a50211`; main is not changed. Keep the PR | ||
| draft and unmerged pending review. The owner requested assistant self-review | ||
| and optional CodeRabbit review, explicitly without Codex. | ||
|
|
||
| ## Scope and evidence | ||
|
|
||
| The receiver, observer, lifecycle policies and pinned upstream source are | ||
| unchanged. This is evidence-verifier hardening, not a new recovery result or | ||
| new algorithm. `REVIEW_FIXES.md` and `evidence/review-fix-2026-09-05/` preserve | ||
| the earlier local patch results on Python 3.13.5 / cryptography 46.0.4. | ||
| They are not CI evidence for the dependency update. | ||
|
|
||
| `requirements.txt` now pins cryptography 50.0.1. Upstream lists that release | ||
| on 2026-08-25 and security fixes since 46.0.4: | ||
| https://cryptography.io/en/latest/changelog/ | ||
| https://pypi.org/project/cryptography/50.0.1/ | ||
|
|
||
| The local environment could not download the new wheel (network/DNS failure). | ||
| Consequently compatibility of 50.0.1 must be established by the actual new CI | ||
| runs, not by relabeling the earlier local results. The workflow installs and | ||
| checks 50.0.1, records the Python/OpenSSL/package environment, reruns the 32 | ||
| validator/restoration methods in normal and optimized mode, reruns all 40 HTTP | ||
| methods and 560 bounded model traces, then validates fresh and historical | ||
| artifacts. It also scans resolved requirements using pip-audit 2.10.1 in a | ||
| separate environment; scan failure is not suppressed. | ||
|
|
||
| Inspect the real run conclusion and artifacts. A configured workflow is not | ||
| an executed check. A clean dependency scan only means no known findings in | ||
| that scan; it is not a security or production certification. | ||
|
|
||
| ## Historical provenance, deliberately not rewritten | ||
|
|
||
| The original `source_commit` field labels the HTTP-v2 dependency, not the v3 | ||
| producer. Original archive chunks, original observed summary and checksums | ||
| remain untouched. `evidence_contract.json` documents the distinction. Historical | ||
| validation is opt-in (`--historical`) and byte-pinned. Fresh runs record actual | ||
| Git revision/dirty status or explicit unavailability, plus installed cryptography. | ||
|
|
||
| ## External handoff | ||
|
|
||
| No external email or endorsement is part of this change. After CI and review, | ||
| a separate bounded reproduction invitation can point to a pinned commit. | ||
| SQLite insertion remains the effect; no atomicity for real payments, arbitrary | ||
| external services, hostile hosts, production cryptography or hardware is claimed. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Sensitive Data Exposure (CWE-522): Insufficiently Protected Credentials
Reachability: External · Exploitability: Moderate
Disable checkout credential persistence.
actions/checkout@v4persists the GitHub token by default. Laterrunsteps can read.git/configand copy the token intoevidence-v3/, which the artifact step uploads.contents: readlimits privilege but does not prevent credential disclosure.Suggested fix
📝 Committable suggestion
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 19-19: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Source: Linters/SAST tools