Skip to content

security: canonicalize public forbidden-root authority - #62

Open
seonghobae wants to merge 6 commits into
mainfrom
security/canonical-forbidden-root
Open

security: canonicalize public forbidden-root authority#62
seonghobae wants to merge 6 commits into
mainfrom
security/canonical-forbidden-root

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Test-first security repair

Closes #61 with a bounded public-API trust-boundary repair.

Exact tree binding

  • Protected-main base: 10d0c51daf2ad278d66f43be479df8cf6b08ba6d.
  • Immutable security RED head: 35c31495f041b6980a4c6b003424eb8816ae2148.
  • Prior exact security GREEN head: 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657.
  • Exact current candidate: 6a8f57c29c9ebb561c771829ba75501ba9a91eb8.

Implemented boundary

  • canonicalizes a non-None public forbidden_root through the existing canonical evidence-root contract before output-parent creation or output-path access;
  • normalizes every invalid root to evidence manifest forbidden root is missing or unsafe;
  • stores one canonical root and reuses it for the pre-open, descriptor-bound, and post-fsync containment checks;
  • preserves deterministic strict JSON, exclusive owner-only creation, CLI behavior, and post-publication verification;
  • adds beginner-readable public API/operator guidance and an [Unreleased] Security entry;
  • changes no .github file, dependency, credential, release permission, transport API, or review-agent identity.

Deterministic central-coverage repair

Central OpenCode coverage run 31092401095, attempts 1 and 2, exposed an interpreter-dependent test fixture on Python 3.14: a 10,000-level JSON array was parsed successfully and reached the existing safe non-object rejection, while the test expected json.loads itself to raise RecursionError. Exact current commit 6a8f57c29c9ebb561c771829ba75501ba9a91eb8 changes only tests/test_sealed_release_evidence_resource_limits.py so the parser-recursion normalization contract is exercised deterministically through an injected RecursionError. Production code and the non-object rejection remain unchanged.

Exact-head evidence

CI run 31101925284 succeeded on exact head 6a8f57c29c9ebb561c771829ba75501ba9a91eb8:

  • Python 3.10–3.13, Ruff, compileall, and product-guard self-test: success;
  • 743 tests: success;
  • production coverage: 1,626 statements and 554 branches, 100%;
  • wheel and source-distribution package acceptance: success.

SAST Semgrep run 31101924971 and Security Scan run 31101925107 also succeeded on the same exact head.

Remaining gates

The earlier CodeRabbit review of 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 does not establish exact-current-head review success. A completed automated review and central current-head review of 6a8f57c29c9ebb561c771829ba75501ba9a91eb8, independent non-author approval, branch protection, and every repository policy gate remain mandatory. Do not merge, enable auto-merge, release, or publish before all gates are satisfied.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 15 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a02f338-602a-4010-9414-21e81d8b98cf

📥 Commits

Reviewing files that changed from the base of the PR and between 10d0c51 and 6a8f57c.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • docs/sealed-release-evidence.md
  • src/egressweave/release_evidence.py
  • tests/test_sealed_release_evidence_forbidden_root.py
  • tests/test_sealed_release_evidence_resource_limits.py

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

@opencode-agent Implement the bounded GREEN repair for exact current test-only head 44fb75dfb21dda4b2e35266a83b507c9c52d9279 on branch security/canonical-forbidden-root.

The immutable RED history is valid:

  • exact head 35c31495f041b6980a4c6b003424eb8816ae2148 failed every Python 3.10–3.13 lane only because test_public_writer_rejects_symlinked_forbidden_root observed DID NOT RAISE; Python 3.13 reported 1 failed, 739 passed;
  • current test-only head adds missing, non-directory, and canonicalization-failure preconditions, all reproduced locally as four expected failures before production changes;
  • package acceptance, Ruff on the initial RED head, SAST Semgrep, and Security Scan were otherwise successful.

Apply only the minimal root-cause fix and documentation in these paths:

  • src/egressweave/release_evidence.py
  • tests/test_sealed_release_evidence_forbidden_root.py
  • docs/sealed-release-evidence.md
  • CHANGELOG.md

Required implementation:

  1. Add a beginner-readable private helper that canonicalizes the public writer's forbidden_root by reusing the existing _require_canonical_evidence_root(...) contract and normalizes every failure to exactly evidence manifest forbidden root is missing or unsafe.
  2. In write_evidence_manifest(...), encode the detached strict-JSON payload first, then validate/canonicalize a non-None forbidden root before output_path.parent.mkdir(...) or any output-path access.
  3. Store the returned canonical root once and use that exact authority for the pre-open, descriptor-bound, and post-fsync containment checks. Never compare against the caller's original alias again.
  4. Expand the public function docstring to state that the optional root must be one existing real directory reached through a lexical path with no symbolic-link component, is validated before output-parent creation, and is reused throughout publication.
  5. Update the operator guide to distinguish public API callers from the CLI, explain the fail-closed precondition and stable error, and retain the existing CWE-59/CWE-367 residual-race guidance in APA 7 form.
  6. Add an [Unreleased] Security entry. Do not change the package version.

The focused implementation has already been independently rehearsed against the exact merged package: all tests/test_sealed_release_evidence*.py passed (75 passed), and release_evidence.py achieved 368 statements, 120 branches, 100% statement and branch coverage. Reproduce the complete repository checks on the new exact head.

