Skip to content

fix(security): harden audit pseudonymization and refresh Netty evidence - #270

Open
seonghobae wants to merge 85 commits into
mainfrom
fix/pii-logging-16240128950440010639
Open

fix(security): harden audit pseudonymization and refresh Netty evidence#270
seonghobae wants to merge 85 commits into
mainfrom
fix/pii-logging-16240128950440010639

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Objective

Authoritative buyer-readiness parent for privacy-safe policy-override auditing, coordinated Netty remediation, deterministic SBOM/attribution evidence, exact-head CI semantics, zero-missed production coverage, warning-free public Javadocs, and fail-closed test evidence. Exact current head: 26563218ae42eaa876c784fcf56b27f8cb810080.

This PR supersedes closed-unmerged #165, #222, #257, #267, and #269. It remains the parent of stacked follow-up PRs #265, #268, and #271.

Security, privacy, and acceptance contract

  • Raw approver identifiers and approval tokens are excluded from policy-override audit logs.
  • Approver evidence uses versioned, domain-separated HMAC pseudonyms; pseudonymized values remain personal data.
  • Policy-signing and audit-pseudonym keys require at least 32 UTF-8 bytes, distinct purposes, and fail-closed configuration during Spring startup and standalone/MSA construction.
  • The complete Spring-managed Netty family is aligned to 4.1.136.Final.
  • The committed CycloneDX 1.6 SBOM and third-party attribution are deterministically regenerated and checked byte-for-byte.
  • Direct filesystem reads remove redundant existence prechecks and preserve fail-closed I/O semantics.
  • Exact pull-request head and synthetic merge compatibility are verified separately.
  • Maven verify enforces zero missed production lines and branches plus warning-free public Java 21 Javadocs.
  • Surefire evidence is mandatory, must contain at least one executed test, and must contain zero skips, failures, and errors. Optional Failsafe evidence is held to the same rules.
  • Every Maven testsuite must explicitly provide non-negative integer tests, skipped, failures, and errors attributes. Missing outcome attributes are incomplete evidence and are rejected instead of being inferred as zero.
  • Maven XML reports use one bounded read with a 16 MiB per-file limit; only strict UTF-8 with an optional UTF-8 BOM is accepted; NUL bytes, DTDs, and entity declarations are rejected before parsing. Malformed, missing, empty, incomplete-count, negative-count, skipped, failing, error-bearing, alternate-encoding, and oversized evidence fails closed.

Test-first remediation evidence

CodeRabbit correctly identified that successful mvn verify did not itself reject @Disabled, skipped, or zero-executed test reports.

  • RED head 1e3d6f6c2bb5b1d40a1729c977f5226fc878c314 introduced executable report-gate tests before the initial implementation.
  • The implementation added scripts/verify_maven_test_reports.py and invokes it after Maven verification in both exact-head and synthetic-merge jobs.
  • Semgrep correctly rejected the initial unbounded native XML parse.
  • Follow-up tests first required bounded input, DTD/entity rejection, UTF-16 declaration-bypass rejection, optional UTF-8 BOM support, and zero failure/error outcomes.
  • RED commit e3104fcce41b0f953cccd58d030453d4172626b0 added regressions requiring all four Maven suite count attributes before production behavior changed. Its superseded workflow attempts were cancelled after the implementation commits and are not counted as passing evidence.
  • The final implementation rejects each missing required count, performs one bounded read, validates strict UTF-8, rejects NUL and dangerous declarations, and parses only the validated bytes.
  • CHANGELOG.md and the canonical engineering acceptance policy record the complete-count fail-closed contract.
  • CodeRabbit's addressed inline thread and the superseded GitHub Advanced Security thread remain resolved; no unresolved review thread exists.

Exact-head acceptance evidence

For exact current head 26563218ae42eaa876c784fcf56b27f8cb810080:

  • CI 31033565648: success.
    • Maven exact-head job: success.
    • Maven synthetic-merge compatibility: success.
    • Buyer-readiness script tests: success, including missing required tests, skipped, failures, and errors attributes plus missing/zero/skipped/failure/error/malformed/negative-count, UTF-8 BOM, UTF-16 bypass, DTD/entity, oversized-report, and workflow-order regressions.
  • Security Scan 31033564507: success.
  • SAST Semgrep 31033566265: success.
  • Fuzz 31033564737: success across all exact-head fuzz jobs.
  • CodeRabbit commit status: success.
  • CodeRabbit's exact-current-head source review inspected this head against protected main and reported no actionable source-level finding. That bot comment is review evidence, not a counted approval.
  • OpenCode/Noema exact-current-head review evidence: absent.
  • Unresolved review threads: zero.
  • Formal GitHub review submissions currently available are comments anchored to predecessor heads; they are not treated as exact-current-head approval.
  • Counted independent write-authorized approval: absent.

Queued, pending, cancelled, skipped-required, absent-required, stale-head, predecessor-head, local-only, and dry-run evidence are not passing.

Remaining merge gate

Do not merge until OpenCode/Noema exact-current-head review evidence exists, zero unresolved threads remains true, a repository-write-authorized independent reviewer submits a counted approval, every branch-protection and repository-policy rule is satisfied, and the merge operation is expected-head safe. Do not weaken tests, bypass protections, infer approval from status checks or bot comments, or publish a release before integrated release acceptance succeeds.

seonghobae and others added 28 commits August 5, 2026 12:59
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

이번 변경은 정확한 커밋 검증, Maven 품질 게이트, Netty SBOM 일치성, 감사 식별자 가명화, 입력값 보호, 저장소 경계 테스트를 추가하고 관련 문서와 설정을 갱신합니다.

Changes

검증 게이트와 의존성 증거

