Skip to content

docs: add protected GitHub Pages publication lane - #98

Open
seonghobae wants to merge 25 commits into
docs/h2-h1-framing-owner-path-v1from
docs/pages-publication-v1
Open

seonghobae wants to merge 25 commits into
docs/h2-h1-framing-owner-path-v1from
docs/pages-publication-v1

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Refs #51, #58, #97.

Writer-safe publication child of #93 exact 175b831895a58791c5243778c508b17c25f14e46.

Repository metadata still reports has_pages:false, while docs/index.md is maintained as the buyer-facing source. A checked-in Markdown page is not public-site evidence. This PR owns only the source/workflow half of that gap and does not fabricate repository-admin enablement.

Changes:

  • adds .github/workflows/pages.yml as a manual-only publication lane that fails closed unless dispatched from protected main;
  • checks out and verifies exact github.sha, builds only ./docs through GitHub's Jekyll Pages builder, writes source-sha.txt, computes the exact rendered _site/index.html SHA-256, exports that digest as a trusted build-job output, writes the same digest to index-sha256.txt, uploads the rendered artifact, deploys through the github-pages environment, and verifies both source identity and buyer-facing root bytes after deployment;
  • pins all GitHub-owned Pages actions to exact commits (checkout@v6, configure-pages@v6, jekyll-build-pages@v1, upload-pages-artifact@v5, deploy-pages@v5);
  • scopes token authority per job: workflow-level permissions: {}, build-only contents: read + pages: read, deploy-only pages: write + id-token: write;
  • constrains every public evidence request to HTTPS, rejects every redirect with --max-redirs 0, preserves curl failure status, and requires exact HTTP 200;
  • rejects partial publication/cache skew by requiring the public digest file and SHA-256 of the fetched site root to equal the digest produced by the trusted build job, rather than treating public index-sha256.txt as the expected-digest authority;
  • adds tests/pages_workflow_contract.rs to lock manual/main-only authority, job-scoped least privilege, exact pins, source/rendered-root binding, build-to-deploy digest propagation, zero-redirect/failure-preserving/exact-200 public verification, deployment ordering and serialization;
  • maintains docs/doctoring/PAGES_PUBLISHING_TRACEABILITY.md with the admin boundary, alternatives, action authority, transport/origin/exit-status/HTTP-status/rendered-root evidence, acceptance and forward-recovery model.

The lane intentionally does not use configure-pages enablement: true: exact actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d documents that enabling Pages requires a token other than GITHUB_TOKEN and, for a GitHub App, administration+Pages write permission. That authority remains with the repository owner rather than being introduced as a repository secret.

RED/repair history includes the earlier job-permission isolation, HTTPS downgrade rejection, cross-origin redirect rejection, curl failure-status preservation, exact-HTTP-200 gates, and rendered-root binding. Fresh review found one remaining evidence-integrity gap in 2780f08f53c36f7f367a043b1097e13449552596: the verifier fetched index-sha256.txt from the public site and then used that public value as the expected digest. A cache-skewed state with a fresh source-sha.txt but stale index-sha256.txt plus matching stale / could therefore satisfy the predicate. Test-first 352c39c441e204c1a7ce15821b58e93bc49f1a67 requires build-origin digest authority; 95084621c54fae4f707969b8e3a868066bcbf082 exports the rendered-root digest from the build step and passes it through the workflow DAG to deploy; current exact 0342fbda2c0e4f97d412d12d4a025fdffd46b599 records the RCA and recovery boundary.

Current exact head is 0342fbda2c0e4f97d412d12d4a025fdffd46b599, an ordinary-forward repair touching only the existing workflow/test/TRACEABILITY scope. Fresh exact-head CI 34680605405, Supply Chain 34680605333, Release Reproducibility 34680605311, PgErd bounded-origin capacity 34680605316, and TLS H2 Performance 34680605315 are all terminal success. Exact-current technical re-review 5185751327 re-read the complete three-path range after execution and found no additional writer-safe workflow/test/doctoring or authority-boundary defect; fresh review threads are empty. The PR is Ready again. This COMMENT is technical evidence only and no independent APPROVED review is claimed.