Do not modify .github, workflows, dependencies, release/signing permissions, protected refs, credentials, review-agent identities, network transport APIs, or files outside the four-path allowlist. Keep the PR draft until the complete exact-head checks are green. Do not merge, enable auto-merge, release, or publish.

@seonghobae
seonghobae marked this pull request as ready for review August 6, 2026 05:11

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Review exact current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657. The immutable RED history is retained, and CI, Python 3.10–3.13, 100% production statement/branch coverage, package acceptance, SAST Semgrep, and Security Scan have completed successfully on this exact head.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

@seonghobae I will review the current PR state for commit 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Retry the exact-head review for 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657; the prior request was deferred solely by the temporary review-rate window.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

@seonghobae I will review the PR at exact head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review the unchanged exact current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657. Treat earlier rate-limit output as incomplete rather than approval. Do not review or infer from any other head.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

@seonghobae I will review pull request #62 at exact head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657. I will not treat the earlier rate-limited requests as approval.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please perform a complete review of unchanged exact current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 against exact base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d. The prior run was rate-limited and is not being treated as review success. Do not infer approval from status context or review another head.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

@seonghobae I will perform a complete review of PR #62 at head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 against base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d. I will not treat the earlier rate-limited requests as review success.

⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 29 minutes.

@seonghobae
seonghobae marked this pull request as draft August 6, 2026 07:03

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Review exact current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657. The PR remains draft; do not treat review latency or a rate-limit response as approval.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

@seonghobae I will review pull request #62 at exact head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657. The PR remains a draft. A delayed or rate-limited review is not approval.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Review only exact current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 against protected-main base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d. The prior rate-limited attempts are incomplete, not successful reviews. Focus on canonicalizing the public forbidden_root before output-parent or output-path access, stable non-leaking invalid-root errors, reuse of one resolved authority through pre-open/descriptor/post-fsync checks, strict deterministic owner-only manifest publication, symlink and containment race resistance, docs and CHANGELOG accuracy, and absence of workflow, credential, dependency, release, or transport changes. Do not approve, merge, publish, or substitute current green checks for independent review.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='10d0c51daf2ad278d66f43be479df8cf6b08ba6d'
head='13cd59b5d0307f1a4dc1e4ffe777ed31b878c657'

printf '%s\n' '== Checked-out commit =='
git rev-parse HEAD
printf '%s\n' '== Requested commits =='
git show -s --format='%H%n%P%n%s' "$base" "$head"
printf '%s\n' '== Base ancestry =='
git merge-base --is-ancestor "$base" "$head" && echo 'base-is-ancestor=true'
printf '%s\n' '== Changed paths =='
git diff --name-status "$base" "$head"
printf '%s\n' '== Diff stat =='
git diff --stat "$base" "$head"

printf '%s\n' '== release_evidence outline =='
ast-grep outline src/egressweave/release_evidence.py --items all --view expanded
printf '%s\n' '== Relevant writer and helper references =='
rg -n -C 8 --glob 'src/egressweave/release_evidence.py' \
  'def (_require_canonical_evidence_root|write_evidence_manifest)|forbidden_root|contain|fsync|open\(' \
  src/egressweave/release_evidence.py
printf '%s\n' '== Exact diff =='
git diff --find-renames --find-copies --unified=80 "$base" "$head" -- \
  src/egressweave/release_evidence.py \
  tests/test_sealed_release_evidence_forbidden_root.py \
  docs/sealed-release-evidence.md \
  CHANGELOG.md

Length of output: 49156


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Canonical-root and writer implementation =='
nl -ba src/egressweave/release_evidence.py | sed -n '135,165p;605,715p'

printf '%s\n' '== Public writer call sites =='
rg -n -C 5 --glob '*.py' \
  '\bwrite_evidence_manifest\s*\(' \
  src tests

printf '%s\n' '== Relevant test files =='
fd -t f 'test_sealed_release_evidence.*\.py$' tests | sort

printf '%s\n' '== Output-boundary test structure =='
ast-grep outline tests/test_sealed_release_evidence_output_boundary.py --items all --view expanded
printf '%s\n' '== Output-boundary containment and writer tests =='
rg -n -C 12 --glob 'test_sealed_release_evidence*.py' \
  '(write_evidence_manifest|forbidden_root|output.*(inside|outside)|symlink|fsync|parent)' \
  tests

printf '%s\n' '== Documentation residual-race references =='
rg -n -C 4 'CWE-59|CWE-367|APA|race|TOCTOU|Time.of.check' \
  docs/sealed-release-evidence.md CHANGELOG.md

Length of output: 1330


🏁 Script executed:

#!/bin/bash
set -u

echo '== Canonical-root and writer implementation =='
sed -n '135,165p;605,715p' src/egressweave/release_evidence.py

echo '== Public writer call sites =='
rg -n -C 5 --glob '*.py' '\bwrite_evidence_manifest\s*\(' src tests || true

echo '== Relevant test files =='
find tests -type f -name 'test_sealed_release_evidence*.py' -print | sort

echo '== Output-boundary test structure =='
ast-grep outline tests/test_sealed_release_evidence_output_boundary.py --items all --view expanded || true

echo '== Output-boundary containment and writer tests =='
rg -n -C 12 --glob 'test_sealed_release_evidence*.py' \
  '(write_evidence_manifest|forbidden_root|output.*(inside|outside)|symlink|fsync|parent)' \
  tests || true