Layer / File(s) Summary
CI·Maven·SBOM 검증 게이트
.github/workflows/*, pom.xml, AGENTS.md, src/test/java/com/clearfolio/viewer/config/DependencyPolicyTest.java, scripts/*
PR head와 병합 커밋을 검증하고 mvn verify, JaCoCo, Javadoc, Netty 및 SBOM 계약 검사를 실행합니다.
의존성 증거와 릴리스 기록
docs/legal/*, docs/security/*, docs/qa/evidence/*, CHANGELOG.md
Netty, PDFBox, Commons Logging, pdfjs-dist 버전과 SBOM, attribution, acceptance evidence를 갱신합니다.

감사 가명화와 경계 보호

Layer / File(s) Summary
감사 가명화와 키 분리
src/main/java/com/clearfolio/viewer/security/*, src/main/java/com/clearfolio/viewer/service/*, src/main/resources/application.yml, docs/security/*, src/test/java/com/clearfolio/viewer/security/*, src/test/java/com/clearfolio/viewer/service/*
정책 키와 감사 키를 검증하고, AuditPseudonymizerapproverFingerprint를 생성하며, 감사 로그에서 원시 식별자를 제외합니다.
API·파일·서비스 경계 보호
src/main/java/com/clearfolio/viewer/api/*, src/main/java/com/clearfolio/viewer/artifact/*, src/main/java/com/clearfolio/viewer/controller/*, src/main/java/com/clearfolio/viewer/repository/*, src/test/java/com/clearfolio/viewer/*
오류 응답 입력을 마스킹하고 파일명·파일 읽기·삭제·테넌트 범위 동작을 보강합니다. 공개 API Javadoc과 기본 생성자도 추가합니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant CIWorkflow
  participant MavenVerify
  participant JaCoCo
  participant Javadoc
  PullRequest->>CIWorkflow: PR head SHA 전달
  CIWorkflow->>CIWorkflow: checkout SHA 검증
  CIWorkflow->>MavenVerify: verify 실행
  MavenVerify->>JaCoCo: coverage gate 실행
  MavenVerify->>Javadoc: public API 문서 gate 실행
  JaCoCo-->>CIWorkflow: coverage 결과 반환
  Javadoc-->>CIWorkflow: 문서 검증 결과 반환
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 감사 pseudonymization 강화와 Netty 증거 갱신이라는 PR의 주요 변경 사항을 정확하고 간결하게 설명합니다.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pii-logging-16240128950440010639

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

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Independently review exact current head 7b6f60a11aed506fc8dbd7e6d4aac67619bec1c5 only. Exact-head CI 31026069878, Security Scan 31026070476, SAST Semgrep 31026069693, and fuzz 31026070477 are successful. Verify the CodeRabbit-requested zero-skipped/positive-test report gate, bounded one-read Maven XML handling, pre-parse DTD/entity rejection, malformed and negative-count fail-closed behavior, exact-head and synthetic-merge invocation, and that the Semgrep suppression is narrowly justified by executable bounds and regression tests rather than hiding an unsafe parser. Also reverify the complete audit-pseudonymization, key-separation, Netty, SBOM/attribution, filesystem, coverage, Javadoc, and buyer-evidence contract. Submit formal review evidence only for exact head 7b6f60a11aed506fc8dbd7e6d4aac67619bec1c5; independent write-authorized approval remains a separate mandatory gate.

@coderabbitai

coderabbitai Bot commented Aug 5, 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

repo='ContextualWisdomLab/clearfolio'
pr='270'
head='7b6f60a11aed506fc8dbd7e6d4aac67619bec1c5'

printf '%s\n' '== Exact head =='
git rev-parse HEAD
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$head"
git merge-base --is-ancestor "$head" HEAD && echo 'requested head is an ancestor of checkout' || true
git diff --name-status "${head}^" "$head"

printf '%s\n' '== Changes from protected main =='
if git show-ref --verify --quiet refs/remotes/origin/main; then
  git diff --name-status origin/main "$head"
fi

printf '%s\n' '== Relevant file map =='
fd -HI -t f . -E .git -E target \
 | rg '(pom\.xml$|AGENTS\.md$|workflows/.*\.(yml|yaml)$|Maven|maven|Report|report|Audit|DocumentValidation|PolicyOverride|Attribution|sbom|Semgrep|semgrep)' \
 | sed -n '1,260p'

printf '%s\n' '== Parser and Semgrep references =='
rg -n -C 5 \
  '(surefire|failsafe|skipped|tests=|TestReport|XMLInputFactory|DocumentBuilderFactory|DOCTYPE|DTD|ENTITY|external.entities|isSupportingExternalEntities|semgrep|nosemgrep|suppress)' \
  . -g '!**/.git/**' -g '!**/target/**' | sed -n '1,800p'

printf '%s\n' '== Relevant Java outlines =='
fd -HI -t f -e java src . -E .git -E target \
 | rg '(Maven|maven|Report|report|Audit|DocumentValidation|PolicyOverride)' \
 | while IFS= read -r file; do
     printf '\n-- %s --\n' "$file"
     ast-grep outline "$file" --items all --view compact || true
   done

printf '%s\n' '== GitHub PR and current checks =='
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,reviews,statusCheckRollup \
  --jq '{headRefOid,mergeStateStatus,reviewDecision,reviews:[.reviews[]|{author:.author.login,state,commit:.commit.oid}],checks:[.statusCheckRollup[]|{name,status,conclusion,workflowName}]}'

gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '[.check_runs[]|{name,status,conclusion,details_url,app:.app.slug}]'

gh api "repos/$repo/commits/$head/status" \
  --jq '{state,sha,contexts:[.statuses[]|{context,state,target_url}]}' || true

Length of output: 98484


🏁 Script executed:

#!/bin/bash
set -u

show() {
  local file="$1"
  printf '\n===== %s =====\n' "$file"
  cat -n "$file"
}

show scripts/verify_maven_test_reports.py
show scripts/test_verify_maven_test_reports.py

printf '\n===== Exact-head parser change =====\n'
git diff --unified=100 '7b6f60a11aed506fc8dbd7e6d4aac67619bec1c5^' \
  '7b6f60a11aed506fc8dbd7e6d4aac67619bec1c5' -- \
  scripts/verify_maven_test_reports.py scripts/test_verify_maven_test_reports.py

printf '\n===== CI report-gate and synthetic-merge steps =====\n'
rg -n -C 12 \
  '(verify_maven_test_reports|mvn -B|pull_request\.head\.sha|merge_group|github\.sha|actions/checkout|permissions:|persist-credentials)' \
  .github/workflows/ci.yml .github/workflows/fuzz.yml

printf '\n===== Relevant security and filesystem methods =====\n'
ast-grep outline src/main/java/com/clearfolio/viewer/security/AuditKeySeparationGuard.java --items all --view expanded
ast-grep outline src/main/java/com/clearfolio/viewer/security/AuditPseudonymizer.java --items all --view expanded
ast-grep outline src/main/java/com/clearfolio/viewer/service/DefaultDocumentValidationService.java --items all --view expanded
ast-grep outline src/main/java/com/clearfolio/viewer/artifact/FileSystemArtifactStore.java --items all --view expanded
sed -n '1,190p' src/main/java/com/clearfolio/viewer/security/AuditKeySeparationGuard.java | nl -ba
sed -n '1,220p' src/main/java/com/clearfolio/viewer/security/AuditPseudonymizer.java | nl -ba
sed -n '1,340p' src/main/java/com/clearfolio/viewer/service/DefaultDocumentValidationService.java | nl -ba
sed -n '55,125p' src/main/java/com/clearfolio/viewer/artifact/FileSystemArtifactStore.java | nl -ba

printf '\n===== POM gates and application secret source =====\n'
rg -n -C 8 '(netty.version|jacoco-maven-plugin|maven-javadoc-plugin|MISSEDCOUNT|doclint|failOnWarnings|failOnError)' pom.xml
cat -n src/main/resources/application.yml

printf '\n===== SBOM coherence and attribution hashes =====\n'
python3 - <<'PY'
import hashlib
import json
from pathlib import Path
sbom_path = Path("docs/qa/evidence/2026-07-02-krw2b-sale-readiness/sbom-cyclonedx.json")
attribution_path = Path("docs/legal/2026-07-03-third-party-attribution.md")
sbom = json.loads(sbom_path.read_text(encoding="utf-8"))
components = sbom["components"]
netty = [c for c in components if c.get("group") == "io.netty"]
refs = {c["bom-ref"] for c in components}
edges = sbom["dependencies"]
edge_sources = {e["ref"] for e in edges}
edge_targets = {d for e in edges for d in e.get("dependsOn", [])}
netty_refs = {c["bom-ref"] for c in netty}
print("components", len(components))
print("netty_components", len(netty))
print("netty_versions", sorted({c["version"] for c in netty}))
print("netty_ref_equals_purl", all(c["bom-ref"] == c["purl"] for c in netty))
print("netty_edges_complete", netty_refs <= edge_sources and netty_refs <= edge_targets)
print("all_edges_resolve", edge_sources <= refs and edge_targets <= refs)
print("legacy_netty_present", "4.1.135.Final" in sbom_path.read_text(encoding="utf-8"))
print("sbom_sha256", hashlib.sha256(sbom_path.read_bytes()).hexdigest())
print("attribution_sha256", hashlib.sha256(attribution_path.read_bytes()).hexdigest())
PY

Length of output: 45670


🏁 Script executed:

#!/bin/bash
set -u

printf '%s\n' '===== Security and filesystem implementations ====='
for file in \
  src/main/java/com/clearfolio/viewer/security/AuditKeySeparationGuard.java \
  src/main/java/com/clearfolio/viewer/security/AuditPseudonymizer.java \
  src/main/java/com/clearfolio/viewer/service/DefaultDocumentValidationService.java \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/main/java/com/clearfolio/viewer/artifact/FileSystemArtifactStore.java
do
  printf '\n-- %s --\n' "$file"
  cat -n "$file"
done

printf '%s\n' '===== Raw audit inputs and production logger calls ====='
rg -n -C 7 --glob '*.java' \
  '(getApproverId\(\)|getApprovalToken\(\)|approverFingerprint|tokenFingerprint|\b(LOG|log|logger)\.(trace|debug|info|warn|error)\s*\()' \
  src/main/java

printf '%s\n' '===== Filesystem existence checks and missing-file mappings ====='
rg -n -C 5 --glob '*.java' \
  '(Files\.(exists|notExists|isRegularFile|readAllBytes|readString|lines|newInputStream)|NoSuchFileException)' \
  src/main/java

printf '%s\n' '===== Workflow mutation patterns ====='
rg -n -C 3 \
  '(permissions:|contents:\s*write|pull-requests:\s*write|issues:\s*write|id-token:\s*write|git push|gh (pr|api|issue)|workflow_dispatch)' \
  .github/workflows || true

printf '%s\n' '===== SBOM dependency references not declared as components ====='
python3 - <<'PY'
import json
from pathlib import Path
p = Path("docs/qa/evidence/2026-07-02-krw2b-sale-readiness/sbom-cyclonedx.json")
b = json.loads(p.read_text(encoding="utf-8"))
refs = {c["bom-ref"] for c in b["components"]}
sources = {e["ref"] for e in b["dependencies"]}
targets = {d for e in b["dependencies"] for d in e.get("dependsOn", [])}
print("unlisted_sources=", sorted(sources - refs))
print("unlisted_targets=", sorted(targets - refs))
for entry in b["dependencies"]:
    if entry["ref"] not in refs or any(d not in refs for d in entry.get("dependsOn", [])):
        print(json.dumps(entry, sort_keys=True))
PY

printf '%s\n' '===== Exact-head GitHub state ====='
repo='ContextualWisdomLab/clearfolio'
pr='270'
head='7b6f60a11aed506fc8dbd7e6d4aac67619bec1c5'
gh pr view "$pr" --repo "$repo" --json headRefOid,mergeStateStatus,reviewDecision,reviews \
  --jq '{headRefOid,mergeStateStatus,reviewDecision,reviews:[.reviews[]|{author:.author.login,state,commit:.commit.oid}]}' || true
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '[.check_runs[]|{name,status,conclusion,app:.app.slug,details_url}]' || true
gh api "repos/$repo/commits/$head/status" \
  --jq '{state,contexts:[.statuses[]|{context,state,target_url}]}' || true
gh api graphql -F owner='ContextualWisdomLab' -F name='clearfolio' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) { nodes { isResolved } }
    }
  }
}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length' || true

Length of output: 56373


@seonghobae I reviewed commit 7b6f60a11aed506fc8dbd7e6d4aac67619bec1c5.

I found no source-level blocker in the requested contracts.

  • The Maven report gate uses one bounded read per report. It removed the prior stat()-then-read race.
  • The gate limits each report to 16 MiB.
  • The gate rejects DTD and entity declarations before XML parsing.
  • The gate rejects missing reports, malformed XML, missing test suites, zero tests, skipped tests, negative counts, and non-numeric counts.
  • The Semgrep suppression applies only to the ElementTree.fromstring call after the size and declaration checks. The test suite covers those controls.
  • Exact-head CI runs the report gate after mvn -B --no-transfer-progress verify.
  • The synthetic-merge job runs the same gate after Maven verification.
  • The audit contract uses a dedicated HMAC-SHA-256 pseudonym key with domain separation and key-version validation.
  • AuditKeySeparationGuard validates Spring startup and direct DefaultDocumentValidationService construction.
  • The accepted-override log excludes raw approver identifiers and approval tokens.
  • The filesystem paths map only NoSuchFileException to a missing-file result. Other I/O failures fail closed.
  • The SBOM contains 61 components and 17 Netty components at 4.1.136.Final. The Netty purls, bom-refs, and dependency edges are coherent.
  • The committed SBOM and attribution SHA-256 values match the documented values.
  • The changed CI and fuzz workflows use read-only contents permissions and disabled persisted checkout credentials.

I do not submit APPROVE.

The requested commit is no longer the PR head. GitHub now reports PR #270 head 98870b04024f77e5a9de70e4272fc8d7a48dbdec.

The inspected state for 7b6f60a11aed506fc8dbd7e6d4aac67619bec1c5 also had strix in progress, mergeStateStatus=BLOCKED, reviewDecision=REVIEW_REQUIRED, and no counted approval. A new exact-head review is required for 98870b04024f77e5a9de70e4272fc8d7a48dbdec.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Independently review exact current head d089e6bd975a2ca7dd44c96d9307d25fe18f76ca only. Exact-head CI 31026764576, Security Scan 31026764465, SAST Semgrep 31026764579, and fuzz 31026763744 are successful. Verify the CodeRabbit-requested non-skipped positive-test gate; zero failure/error acceptance; one-read 16 MiB bound; strict UTF-8 with optional UTF-8 BOM; rejection of NUL, UTF-16 declaration bypasses, DTDs, entities, malformed and negative-count evidence; exact-head and synthetic-merge invocation; and the narrowly justified native parser suppression. Reverify the complete audit-pseudonymization, key-separation, Netty, SBOM/attribution, filesystem, coverage, Javadoc, and buyer-evidence contract. Submit formal review evidence only for exact head d089e6bd975a2ca7dd44c96d9307d25fe18f76ca; independent write-authorized approval remains a separate mandatory gate.

@coderabbitai

coderabbitai Bot commented Aug 5, 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

repo='ContextualWisdomLab/clearfolio'
pr='270'
head='d089e6bd975a2ca7dd44c96d9307d25fe18f76ca'

printf '%s\n' '== Requested commit and checkout =='
git rev-parse HEAD
git cat-file -t "$head"
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$head"
git diff --name-status "${head}^" "$head"

printf '%s\n' '== Relevant source map =='
fd -HI -t f . -E .git -E target \
  | rg '(^|/)(verify_maven_test_reports|test_verify_maven_test_reports|render_third_party_attribution|test_render_third_party_attribution)\.py$|(^|/)pom\.xml$|(^|/)(AuditKeySeparationGuard|AuditPseudonymizer|DefaultDocumentValidationService|PolicyOverrideRequest|FileSystemArtifactStore)\.java$|(^|/)(ci|fuzz)\.ya?ml$|sbom-cyclonedx\.json$|third-party-attribution\.md$|application\.yml$' \
  | sort

printf '%s\n' '== XML report parser, test coverage, and exact-head diff =='
for path in scripts/verify_maven_test_reports.py scripts/test_verify_maven_test_reports.py; do
  printf '\n===== %s =====\n' "$path"
  cat -n "$path"
done
git diff --unified=120 "${head}^" "$head" -- \
  scripts/verify_maven_test_reports.py \
  scripts/test_verify_maven_test_reports.py \
  .github/workflows/ci.yml \
  .github/workflows/fuzz.yml

printf '%s\n' '== Parser suppression and workflow invocation =='
rg -n -C 8 \
  '(nosemgrep|semgrep|ElementTree|fromstring|verify_maven_test_reports|pull_request\.head\.sha|merge_group|github\.sha|actions/checkout|persist-credentials|permissions:)' \
  scripts .github/workflows

printf '%s\n' '== Security and filesystem implementations =='
for path in \
  src/main/java/com/clearfolio/viewer/security/AuditKeySeparationGuard.java \
  src/main/java/com/clearfolio/viewer/security/AuditPseudonymizer.java \
  src/main/java/com/clearfolio/viewer/service/DefaultDocumentValidationService.java \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/main/java/com/clearfolio/viewer/artifact/FileSystemArtifactStore.java \
  src/main/resources/application.yml
do
  printf '\n===== %s =====\n' "$path"
  cat -n "$path"
done

printf '%s\n' '== Raw audit-value flows and filesystem missing-file handling =='
rg -n -C 6 --glob '*.java' \
  '(getApproverId\(\)|getApprovalToken\(\)|approverFingerprint|tokenFingerprint|\b(LOG|log|logger)\.(trace|debug|info|warn|error)\s*\(|NoSuchFileException|Files\.(exists|notExists|isRegularFile|readAllBytes|readString|lines|newInputStream))' \
  src/main/java

printf '%s\n' '== Maven gates and dependency declarations =='
rg -n -C 8 \
  '(netty.version|4\.1\.136\.Final|jacoco-maven-plugin|MISSEDCOUNT|maven-javadoc-plugin|doclint|failOnWarnings|failOnError)' \
  pom.xml

printf '%s\n' '== SBOM and attribution coherence =='
python3 - <<'PY'
import hashlib
import json
from pathlib import Path

sbom_path = Path("docs/qa/evidence/2026-07-02-krw2b-sale-readiness/sbom-cyclonedx.json")
attribution_path = Path("docs/legal/2026-07-03-third-party-attribution.md")
sbom = json.loads(sbom_path.read_text(encoding="utf-8"))
components = sbom.get("components", [])
dependencies = sbom.get("dependencies", [])
refs = {component.get("bom-ref") for component in components}
netty = [component for component in components if component.get("group") == "io.netty"]
netty_refs = {component.get("bom-ref") for component in netty}
sources = {entry.get("ref") for entry in dependencies}
targets = {target for entry in dependencies for target in entry.get("dependsOn", [])}
text = sbom_path.read_text(encoding="utf-8")

print("components=", len(components))
print("netty_components=", len(netty))
print("netty_versions=", sorted({component.get("version") for component in netty}))
print("netty_refs_equal_purls=", all(c.get("bom-ref") == c.get("purl") for c in netty))
print("netty_edges_complete=", netty_refs <= sources and netty_refs <= targets)
print("all_edges_resolve=", sources <= refs and targets <= refs)
print("legacy_4.1.135_present=", "4.1.135.Final" in text)
print("sbom_sha256=", hashlib.sha256(sbom_path.read_bytes()).hexdigest())
print("attribution_sha256=", hashlib.sha256(attribution_path.read_bytes()).hexdigest())
PY

printf '%s\n' '== Exact-head GitHub review state =='
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,reviews,statusCheckRollup \
  --jq '{headRefOid,mergeStateStatus,reviewDecision,reviews:[.reviews[]|{author:.author.login,state,commit:.commit.oid}],checks:[.statusCheckRollup[]|{name,status,conclusion,workflowName}]}'
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '[.check_runs[]|{name,status,conclusion,app:.app.slug,details_url}]'
gh api "repos/$repo/commits/$head/status" \
  --jq '{state,sha,contexts:[.statuses[]|{context,state,target_url}]}'
gh api graphql -F owner='ContextualWisdomLab' -F name='clearfolio' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) { nodes { isResolved } }
    }
  }
}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length'

Length of output: 111262


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== SBOM unresolved dependency references and metadata component =='
python3 - <<'PY'
import json
from pathlib import Path

path = Path("docs/qa/evidence/2026-07-02-krw2b-sale-readiness/sbom-cyclonedx.json")
sbom = json.loads(path.read_text(encoding="utf-8"))
components = sbom.get("components", [])
refs = {component.get("bom-ref") for component in components}
metadata_component = sbom.get("metadata", {}).get("component", {})
metadata_ref = metadata_component.get("bom-ref")
sources = {entry.get("ref") for entry in sbom.get("dependencies", [])}
targets = {target for entry in sbom.get("dependencies", []) for target in entry.get("dependsOn", [])}

print("metadata_component_ref=", metadata_ref)
print("unlisted_dependency_sources=", sorted(sources - refs))
print("unlisted_dependency_targets=", sorted(targets - refs))
print("unlisted_sources_are_metadata=", (sources - refs) <= {metadata_ref})
print("unlisted_targets_are_metadata=", (targets - refs) <= {metadata_ref})
for entry in sbom.get("dependencies", []):
    if entry.get("ref") not in refs or any(target not in refs for target in entry.get("dependsOn", [])):
        print("unresolved_entry=", json.dumps(entry, sort_keys=True))
PY

printf '%s\n' '== Attribution generation, drift tests, and documented provenance =='
for path in \
  scripts/render_third_party_attribution.py \
  scripts/test_render_third_party_attribution.py \
  docs/qa/evidence/2026-07-02-krw2b-sale-readiness/README.md \
  docs/security/2026-08-05-netty-4.1.136-remediation.md
do
  printf '\n===== %s =====\n' "$path"
  cat -n "$path"
done

printf '%s\n' '== Changed workflow scope and mutation patterns =='
git diff --name-status origin/main HEAD -- .github
rg -n -C 4 \
  '(permissions:|contents:\s*write|pull-requests:\s*write|issues:\s*write|id-token:\s*write|actions/checkout|persist-credentials|git push|gh (pr|api|issue)|workflow_dispatch|curl .*(-X|--request)\s*(POST|PUT|PATCH|DELETE))' \
  .github/workflows

printf '%s\n' '== All production filesystem prechecks and missing-file mappings =='
rg -n -C 4 --glob '*.java' \
  '(Files\.(exists|notExists|isRegularFile)|\.exists\(\)|NoSuchFileException)' \
  src/main/java

printf '%s\n' '== Exact-head report-gate and audit contract test files =='
for path in \
  src/test/java/com/clearfolio/viewer/security/AuditKeySeparationGuardTest.java \
  src/test/java/com/clearfolio/viewer/security/AuditPseudonymizerTest.java \
  src/test/java/com/clearfolio/viewer/service/DefaultDocumentValidationServiceAuditTest.java \
  src/test/java/com/clearfolio/viewer/service/DefaultDocumentValidationServiceConfigurationTest.java \
  src/test/java/com/clearfolio/viewer/artifact/FileSystemArtifactStoreCoverageTest.java
do
  printf '\n===== %s =====\n' "$path"
  cat -n "$path"
done

Length of output: 68382


@seonghobae I reviewed exact head d089e6bd975a2ca7dd44c96d9307d25fe18f76ca only.

I found no source-level blocker in the requested scope.

  • The Maven report gate reads each report once. It reads at most 16 MiB plus one byte.
  • The gate requires strict UTF-8 and permits only an optional UTF-8 BOM.
  • The gate rejects NUL bytes, UTF-16 input, DTD declarations, entity declarations, malformed XML, missing report suites, zero tests, skipped tests, negative counts, failures, and errors.
  • The ElementTree.fromstring suppression applies only after the size, encoding, NUL, DTD, and entity checks. The regression tests cover these controls.
  • CI runs the report gate after mvn -B --no-transfer-progress verify.
  • The synthetic-merge job also runs Maven verification and the report gate.
  • AuditKeySeparationGuard enforces strong and distinct policy-signing and audit-pseudonym keys. DefaultDocumentValidationService calls the same validation during direct construction.
  • AuditPseudonymizer uses versioned, domain-separated HMAC-SHA-256 fingerprints.
  • The accepted override log records fingerprints. It does not record the raw approver identifier or approval token.
  • The config tree defines the policy and audit secret inputs.
  • The POM pins the Netty family at 4.1.136.Final.
  • The SBOM has 61 components and 17 Netty components. The Netty component versions, purls, bom-refs, and dependency edges are coherent.
  • The only dependency reference outside components is the CycloneDX metadata.component ref. Its dependency targets resolve to listed components. This is valid SBOM structure.
  • The SBOM and attribution hashes match the documented provenance hashes. The attribution drift test requires byte-for-byte generated output.
  • Production filesystem reads map only NoSuchFileException to the missing-file result. Other I/O failures fail closed.
  • CI and fuzz workflows use contents: read, disable persisted checkout credentials, and verify the checked-out SHA.

I do not submit APPROVE.

The exact-head Maven, merge-compatibility, buyer-readiness, SAST, Security Scan, and three fuzz jobs are successful. However, strix is still IN_PROGRESS. GitHub reports mergeStateStatus=BLOCKED and reviewDecision=REVIEW_REQUIRED. No counted approval exists. These conditions prevent formal approval on this head.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head d089e6bd975a2ca7dd44c96d9307d25fe18f76ca only. Verify the bounded privacy, dependency, release-evidence, and CI changes against protected main: domain-separated HMAC audit pseudonymization and key separation; no raw approver or token disclosure; Netty 4.1.136.Final family alignment; deterministic CycloneDX/attribution regeneration; exact-head versus synthetic-merge separation; zero missed production lines and branches; warning-free beginner-readable public Javadocs; and fail-closed Surefire/Failsafe XML evidence with bounded strict-UTF-8 parsing, zero skips/failures/errors, and no DTD/entity handling.

Exact-head GitHub Actions are successful: CI 31026764576, Security Scan 31026764465, SAST Semgrep 31026764579, and fuzz 31026763744. Both existing inline findings are resolved; predecessor-head comments are not approval for this head. Submit a formal exact-head review and APPROVE only if no actionable blocker remains. Do not infer independent human approval or bypass repository protections.

@coderabbitai

coderabbitai Bot commented Aug 5, 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

repo='ContextualWisdomLab/clearfolio'
pr='270'
head='d089e6bd975a2ca7dd44c96d9307d25fe18f76ca'

printf '%s\n' '== Commit identity and change scope =='
git cat-file -t "$head"
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$head"
git diff --name-status "${head}^" "$head"
if git show-ref --verify --quiet refs/remotes/origin/main; then
  git diff --name-status origin/main "$head"
fi

printf '%s\n' '== Parser and parser tests =='
for path in scripts/verify_maven_test_reports.py scripts/test_verify_maven_test_reports.py; do
  printf '\n===== %s =====\n' "$path"
  cat -n "$path"
done

printf '%s\n' '== CI and fuzz report-gate invocation =='
rg -n -C 10 \
  '(verify_maven_test_reports|mvn -B|pull_request\.head\.sha|merge_group|github\.sha|actions/checkout|persist-credentials|permissions:)' \
  .github/workflows/ci.yml .github/workflows/fuzz.yml

printf '%s\n' '== Audit and filesystem implementation outlines =='
for path in \
  src/main/java/com/clearfolio/viewer/security/AuditKeySeparationGuard.java \
  src/main/java/com/clearfolio/viewer/security/AuditPseudonymizer.java \
  src/main/java/com/clearfolio/viewer/service/DefaultDocumentValidationService.java \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/main/java/com/clearfolio/viewer/artifact/FileSystemArtifactStore.java \
  src/main/resources/application.yml
do
  printf '\n===== %s =====\n' "$path"
  cat -n "$path"
done

printf '%s\n' '== Raw audit-value flows and filesystem mappings =='
rg -n -C 5 --glob '*.java' \
  '(getApproverId\(\)|getApprovalToken\(\)|approverFingerprint|tokenFingerprint|\b(LOG|log|logger)\.(trace|debug|info|warn|error)\s*\(|NoSuchFileException|Files\.(exists|notExists|isRegularFile|readAllBytes|readString|lines|newInputStream))' \
  src/main/java

printf '%s\n' '== Maven policy gates =='
rg -n -C 8 \
  '(netty.version|4\.1\.136\.Final|jacoco-maven-plugin|MISSEDCOUNT|maven-javadoc-plugin|doclint|failOnWarnings|failOnError)' \
  pom.xml

printf '%s\n' '== SBOM consistency and provenance hashes =='
python3 - <<'PY'
import hashlib, json
from pathlib import Path
sbom_path = Path("docs/qa/evidence/2026-07-02-krw2b-sale-readiness/sbom-cyclonedx.json")
attr_path = Path("docs/legal/2026-07-03-third-party-attribution.md")
sbom = json.loads(sbom_path.read_text(encoding="utf-8"))
components = sbom.get("components", [])
refs = {c.get("bom-ref") for c in components}
netty = [c for c in components if c.get("group") == "io.netty"]
netty_refs = {c.get("bom-ref") for c in netty}
sources = {d.get("ref") for d in sbom.get("dependencies", [])}
targets = {x for d in sbom.get("dependencies", []) for x in d.get("dependsOn", [])}
print("components=", len(components))
print("netty_components=", len(netty))
print("netty_versions=", sorted({c.get("version") for c in netty}))
print("netty_refs_equal_purls=", all(c.get("bom-ref") == c.get("purl") for c in netty))
print("netty_edges_complete=", netty_refs <= sources and netty_refs <= targets)
print("all_component_edges_resolve=", sources <= refs and targets <= refs)
print("legacy_netty_present=", "4.1.135.Final" in sbom_path.read_text(encoding="utf-8"))
print("sbom_sha256=", hashlib.sha256(sbom_path.read_bytes()).hexdigest())
print("attribution_sha256=", hashlib.sha256(attr_path.read_bytes()).hexdigest())
PY

printf '%s\n' '== Current GitHub PR and requested-commit state =='
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,reviews,statusCheckRollup \
  --jq '{headRefOid,mergeStateStatus,reviewDecision,reviews:[.reviews[]|{author:.author.login,state,commit:.commit.oid}],checks:[.statusCheckRollup[]|{name,status,conclusion,workflowName}]}'
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '[.check_runs[]|{name,status,conclusion,app:.app.slug,details_url}]'
gh api "repos/$repo/commits/$head/status" \
  --jq '{state,sha,contexts:[.statuses[]|{context,state,target_url}]}'
gh api graphql -F owner='ContextualWisdomLab' -F name='clearfolio' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) { nodes { isResolved } }
    }
  }
}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length'

Length of output: 99059


@seonghobae I reviewed exact head d089e6bd975a2ca7dd44c96d9307d25fe18f76ca only.

I found no source-level blocker in the requested scope.

  • AuditPseudonymizer uses versioned, domain-separated HmacSHA256 fingerprints.
  • AuditKeySeparationGuard requires strong policy keys, a dedicated audit key, and distinct key values.
  • DefaultDocumentValidationService applies the same validation during direct construction.
  • The accepted-override log contains an approver fingerprint and a token fingerprint. It does not log the raw approver identifier or approval token.
  • PolicyOverrideRequest.toString() redacts both sensitive values.
  • The config-tree import declares the policy, audit-secret, and audit-key-version inputs.
  • The POM pins Netty at 4.1.136.Final.
  • The SBOM contains 61 components and 17 Netty components. All 17 Netty versions, PURLs, BOM references, and dependency edges are coherent. No 4.1.135.Final evidence remains.
  • The committed SBOM and attribution hashes match the documented provenance hashes.
  • JaCoCo requires zero missed lines and branches.
  • Maven Javadoc Plugin 3.12.0 runs during verify with doclint=all, failOnError=true, and failOnWarnings=true.
  • FileSystemArtifactStore.getPdf() maps only NoSuchFileException to Optional.empty(). Other IOException values fail closed.
  • The report gate reads each report once, with a 16 MiB limit plus one-byte overflow check.
  • The report gate accepts only strict UTF-8 with an optional UTF-8 BOM.
  • The report gate rejects NUL bytes, DTD declarations, entity declarations, malformed XML, invalid or negative counts, zero tests, skips, failures, and errors.
  • The native XML parser suppression is limited to the guarded ElementTree.fromstring call. Tests cover the size, encoding, NUL, DTD, and entity controls.
  • The exact-head CI job runs the report gate after Maven verification.
  • The synthetic-merge job separately runs Maven verification and the report gate.
  • The changed CI and fuzz workflows use contents: read, disable persisted checkout credentials, and verify the checked-out revision.
  • All inline review threads are resolved.

The exact-head checks are complete and successful, including Maven test, Maven merge compatibility, buyer-readiness scripts, Security Scan, SAST Semgrep, all three fuzz targets, CodeQL, and Strix. The CodeRabbit commit status is also successful.

I do not submit APPROVE.

GitHub currently reports mergeStateStatus=BLOCKED and reviewDecision=REVIEW_REQUIRED. GitHub also reports no counted approval for this exact head. These repository-protection conditions remain unsatisfied.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently review exact current head 26563218ae42eaa876c784fcf56b27f8cb810080 only.

The new bounded test-first hardening rejects Maven testsuite evidence that omits any required tests, skipped, failures, or errors count instead of silently interpreting missing outcomes as zero. Verify scripts/verify_maven_test_reports.py, its four missing-attribute regressions, the UTF-8 BOM positive fixture, canonical acceptance documentation, and CHANGELOG.md; also confirm no existing bounded-read, DTD/entity, alternate-encoding, zero-test, skip, failure, error, JaCoCo, Javadoc, privacy, Netty, SBOM, or exact-head guarantees regressed.

Exact-head CI 31033565648, Security Scan 31033564507, SAST Semgrep 31033566265, and fuzz 31033564737 all succeeded. CodeRabbit's formal review attempt was rate-limited and is not approval. Submit a formal exact-head review and APPROVE only if no actionable blocker remains; do not infer independent human approval or bypass repository protection.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please perform a formal independent review of exact current head 26563218ae42eaa876c784fcf56b27f8cb810080 against protected main at f3cc09a9838f0f88c81a2ceae22138fab80a2edb. Exact-head CI 31033565648, Security Scan 31033564507, SAST Semgrep 31033566265, and fuzz 31033564737 are completed successfully; the CodeRabbit commit status is successful and there are zero unresolved review threads. Verify the privacy-safe audit pseudonymization and key-separation boundary, coordinated Netty 4.1.136.Final evidence, deterministic CycloneDX/attribution derivation, bounded fail-closed Surefire/Failsafe XML evidence gate, exact-head and synthetic-merge verification, zero-missed production line/branch coverage, beginner-readable public Javadocs, and absence of temporary or write-scoped repair workflows. Treat stale, predecessor-head, pending, queued, skipped-required, cancelled, or absent evidence as not passing. Submit actionable findings or a formal review anchored to this exact head; do not infer approval from a status check.

@coderabbitai

coderabbitai Bot commented Aug 5, 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

repo='ContextualWisdomLab/clearfolio'
pr='270'
head='26563218ae42eaa876c784fcf56b27f8cb810080'
base='f3cc09a9838f0f88c81a2ceae22138fab80a2edb'

printf '%s\n' '== Commit identity, ancestry, and changed scope =='
git cat-file -t "$head"
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$head"
git cat-file -t "$base"
git merge-base --is-ancestor "$base" "$head" && echo 'protected base is an ancestor of requested head'
git diff --name-status "$base" "$head"
printf '%s\n' '== Latest commit changes =='
git diff --unified=100 "${head}^" "$head" -- \
  scripts/verify_maven_test_reports.py \
  scripts/test_verify_maven_test_reports.py \
  .github/workflows/ci.yml \
  .github/workflows/fuzz.yml \
  docs/engineering/acceptance-criteria.md \
  CHANGELOG.md

printf '%s\n' '== XML report gate and regression tests =='
for path in scripts/verify_maven_test_reports.py scripts/test_verify_maven_test_reports.py; do
  printf '\n===== %s =====\n' "$path"
  cat -n "$path"
done

printf '%s\n' '== CI and fuzz exact-head / synthetic-merge report-gate calls =='
rg -n -C 12 \
  '(verify_maven_test_reports|mvn -B|pull_request\.head\.sha|merge_group|github\.sha|actions/checkout|persist-credentials|permissions:)' \
  .github/workflows/ci.yml .github/workflows/fuzz.yml

printf '%s\n' '== Security, filesystem, configuration, and Maven enforcement =='
for path in \
  src/main/java/com/clearfolio/viewer/security/AuditKeySeparationGuard.java \
  src/main/java/com/clearfolio/viewer/security/AuditPseudonymizer.java \
  src/main/java/com/clearfolio/viewer/service/DefaultDocumentValidationService.java \
  src/main/java/com/clearfolio/viewer/service/PolicyOverrideRequest.java \
  src/main/java/com/clearfolio/viewer/artifact/FileSystemArtifactStore.java \
  src/main/resources/application.yml
do
  printf '\n===== %s =====\n' "$path"
  cat -n "$path"
done
rg -n -C 8 \
  '(netty.version|4\.1\.136\.Final|jacoco-maven-plugin|MISSEDCOUNT|maven-javadoc-plugin|doclint|failOnWarnings|failOnError)' \
  pom.xml

printf '%s\n' '== Raw audit value flows, filesystem mappings, and workflow mutation patterns =='
rg -n -C 5 --glob '*.java' \
  '(getApproverId\(\)|getApprovalToken\(\)|approverFingerprint|tokenFingerprint|\b(LOG|log|logger)\.(trace|debug|info|warn|error)\s*\(|NoSuchFileException|Files\.(exists|notExists|isRegularFile|readAllBytes|readString|lines|newInputStream))' \
  src/main/java
rg -n -C 4 \
  '(permissions:|contents:\s*write|pull-requests:\s*write|issues:\s*write|id-token:\s*write|git push|gh (pr|api|issue)|workflow_dispatch)' \
  .github/workflows || true

printf '%s\n' '== SBOM, attribution, and provenance coherence =='
python3 - <<'PY'
import hashlib
import json
from pathlib import Path

sbom_path = Path("docs/qa/evidence/2026-07-02-krw2b-sale-readiness/sbom-cyclonedx.json")
attr_path = Path("docs/legal/2026-07-03-third-party-attribution.md")
sbom = json.loads(sbom_path.read_text(encoding="utf-8"))
components = sbom.get("components", [])
refs = {c.get("bom-ref") for c in components}
netty = [c for c in components if c.get("group") == "io.netty"]
netty_refs = {c.get("bom-ref") for c in netty}
sources = {d.get("ref") for d in sbom.get("dependencies", [])}
targets = {x for d in sbom.get("dependencies", []) for x in d.get("dependsOn", [])}
print("components=", len(components))
print("netty_components=", len(netty))
print("netty_versions=", sorted({c.get("version") for c in netty}))
print("netty_refs_equal_purls=", all(c.get("bom-ref") == c.get("purl") for c in netty))
print("netty_edges_complete=", netty_refs <= sources and netty_refs <= targets)
print("unlisted_dependency_sources=", sorted(sources - refs))
print("unlisted_dependency_targets=", sorted(targets - refs))
print("legacy_4.1.135_present=", "4.1.135.Final" in sbom_path.read_text(encoding="utf-8"))
print("sbom_sha256=", hashlib.sha256(sbom_path.read_bytes()).hexdigest())
print("attribution_sha256=", hashlib.sha256(attr_path.read_bytes()).hexdigest())
PY
for path in \
  scripts/render_third_party_attribution.py \
  scripts/test_render_third_party_attribution.py \
  docs/qa/evidence/2026-07-02-krw2b-sale-readiness/README.md \
  docs/engineering/acceptance-criteria.md \
  CHANGELOG.md
do
  printf '\n===== %s =====\n' "$path"
  cat -n "$path"
done

printf '%s\n' '== Exact-head GitHub state =='
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,reviews,statusCheckRollup \
  --jq '{headRefOid,mergeStateStatus,reviewDecision,reviews:[.reviews[]|{author:.author.login,state,commit:.commit.oid}],checks:[.statusCheckRollup[]|{name,status,conclusion,workflowName}]}'
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '[.check_runs[]|{name,status,conclusion,app:.app.slug,details_url}]'
gh api "repos/$repo/commits/$head/status" \
  --jq '{state,sha,contexts:[.statuses[]|{context,state,target_url}]}' || true
gh api graphql -F owner='ContextualWisdomLab' -F name='clearfolio' -F number="$pr" -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) { nodes { isResolved } }
    }
  }
}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length'

Length of output: 148923


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
pr='270'
head='26563218ae42eaa876c784fcf56b27f8cb810080'

printf '%s\n' '== Protected main branch policy =='
gh api "repos/$repo/branches/main/protection/required_status_checks" \
  --jq '{strict,contexts,checks}' || true
gh api "repos/$repo/branches/main/protection/required_pull_request_reviews" \
  --jq '{required_approving_review_count,dismissal_restrictions,dismiss_stale_reviews,require_code_owner_reviews,require_last_push_approval,bypass_pull_request_allowances}' || true
gh api "repos/$repo/branches/main/protection" \
  --jq '{required_status_checks,required_pull_request_reviews,required_conversation_resolution,required_linear_history,required_signatures,enforce_admins}' || true

printf '%s\n' '== Rulesets that apply to main =='
gh api "repos/$repo/rules/branches/main" \
  --jq '[.[] | {id,name,type,enforcement,rules}]' || true

printf '%s\n' '== Exact-head review and merge state =='
gh pr view "$pr" --repo "$repo" \
  --json headRefOid,baseRefOid,mergeStateStatus,reviewDecision,reviews \
  --jq '{headRefOid,baseRefOid,mergeStateStatus,reviewDecision,reviews:[.reviews[] | {author:.author.login,state,commit:.commit.oid}]}'

printf '%s\n' '== Active or failed exact-head check runs =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" \
  --jq '[.check_runs[] | select(.status != "completed" or (.conclusion != "success" and .conclusion != "skipped")) | {name,status,conclusion,app:.app.slug,details_url}]'

Length of output: 3428


@seonghobae I reviewed exact head 26563218ae42eaa876c784fcf56b27f8cb810080 against base f3cc09a9838f0f88c81a2ceae22138fab80a2edb.

I found no actionable source-level finding.

  • The Maven report gate requires tests, skipped, failures, and errors on every testsuite.
  • The gate rejects missing, invalid, negative, zero-test, skipped, failure, and error counts.
  • The four missing-attribute regressions and the UTF-8 BOM positive fixture are present.
  • Each report has one bounded read of at most 16 MiB plus one overflow byte.
  • The gate requires UTF-8, permits a UTF-8 BOM, and rejects NUL, DTD, entity, malformed XML, and alternate encodings before parsing.
  • The Semgrep suppression is limited to the guarded ElementTree.fromstring call.
  • The PR-head job and the synthetic-merge job both run mvn -B --no-transfer-progress verify and the report gate.
  • The audit path uses versioned, domain-separated HmacSHA256 fingerprints.
  • The key guard enforces strong, distinct policy-signing and audit-pseudonym keys during Spring startup and direct service construction.
  • The accepted-override log excludes raw approver IDs and approval tokens.
  • Netty is pinned at 4.1.136.Final.
  • The SBOM contains 61 components and 17 coherent Netty components. The attribution matches the SBOM-derived output.
  • JaCoCo enforces zero missed production lines and branches.
  • Maven Javadoc Plugin 3.12.0 enforces public Java 21 documentation with doclint=all, warning failure, and error failure.
  • Filesystem reads map only NoSuchFileException to the established missing-file result.
  • Changed CI and fuzz workflows use read-only contents permissions and disable persisted checkout credentials.

GitHub confirms that the requested commit is the current PR head. All active exact-head checks are complete and successful. There are zero unresolved review threads.

I do not submit APPROVE.

GitHub reports mergeStateStatus=BLOCKED and reviewDecision=REVIEW_REQUIRED. No approval exists for this exact head. I also could not read the protected-branch policy because GitHub returned HTTP 403 to the integration. Therefore, required-review and required-check policy verification is inconclusive. A counted authorized approval and verifiable branch-protection satisfaction remain required before merge.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently review exact current head 26563218ae42eaa876c784fcf56b27f8cb810080. Validate the fail-closed Surefire/Failsafe XML evidence parser, bounded strict-UTF-8 input handling, DTD/entity/NUL rejection, mandatory complete non-negative counts, exact-head and synthetic-merge separation, zero-missed JaCoCo and warning-free public Javadoc gates, privacy-safe HMAC audit pseudonymization, key separation, coordinated Netty/SBOM evidence, and resolved CodeRabbit/GitHub Advanced Security findings. Submit exact-head review evidence only; do not infer approval from successful statuses or predecessor reviews.

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.

2 participants