This does not claim publication yet. Repository-owner administration must enable GitHub Actions as the Pages publishing source. After dependency-ordered protected integration, a manual run from protected main must deploy the exact protected artifact; the public HTTPS source marker must equal the protected source SHA, the public digest file must equal the build-origin rendered-root digest, and the public root bytes must hash to that same digest before issue #97 can close. No product release, gateway deployment, canary/cutover or legacy-removal credit follows from Pages publication.

@coderabbitai

coderabbitai Bot commented Sep 12, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 84ed4407-c6b7-4585-8b55-28ad785a9fc8

📥 Commits

Reviewing files that changed from the base of the PR and between 175b831 and db93bb1.

📒 Files selected for processing (3)
  • .github/workflows/pages.yml
  • docs/doctoring/PAGES_PUBLISHING_TRACEABILITY.md
  • tests/pages_workflow_contract.rs

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

GitHub Pages 수동 배포 워크플로를 추가했다. main 커밋을 검증한 뒤 docs를 빌드하고 소스 SHA를 기록한다. 배포 후 HTTPS 공개 사이트의 source-sha.txt를 재시도 방식으로 검증한다. 관련 정책 문서와 계약 테스트도 추가했다.

Changes

Pages 문서 배포

Layer / File(s) Summary
빌드 계약과 소스 무결성
.github/workflows/pages.yml, docs/doctoring/PAGES_PUBLISHING_TRACEABILITY.md, tests/pages_workflow_contract.rs
수동 실행만 허용하고 mainGITHUB_SHA 일치를 확인한다. docs를 빌드하고 소스 SHA를 Pages 아티팩트에 기록한다. 액션 고정, 권한 범위, 트리거 조건을 계약 테스트로 검증한다.
Pages 배포와 공개 사이트 검증
.github/workflows/pages.yml, tests/pages_workflow_contract.rs
빌드 완료 후 Pages 아티팩트를 배포한다. HTTPS URL을 확인하고 공개 source-sha.txt가 현재 커밋과 일치할 때까지 최대 12회 조회한다. 배포 의존성과 동시성 설정을 검증한다.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant BuildJob
  participant PagesArtifact
  participant DeployJob
  participant PublicSite
  BuildJob->>PagesArtifact: 문서 빌드 결과와 source-sha.txt 업로드
  PagesArtifact->>DeployJob: Pages 아티팩트 전달
  DeployJob->>PublicSite: 아티팩트 배포
  DeployJob->>PublicSite: HTTPS source-sha.txt 요청
  PublicSite-->>DeployJob: 공개 소스 SHA 응답
Loading

Merge Risk: ⚪ Minimal · up to db93b