echo '== Documentation residual-race references =='
rg -n -C 4 'CWE-59|CWE-367|APA|race|TOCTOU|Time.of.check' \
  docs/sealed-release-evidence.md CHANGELOG.md || true

Length of output: 76684


@seonghobae I reviewed exact head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 against base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d.

I found no actionable defects in the static review.

The diff changes only the four allowed paths. The public writer canonicalizes forbidden_root before output-parent creation. It emits the required stable invalid-root error. It stores and reuses one canonical root for the pre-open, descriptor-bound, and post-fsync containment checks.

The strict JSON encoding, exclusive owner-only creation, final-path protection, descriptor checks, and post-publication verification remain intact. The added tests cover symlinked, missing, non-directory, and resolution-failure roots. The documentation and changelog match the implementation. The guide retains the CWE-59 and CWE-367 residual-race guidance.

I did not execute tests in this sandbox. I therefore do not independently confirm the reported CI, coverage, package acceptance, SAST, or Security Scan results. I did not approve, merge, publish, or change the draft state.

You are interacting with an AI system.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Review only exact current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 against exact base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d. Prior rate-limited requests are superseded. CI, SAST Semgrep, and Security Scan have completed successfully on this exact head. Focus on canonicalizing the public forbidden_root before output-parent or output-path access, stable failure normalization, reuse of one canonical authority across pre-open/descriptor/post-fsync checks, regression completeness, operator guidance, and unchanged credential/workflow boundaries. Do not approve, merge, publish, release, rebase, or retarget.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='10d0c51daf2ad278d66f43be479df8cf6b08ba6d'
head='13cd59b5d0307f1a4dc1e4ffe777ed31b878c657'

echo '== commit identity =='
printf 'checked_out='
git rev-parse HEAD
git show -s --format='base=%H%nbase_subject=%s' "$base"
git show -s --format='head=%H%nhead_subject=%s' "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=true'

echo '== changed paths =='
git diff --name-status "$base" "$head"

echo '== affected source outline =='
ast-grep outline src/egressweave/release_evidence.py --items all --view expanded

echo '== canonical-root helper and writer =='
rg -n -C 12 \
  'def (_require_canonical_evidence_root|_require_canonical_forbidden_root|write_evidence_manifest)|forbidden_root|output_path\.parent\.mkdir|contain|fsync|dir_fd|open\(' \
  src/egressweave/release_evidence.py

echo '== exact allowed-path diff =='
git diff --unified=50 "$base" "$head" -- \
  src/egressweave/release_evidence.py \
  tests/test_sealed_release_evidence_forbidden_root.py \
  docs/sealed-release-evidence.md \
  CHANGELOG.md

echo '== changed files outside allowlist =='
git diff --name-only "$base" "$head" | grep -Ev '^(src/egressweave/release_evidence\.py|tests/test_sealed_release_evidence_forbidden_root\.py|docs/sealed-release-evidence\.md|CHANGELOG\.md)$' || true

Length of output: 43306


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== canonical evidence-root contract =='
sed -n '143,161p' src/egressweave/release_evidence.py

echo '== complete public forbidden-root regression module =='
cat -n tests/test_sealed_release_evidence_forbidden_root.py

echo '== existing writer and containment regression definitions =='
rg -n -C 8 --glob 'test_sealed_release_evidence*.py' \
  'def test_.*(writer|output|contain|symlink|forbidden)|write_evidence_manifest\s*\(' \
  tests

echo '== operator guide threat-model citations and new API guidance =='
rg -n -C 8 \
  'Direct public API|forbidden_root|CWE-59|CWE-367|National Institute|race|TOCTOU|References' \
  docs/sealed-release-evidence.md

echo '== writer call sites =='
rg -n -C 4 --glob '*.py' '\bwrite_evidence_manifest\s*\(' src tests

Length of output: 49081


@seonghobae I reviewed PR #62 at exact head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 against exact base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d.

I found no actionable defects in the static review.

The diff changes only the four allowed paths. It does not change workflow, credential, dependency, release, or transport boundaries.

write_evidence_manifest(...) encodes the strict JSON payload first. It canonicalizes a non-None forbidden_root before output-parent creation. _require_canonical_forbidden_root(...) reuses _require_canonical_evidence_root(...) and normalizes invalid-root failures to the required stable error.

The writer stores one canonical_forbidden_root. It uses that authority for the pre-open, descriptor-bound, and post-fsync containment checks. It does not reuse the caller-provided alias.

The regression tests cover symlinked, missing, non-directory, and resolution-failure roots. The missing, non-directory, and resolution-failure tests verify that the output parent does not exist after failure.

The public API guidance, CLI distinction, residual-race guidance, APA-style CWE-59/CWE-367 references, and [Unreleased] Security entry match the implementation.

I did not run tests or other runtime checks in this sandbox. I do not independently confirm the reported CI, coverage, package acceptance, SAST Semgrep, or Security Scan results. I did not approve, merge, publish, release, rebase, or retarget the PR.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@seonghobae
seonghobae marked this pull request as ready for review August 6, 2026 09:15

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657.

  • Head SHA: 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657

  • Workflow run: 31092401095

  • Workflow attempt: 1

Coverage evidence

Coverage Decision

  • Result: FAIL
  • Test evidence: not proven passing
  • Docstring evidence: not proven passing when configured
  • Failure count: 1

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (2 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (2 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Docs: sealed-release-evidence.md"]
  S2 --> I2["operator or user guidance"]
  I2 --> R2["Review risk: Docs: sealed-release-evidence.md"]
  R2 --> V2["docs review"]
  Evidence --> S3["Test: test_sealed_release_evidence_forbidden_root.py"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test: test_sealed_release_evidence_forbidden_root.py"]
  R3 --> V3["targeted test run"]
Loading

@opencode-agent

opencode-agent Bot commented Aug 6, 2026

Copy link
Copy Markdown

OpenCode Review Overview

  • Head SHA: 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657
  • Workflow run: 31092401095
  • Workflow attempt: 2
  • Gate result: REQUEST_CHANGES (approval step)

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657.

  • Head SHA: 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657

  • Workflow run: 31092401095

  • Workflow attempt: 2

Coverage evidence

Coverage Decision

  • Result: FAIL
  • Test evidence: not proven passing
  • Docstring evidence: not proven passing when configured
  • Failure count: 1

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (2 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (2 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Docs: sealed-release-evidence.md"]
  S2 --> I2["operator or user guidance"]
  I2 --> R2["Review risk: Docs: sealed-release-evidence.md"]
  R2 --> V2["docs review"]
  Evidence --> S3["Test: test_sealed_release_evidence_forbidden_root.py"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test: test_sealed_release_evidence_forbidden_root.py"]
  R3 --> V3["targeted test run"]
Loading

Copy link
Copy Markdown
Contributor Author

@opencode-agent Re-run the independent exact-head review for current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 against base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d without changing any file.

The current CHANGES_REQUESTED review cites coverage-evidence run 31092401095 as failing to prove tests/docstrings, while repository exact-head runs 31073312776 (CI), 31073312699 (SAST Semgrep), and 31073312799 (Security Scan) all completed successfully on this unchanged head; CI includes the Python 3.10–3.13 matrix, Ruff, compileall, public-docstring checks, package acceptance, and 100% production statement and branch coverage. Re-evaluate the exact head and either submit an independent approval or identify a concrete current-head test, docstring, security, or policy failure with reproducible evidence. Do not infer success from queued work, do not dismiss prior review state without a completed replacement review, and do not modify, push, rebase, merge, enable auto-merge, release, or publish.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657.

  • Head SHA: 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657

  • Workflow run: 31092401095

  • Workflow attempt: 2

Coverage evidence

Coverage Decision

  • Result: FAIL
  • Test evidence: not proven passing
  • Docstring evidence: not proven passing when configured
  • Failure count: 1

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (2 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (2 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Docs: sealed-release-evidence.md"]
  S2 --> I2["operator or user guidance"]
  I2 --> R2["Review risk: Docs: sealed-release-evidence.md"]
  R2 --> V2["docs review"]
  Evidence --> S3["Test: test_sealed_release_evidence_forbidden_root.py"]
  S3 --> I3["regression suite"]
  I3 --> R3["Review risk: Test: test_sealed_release_evidence_forbidden_root.py"]
  R3 --> V3["targeted test run"]
Loading

Copy link
Copy Markdown
Contributor Author

@opencode-agent Implement the minimal test-only GREEN repair on exact current head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 of branch security/canonical-forbidden-root.

Central OpenCode coverage run 31092401095, attempts 1 and 2, provides valid RED evidence on Python 3.14: the repository suite failed only at tests/test_sealed_release_evidence_resource_limits.py::test_deeply_nested_json_is_masked_by_the_strict_evidence_boundary (1 failed, 742 passed). The test expects the 10,000-level JSON array to make json.loads raise RecursionError, but this interpreter parses the array successfully; the existing and still-safe object-shape guard then exits with SBOM deep.cdx.json must be a JSON object rather than the parser-normalization message. This is an interpreter-dependent test fixture, not a production trust-boundary failure.

Modify only tests/test_sealed_release_evidence_resource_limits.py.

Replace the environment-dependent deeply nested JSON fixture with a deterministic parser-failure regression: accept monkeypatch: pytest.MonkeyPatch, write a small bounded JSON payload, monkeypatch release_evidence.json.loads to raise RecursionError, and assert that release_evidence._load_strict_json(...) normalizes it to SystemExit matching not strict JSON. Rename the test and docstring if needed so they state that parser recursion failure is normalized. Do not weaken or remove the existing non-object rejection behavior; do not change production code.

Do not modify the PR's four existing changed paths, package code, documentation, CHANGELOG, .github, workflows, dependencies, credentials, permissions, signing, attestation, release, publication, tag, ref, or network behavior. Run the focused regression, then the full Python 3.10–3.13 repository suite, Ruff, compileall, public-docstring checks, 100% production statement and branch coverage, package acceptance, SAST, Security Scan, and the central current-head coverage/review workflow. Stop without writing if the head differs from 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657. Do not rebase, retarget, merge, mark draft, enable auto-merge, release, or publish.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Review only exact current head 6a8f57c29c9ebb561c771829ba75501ba9a91eb8 against exact base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d. The prior completed review of 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 is not exact-current-head review success. Focus on the canonical public forbidden_root authority before output-parent/path access; stable non-leaking invalid-root errors; reuse of one canonical root across pre-open, descriptor-bound, and post-fsync checks; preservation of strict deterministic JSON and exclusive owner-only creation; and the new test-only change proving parser RecursionError normalization without relying on interpreter recursion depth. Verify that production code, non-object rejection, workflows, dependencies, credentials, release permissions, transport APIs, and publication behavior remain unchanged by the latest commit. Do not approve, merge, enable auto-merge, release, publish, or infer success from queued checks.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='10d0c51daf2ad278d66f43be479df8cf6b08ba6d'
head='6a8f57c29c9ebb561c771829ba75501ba9a91eb8'

echo '== Exact commit identity =='
printf 'checked_out='
git rev-parse HEAD
git show -s --format='base=%H%nbase_subject=%s%nbase_parents=%P' "$base"
git show -s --format='head=%H%nhead_subject=%s%nhead_parents=%P' "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=true'

echo '== Full PR changed paths =='
git diff --name-status "$base" "$head"

echo '== Latest commit changed paths =='
git diff-tree --no-commit-id --name-status -r "$head"

echo '== Latest commit diff =='
git show --format=fuller --find-renames --find-copies --unified=80 "$head" -- \
  tests/test_sealed_release_evidence_resource_limits.py

echo '== Full PR diff summary =='
git diff --stat "$base" "$head"

echo '== Relevant source outline =='
ast-grep outline src/egressweave/release_evidence.py --items all --view expanded

echo '== Canonical-root helper and public writer =='
nl -ba src/egressweave/release_evidence.py | sed -n '130,175p;590,735p'

echo '== Strict JSON loader =='
rg -n -C 20 \
  'def _load_strict_json|json\.loads|RecursionError|must be a JSON object|not strict JSON' \
  src/egressweave/release_evidence.py

echo '== Forbidden-root and output-boundary tests =='
rg -n -C 12 --glob 'test_sealed_release_evidence*.py' \
  'def test_.*(forbidden|symlink|root|output|recursion)|write_evidence_manifest\s*\(|_load_strict_json\s*\(' \
  tests

echo '== Public API guidance and changelog =='
rg -n -C 8 \
  'forbidden_root|Direct public API|CLI|CWE-59|CWE-367|Unreleased|Security' \
  docs/sealed-release-evidence.md CHANGELOG.md

echo '== Protected-boundary changes across full PR =='
git diff --name-only "$base" "$head" | grep -E \
  '(^|/)\.github/|(^|/)(pyproject\.toml|poetry\.lock|requirements[^/]*|Pipfile(\.lock)?|setup\.(cfg|py)|Cargo\.toml|package(-lock)?\.json)$|credential|secret|sign|attest|release|transport|network' \
  || true

Length of output: 10208


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='10d0c51daf2ad278d66f43be479df8cf6b08ba6d'
head='6a8f57c29c9ebb561c771829ba75501ba9a91eb8'

echo '== Canonical-root contract and public writer =='
sed -n '135,170p;580,740p' src/egressweave/release_evidence.py

echo '== Strict JSON loader =='
sed -n '255,385p' src/egressweave/release_evidence.py

echo '== Full forbidden-root regression module =='
cat -n tests/test_sealed_release_evidence_forbidden_root.py

echo '== Resource-limit regression module =='
cat -n tests/test_sealed_release_evidence_resource_limits.py

echo '== Existing output containment tests =='
rg -n -C 14 --glob 'test_sealed_release_evidence*.py' \
  'output.*(inside|outside)|forbidden_root|descriptor|fsync|symlink|exclusive|owner' \
  tests

echo '== Public API documentation and changelog excerpts =='
rg -n -C 10 \
  'forbidden_root|public API|CLI|CWE-59|CWE-367|References|Unreleased|Security' \
  docs/sealed-release-evidence.md CHANGELOG.md

echo '== Complete changed-path list, with protected-boundary verdict =='
changed_paths="$(git diff --name-only "$base" "$head")"
printf '%s\n' "$changed_paths"
if printf '%s\n' "$changed_paths" | grep -Eq \
  '(^|/)\.github/|(^|/)(pyproject\.toml|poetry\.lock|requirements[^/]*|Pipfile(\.lock)?|setup\.(cfg|py)|Cargo\.toml|package(-lock)?\.json)$|(^|/).*(credential|secret|transport|network).*'; then
  echo 'protected_boundary_changes=true'
else
  echo 'protected_boundary_changes=false'
fi

echo '== Production source changes introduced by latest commit =='
git diff --name-only "${head}^" "$head" -- src

Length of output: 87907


@seonghobae I reviewed exact head 6a8f57c29c9ebb561c771829ba75501ba9a91eb8 against base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d.

I found no actionable defects in the static review.

The checked-out commit matches the requested head. The requested base is an ancestor of that head.

The full PR changes five files only. The latest commit changes only tests/test_sealed_release_evidence_resource_limits.py. It introduces no production-source change.

write_evidence_manifest(...) encodes the strict JSON payload before it accesses the output parent. It canonicalizes a supplied forbidden_root before it creates the output parent. _require_canonical_forbidden_root(...) reuses _require_canonical_evidence_root(...) and normalizes failures to exactly evidence manifest forbidden root is missing or unsafe.

The writer stores canonical_forbidden_root once. It uses that value for the pre-open, descriptor-bound, and post-fsync containment checks. It does not reuse the caller-supplied path alias.

The existing exclusive creation, O_NOFOLLOW protection, owner-only mode, descriptor identity checks, strict JSON encoding, and post-publication verification remain present.

The new parser regression uses a small JSON object. It monkeypatches release_evidence.json.loads to raise RecursionError. _load_strict_json(...) catches that exception and raises the expected strict-JSON SystemExit. Its separate non-object rejection remains unchanged.

The documentation and [Unreleased] Security entry match the implementation. The full diff contains no workflow, dependency, credential, release-permission, transport, network, or publication-behavior changes.

I did not run repository code in this sandbox. I therefore do not independently verify CI, coverage, package acceptance, SAST, or Security Scan. I did not approve, merge, enable auto-merge, release, or publish.

You are interacting with an AI system.

Copy link
Copy Markdown
Contributor Author

@opencode-agent Review only exact current head 6a8f57c29c9ebb561c771829ba75501ba9a91eb8 against exact base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d; do not modify the branch.

The prior two CHANGES_REQUESTED reviews were correctly bound to old head 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657, where central Python 3.14 coverage failed because an interpreter-dependent deep-array fixture reached the existing safe non-object rejection instead of raising parser RecursionError. Current head changes only that test fixture to inject RecursionError deterministically. Exact-head CI 31101925284, SAST 31101924971, and Security Scan 31101925107 all succeeded; Python 3.10–3.13 reported 743 passing tests and 1,626 statements/554 branches at 100% production coverage.

Review the public forbidden_root canonicalization boundary, stable invalid-root error, one canonical authority reused before open/descriptor binding/after fsync, strict deterministic JSON, owner-only creation, and the deterministic parser-error regression. Verify the latest commit changes no production code, workflows, dependency, credential, permission, transport, release, signing, attestation, or publication behavior. Submit an exact-head review outcome only after independently checking the current tree and evidence. Do not merge, enable auto-merge, release, publish, rebase, retarget, or dismiss prior reviews without a valid current-head superseding outcome.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Review exact current head 6a8f57c29c9ebb561c771829ba75501ba9a91eb8. Treat the prior review of 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 as stale except where a finding remains reproducible. The current head changes only the deterministic Python 3.14 parser-recursion test fixture after the security implementation; CI run 31101925284, SAST run 31101924971, and Security Scan run 31101925107 all succeeded on this exact head. Verify canonical forbidden_root authority before any output-parent/path access, stable non-leaking failures, reuse of one resolved root through all containment checks, and preservation of exclusive owner-only publication and post-publication verification. Do not report success for another head.

Copy link
Copy Markdown
Contributor Author

@opencode-agent Perform a read-only exact-head review of 6a8f57c29c9ebb561c771829ba75501ba9a91eb8 for PR #62. Do not modify files or refs.

The prior formal REQUEST_CHANGES reviews were anchored to 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 and failed only because an interpreter-dependent Python 3.14 recursion fixture prevented coverage evidence. Exact current head replaces that fixture with deterministic injected RecursionError; CI run 31101925284, SAST 31101924971, and Security Scan 31101925107 all succeeded on the exact head. Reassess the complete diff and verify the public forbidden_root is canonicalized before output-parent creation or output-path access, one resolved authority is reused through pre-open/descriptor/post-fsync containment checks, failures remain stable and non-leaking, and strict JSON, owner-only exclusive publication, CLI behavior, and post-publication verification remain intact. Anchor any formal outcome to 6a8f57c29c9ebb561c771829ba75501ba9a91eb8. Do not merge, rebase, retarget, release, publish, or change branch state.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='10d0c51daf2ad278d66f43be479df8cf6b08ba6d'
head='6a8f57c29c9ebb561c771829ba75501ba9a91eb8'

echo '== Commit identity and ancestry =='
printf 'checked_out='
git rev-parse HEAD
git show -s --format='base=%H%nbase_subject=%s%nhead_parent_check=' "$base"
git show -s --format='head=%H%nhead_subject=%s%nhead_parents=%P' "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=true'

echo '== Full PR paths =='
git diff --name-status "$base" "$head"
echo '== Latest commit paths =='
git diff-tree --no-commit-id --name-status -r "$head"

echo '== Full PR diff stat =='
git diff --stat "$base" "$head"
echo '== Latest test-only diff =='
git diff --unified=60 "${head}^" "$head" -- tests/test_sealed_release_evidence_resource_limits.py

echo '== Source outline =='
ast-grep outline src/egressweave/release_evidence.py --items all --view expanded

echo '== Canonical-root helper and writer =='
nl -ba src/egressweave/release_evidence.py | sed -n '130,175p;575,745p'

echo '== Strict JSON loader =='
rg -n -C 20 'def _load_strict_json|json\.loads|RecursionError|not strict JSON|must be a JSON object' \
  src/egressweave/release_evidence.py

echo '== Forbidden-root tests =='
cat -n tests/test_sealed_release_evidence_forbidden_root.py
echo '== Resource-limit tests =='
cat -n tests/test_sealed_release_evidence_resource_limits.py

echo '== Documentation and changelog references =='
rg -n -C 8 'forbidden_root|public API|CLI|CWE-59|CWE-367|Unreleased|Security' \
  docs/sealed-release-evidence.md CHANGELOG.md

echo '== Protected-boundary path check =='
git diff --name-only "$base" "$head" | grep -E \
  '(^|/)\.github/|(^|/)(pyproject\.toml|poetry\.lock|requirements[^/]*|Pipfile(\.lock)?|setup\.(cfg|py)|Cargo\.toml|package(-lock)?\.json)$|credential|secret|permission|transport|network|sign|attest|release|publish' \
  || true

Length of output: 9504


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='10d0c51daf2ad278d66f43be479df8cf6b08ba6d'
head='6a8f57c29c9ebb561c771829ba75501ba9a91eb8'

echo '== Canonical-root contract and public writer =='
sed -n '135,170p;580,740p' src/egressweave/release_evidence.py

echo '== Strict JSON loader =='
sed -n '250,385p' src/egressweave/release_evidence.py

echo '== Forbidden-root regression module =='
cat tests/test_sealed_release_evidence_forbidden_root.py

echo '== Resource-limit regression module =='
cat tests/test_sealed_release_evidence_resource_limits.py

echo '== Writer containment call sites =='
rg -n -C 7 \
  '_require_output_outside_verified_set|canonical_forbidden_root|forbidden_root|output_path\.parent\.mkdir|_open_exclusive_manifest|os\.fsync' \
  src/egressweave/release_evidence.py

echo '== Strict JSON parser and shape checks =='
rg -n -C 7 \
  'json\.loads|RecursionError|JSONDecodeError|must be a JSON object|not strict JSON' \
  src/egressweave/release_evidence.py tests/test_sealed_release_evidence_resource_limits.py

echo '== Documentation and changelog excerpts =='
rg -n -C 8 \
  'forbidden_root|public API|CLI|CWE-59|CWE-367|Unreleased|Security' \
  docs/sealed-release-evidence.md CHANGELOG.md

echo '== Full PR changed paths =='
git diff --name-only "$base" "$head"

echo '== Latest commit production-path check =='
git diff --name-only "${head}^" "$head" -- src docs CHANGELOG.md .github || true

echo '== Workflow and dependency paths in full PR =='
git diff --name-only "$base" "$head" | grep -E \
  '(^|/)\.github/|(^|/)(pyproject\.toml|poetry\.lock|requirements[^/]*|Pipfile(\.lock)?|setup\.(cfg|py)|Cargo\.toml|package(-lock)?\.json)$' \
  || true

Length of output: 50069


@seonghobae I reviewed exact head 6a8f57c29c9ebb561c771829ba75501ba9a91eb8 against base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d.

I found no actionable defects in the static review.

The checked-out commit matches the requested head. The requested base is an ancestor of this head.

write_evidence_manifest(...) encodes the strict JSON payload before it validates forbidden_root. It validates a non-None forbidden_root before output_path.parent.mkdir(...).

_require_canonical_forbidden_root(...) reuses _require_canonical_evidence_root(...). It normalizes invalid-root failures to exactly evidence manifest forbidden root is missing or unsafe.

The writer stores canonical_forbidden_root once. It uses that canonical authority for the pre-open, descriptor-bound, and post-fsync containment checks. It does not use the caller-supplied alias after canonicalization.

Exclusive creation, owner-only mode, final-path no-follow protection, descriptor identity checks, deterministic strict JSON encoding, and post-publication verification remain present.

The latest commit changes only tests/test_sealed_release_evidence_resource_limits.py. The regression uses a bounded JSON object and injects RecursionError through release_evidence.json.loads. _load_strict_json(...) normalizes that error to the expected strict-JSON failure. The separate non-object rejection remains unchanged.

The full PR does not change workflow or dependency paths. The source, documentation, changelog, and tests match the stated boundary.

I did not execute repository code in this sandbox. I therefore do not independently verify CI run 31101925284, SAST run 31101924971, or Security Scan run 31101925107. I did not approve, merge, enable auto-merge, release, or publish.

You are interacting with an AI system.

@seonghobae
seonghobae dismissed stale reviews from opencode-agent[bot] and opencode-agent[bot] August 6, 2026 14:06

Superseded by exact current head 6a8f57c. The Python 3.14-only fixture instability identified by this prior-head review was repaired deterministically, and exact-head CI, SAST, and Security Scan now succeed. This dismissal does not constitute current-head approval; a fresh exact-head review and independent approval remain required.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Review only exact current head 6a8f57c29c9ebb561c771829ba75501ba9a91eb8. The two prior OpenCode CHANGES_REQUESTED reviews were dismissed as superseded because they were anchored to 13cd59b5d0307f1a4dc1e4ffe777ed31b878c657 and its Python 3.14 fixture instability; dismissal is not approval. Focus on canonicalizing the public forbidden_root before output-parent creation or output-path access, reuse of one canonical authority through pre-open/descriptor/post-fsync checks, stable non-leaking failure normalization, deterministic strict JSON, beginner-readable public documentation, 100% production statement/branch coverage, and absence of workflow, credential, dependency, transport, release, or permission changes. Do not infer independent approval, merge, enable auto-merge, release, or publish.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='10d0c51daf2ad278d66f43be479df8cf6b08ba6d'
head='6a8f57c29c9ebb561c771829ba75501ba9a91eb8'

echo '== Commit identity and ancestry =='
printf 'checked_out='; git rev-parse HEAD
git show -s --format='base=%H%nbase_subject=%s' "$base"
git show -s --format='head=%H%nhead_subject=%s%nhead_parents=%P' "$head"
git merge-base --is-ancestor "$base" "$head" && echo 'base_is_ancestor=true'

echo '== Changed paths: base..head =='
git diff --name-status "$base" "$head"
echo '== Changed paths: latest commit =='
git diff-tree --no-commit-id --name-status -r "$head"

echo '== Diff: public writer and canonical-root helper =='
git diff --unified=80 "$base" "$head" -- src/egressweave/release_evidence.py

echo '== Writer and strict JSON implementation =='
ast-grep outline src/egressweave/release_evidence.py --items all --view expanded
sed -n '130,180p;250,390p;575,750p' src/egressweave/release_evidence.py

echo '== Changed regression tests =='
git diff --unified=80 "$base" "$head" -- \
  tests/test_sealed_release_evidence_forbidden_root.py \
  tests/test_sealed_release_evidence_resource_limits.py

echo '== Full focused test modules =='
cat tests/test_sealed_release_evidence_forbidden_root.py
cat tests/test_sealed_release_evidence_resource_limits.py

echo '== Documentation and changelog diff =='
git diff --unified=60 "$base" "$head" -- docs/sealed-release-evidence.md CHANGELOG.md

echo '== Protected-boundary changed paths =='
git diff --name-only "$base" "$head" | grep -E \
  '(^|/)\.github/|(^|/)(pyproject\.toml|poetry\.lock|requirements[^/]*|Pipfile(\.lock)?|setup\.(cfg|py)|Cargo\.toml|package(-lock)?\.json)$|credential|secret|transport|network|permission|sign|attest|release|publish' \
  || true

echo '== Exact-head GitHub checks =='
gh pr checks 62 --repo ContextualWisdomLab/EgressWeave --json name,state,workflow,link \
  || true

Length of output: 65340


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base='10d0c51daf2ad278d66f43be479df8cf6b08ba6d'
head='6a8f57c29c9ebb561c771829ba75501ba9a91eb8'
repo='ContextualWisdomLab/EgressWeave'

echo '== Diff whitespace check =='
git diff --check "$base" "$head"

echo '== Writer call sites and containment-test definitions =='
rg -n -C 10 --glob '*.py' \
  '\bwrite_evidence_manifest\s*\(|def test_.*(output|contain|symlink|forbidden|exclusive|owner|fsync)' \
  src tests

echo '== Public API guide references and residual-race citations =='
rg -n -C 6 \
  'write_evidence_manifest|forbidden_root|CWE-59|CWE-367|References|race|TOCTOU' \
  docs/sealed-release-evidence.md CHANGELOG.md

echo '== Exact SHA bound to requested workflow runs =='
for run in 31101925284 31101924971 31101925107; do
  gh run view "$run" --repo "$repo" \
    --json databaseId,headSha,status,conclusion,workflowName \
    --jq '{databaseId, headSha, status, conclusion, workflowName}'
done

echo '== Latest commit is test-only =='
git diff --name-only "${head}^" "$head"

Length of output: 49399


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/EgressWeave'
for run in 31101924971 31101925107; do
  gh api "repos/$repo/actions/runs/$run" \
    --jq '{id, head_sha, status, conclusion, name, event}'
done

Length of output: 679


@seonghobae I reviewed exact head 6a8f57c29c9ebb561c771829ba75501ba9a91eb8 against base 10d0c51daf2ad278d66f43be479df8cf6b08ba6d.

I found no actionable defects.

The checked-out commit matches the requested head. The base is an ancestor of that head. The latest commit changes only tests/test_sealed_release_evidence_resource_limits.py.

write_evidence_manifest(...) encodes strict JSON before it validates a non-None forbidden_root. It validates and canonicalizes the root before it creates the output parent or accesses the output path.

_require_canonical_forbidden_root(...) reuses _require_canonical_evidence_root(...). It normalizes invalid-root failures to exactly:

evidence manifest forbidden root is missing or unsafe

The writer stores canonical_forbidden_root once. It uses that authority before opening the output, after descriptor binding, and after fsync. It does not reuse the caller-provided alias.

The focused tests cover symlinked, missing, non-directory, and resolution-failure forbidden roots. They verify that invalid roots fail before output-parent creation. Existing regressions cover exclusive creation, owner-only mode, final-path symlink rejection, descriptor/path replacement, and synchronization failures.

The new resource-limit regression uses a bounded JSON object. It injects RecursionError into release_evidence.json.loads. _load_strict_json(...) normalizes the failure to the expected strict-JSON error. The separate non-object rejection remains unchanged.

The documentation describes the public API precondition, the stable error, canonical-root reuse, and the CLI distinction. It retains the CWE-59 and CWE-367 references. The changelog has an [Unreleased] Security entry.

The full PR changes only five paths. It contains no workflow, dependency, credential, permission, transport, release, signing, attestation, or publication-boundary change. git diff --check reported no whitespace errors.

I verified these completed exact-head checks:

  • CI 31101925284
  • SAST Semgrep 31101924971
  • Security Scan 31101925107

Each reports success and is bound to 6a8f57c29c9ebb561c771829ba75501ba9a91eb8.

I did not execute repository tests in this sandbox. I did not approve, merge, enable auto-merge, release, publish, or modify branch state.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

security: canonicalize the public manifest writer's forbidden root

1 participant