The Pages workflow has no remaining actionable issue from this review and is ready to merge.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 1 files. (2 skipped: 2 u…
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 제목은 보호된 수동 GitHub Pages 게시 워크플로를 추가하는 PR의 주요 변경 사항을 정확하고 간결하게 설명합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/pages-publication-v1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Exact-current technical re-review on 891156096cff7692694aab74afe5036025c4863f: re-read the full three-path child range after terminal execution and revalidated the pinned GitHub Pages action authority. The workflow remains manual-only and fails closed off refs/heads/main; checkout and the public source-sha.txt marker are bound to the exact protected SHA; build/Jekyll authority has only contents: read + pages: read; deployment/OIDC authority is isolated to the deploy job; deployment is serialized without cancelling an in-flight publish; and post-deploy verification requires HTTPS plus exact public source-SHA convergence. actions/configure-pages@45bfe019... documents enablement=false by default and that enablement needs non-GITHUB_TOKEN admin+Pages write authority, so repository-owner enablement correctly remains outside this source lane. Current exact CI 34669688301, Supply Chain 34669688233, TLS H2 Performance 34669688274, PgErd capacity 34669688226, and Release Reproducibility 34669688225 are all terminal success. Fresh review threads are empty. I found no additional writer-safe source/test/doctoring or authority-boundary defect. This COMMENT is technical evidence only, not an independent APPROVED review; has_pages:false means no public-site completion or protected merge/release/cutover credit is claimed.

@seonghobae
seonghobae marked this pull request as ready for review September 12, 2026 03:21
@seonghobae
seonghobae marked this pull request as draft September 12, 2026 03:23

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Exact-current technical re-review on db93bb100faa37da1525f1dc0d6e246c7286b8ef: re-read all three writer-safe paths after the HTTPS redirect-downgrade repair and terminal exact-head execution. The historical verifier could follow an initial HTTPS Pages URL onto HTTP; hostile characterization reproduced that acceptance. Current source now constrains both initial and redirect protocols on both public verification requests with curl --proto '=https' --proto-redir '=https', while preserving the exact protected-SHA marker, manual protected-main authority, exact action pins, job-scoped least privilege and serialized deployment. The structural contract requires both HTTPS-only controls twice, and TRACEABILITY records the transport-integrity RCA and recovery boundary. Current exact CI 34670282108, Supply Chain 34670282112, TLS H2 Performance 34670282095, PgErd bounded-origin capacity 34670282140, and Release Reproducibility 34670282161 are all terminal success. Fresh review threads are empty. I found no additional writer-safe source/test/doctoring or authority-boundary defect. This COMMENT is technical evidence only, not an independent APPROVED review; repository has_pages:false still prevents publication-completion credit.

@seonghobae
seonghobae marked this pull request as ready for review September 12, 2026 03:35

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact current head db93bb100faa37da1525f1dc0d6e246c7286b8ef only. Focus on the three changed paths, especially GitHub Pages authority separation, exact-source binding, redirect protocol restrictions, and whether the workflow can produce false publication evidence. Do not transfer predecessor review credit.

@coderabbitai

coderabbitai Bot commented Sep 12, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected_head="db93bb100faa37da1525f1dc0d6e246c7286b8ef"
actual_head="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\n' "$actual_head" "$expected_head"
test "$actual_head" = "$expected_head"

printf '\n== Changed paths against first parent ==\n'
git diff-tree --no-commit-id --name-status -r HEAD^ HEAD

printf '\n== Workflow ==\n'
nl -ba .github/workflows/pages.yml

printf '\n== Structural test ==\n'
nl -ba tests/pages_workflow_contract.rs

printf '\n== Traceability document ==\n'
nl -ba docs/doctoring/PAGES_PUBLISHING_TRACEABILITY.md

printf '\n== Exact diff ==\n'
git diff --no-ext-diff --unified=80 HEAD^ HEAD -- \
  .github/workflows/pages.yml \
  tests/pages_workflow_contract.rs \
  docs/doctoring/PAGES_PUBLISHING_TRACEABILITY.md

printf '\n== Workflow YAML parser availability and parse ==\n'
if command -v ruby >/dev/null 2>&1; then
  ruby -e 'require "yaml"; YAML.load_file(".github/workflows/pages.yml"); puts "ruby_yaml_parse=ok"'
else
  echo "ruby unavailable; skipped"
fi

printf '\n== Relevant repository workflow conventions ==\n'
fd -a -t f -e yml -e yaml .github/workflows -x sh -c 'echo "--- $1"; sed -n "1,240p" "$1"' sh {} \;

Length of output: 24069


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected_head="db93bb100faa37da1525f1dc0d6e246c7286b8ef"
test "$(git rev-parse HEAD)" = "$expected_head"

base="$(git merge-base HEAD origin/main)"
printf 'MERGE_BASE=%s\nHEAD=%s\n' "$base" "$(git rev-parse HEAD)"

printf '\n== All PR paths and diff from main merge base ==\n'
git diff --name-status "$base" HEAD
git diff --no-ext-diff --check "$base" HEAD
git diff --no-ext-diff --unified=100 "$base" HEAD -- \
  .github/workflows/pages.yml \
  tests/pages_workflow_contract.rs \
  docs/doctoring/PAGES_PUBLISHING_TRACEABILITY.md

printf '\n== Commit scope from merge base ==\n'
git log --format='%H %s' --no-decorate "$base"..HEAD

printf '\n== Workflow files ==\n'
fd -a -t f . .github/workflows -x sh -c 'echo "--- $1"; nl -ba "$1"' sh {}

printf '\n== Cargo test registration/context ==\n'
rg -n -C 3 --glob 'Cargo.toml' --glob '*.rs' 'pages_workflow_contract|mod[[:space:]]+pages_workflow_contract|include!.*pages_workflow_contract' .

printf '\n== Repository branch protection and Pages settings (if GitHub credentials are available) ==\n'
gh api repos/ContextualWisdomLab/pingora-gateway --jq '{default_branch, has_pages, private, visibility}' || true
gh api repos/ContextualWisdomLab/pingora-gateway/branches/main/protection --jq '{required_status_checks, enforce_admins, required_pull_request_reviews, restrictions}' || true

Length of output: 209206


🤖 web_search executed:

Verify, from official GitHub documentation and the action repositories, the required GitHub Actions permissions and recommended workflow shape for actions/configure-pages v6, actions/jekyll-build-pages v1, actions/upload-pages-artifact v5, and actions/deploy-pages v5. Also verify curl --proto '=https' and --proto-redir '=https' behavior with --location.

Length of output: 17597


@seonghobae I reviewed exact head db93bb100faa37da1525f1dc0d6e246c7286b8ef only. I found no blocking defect in the three requested paths.

The workflow is manual-only. It fails unless the dispatch ref is refs/heads/main. It checks out and verifies the dispatch SHA before it builds ./docs.

The authority separation is correct. The build job has no deployment or OIDC authority. Only the deploy job has pages: write and id-token: write. The needs: build dependency and github-pages environment match GitHub Pages guidance.

The workflow writes the verified source SHA into the rendered artifact before upload. It then requires the public /source-sha.txt value to equal that same SHA. It verifies the site root only after the marker matches.

Both public fetches restrict the initial protocol and all redirect protocols to HTTPS. An HTTPS-to-HTTP redirect cannot satisfy the publication check.

The structural test covers the reviewed authority, source-binding, ordering, and redirect-protocol invariants. The traceability document accurately retains the repository-owner Pages enablement boundary. It does not claim current publication.

This is an independent source review of the specified head. It does not transfer predecessor review credit. I did not execute the workflow in this sandbox.

✅ Action performed

Review finished.

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 draft September 12, 2026 05:22

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Exact-current technical re-review on 0342fbda2c0e4f97d412d12d4a025fdffd46b599: re-read the complete three-path Pages child after the build-origin rendered-root repair and terminal exact-head execution. The prior verifier trusted public index-sha256.txt as its expected root digest, allowing a fresh source marker to coexist with a stale digest+root pair. Current source now computes SHA-256 of exact _site/index.html in the build job, writes it into the uploaded artifact, exports the same value through the workflow DAG, and requires both the public digest file and fetched root SHA-256 to equal that build-origin value. Manual protected-main-only authority, exact action pins, job-scoped least privilege, direct HTTPS/no-redirect transfer, real curl success and exact HTTP 200 remain intact. Current exact CI 34680605405, Supply Chain 34680605333, Release Reproducibility 34680605311, PgErd bounded-origin capacity 34680605316, and TLS H2 Performance 34680605315 are all terminal success. Fresh review threads are empty. I found no additional writer-safe workflow/test/doctoring or authority-boundary defect. This COMMENT is technical evidence only, not an independent APPROVED review; repository has_pages:false still prevents publication-completion credit.

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

Labels

documentation Improvements or additions to documentation priority: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant