From 188a4bf32c2bea6af0e4015dcf15006336a4f5b8 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 19 Aug 2026 05:05:08 -0700 Subject: [PATCH 1/8] ci: refresh Rust branch coverage nightly --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f804f7496..95c2fa1d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,13 +73,13 @@ jobs: persist-credentials: false - uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 with: - toolchain: nightly-2026-08-01 + toolchain: nightly-2026-08-18 components: llvm-tools-preview - name: Install pinned cargo-llvm-cov run: cargo +1.97.1 install cargo-llvm-cov --version 0.8.6 --locked - name: Measure production functions, lines, regions, and branches run: >- - cargo +nightly-2026-08-01 llvm-cov + cargo +nightly-2026-08-18 llvm-cov --locked --workspace --all-features @@ -88,7 +88,7 @@ jobs: --output-path coverage.json - name: Record uncovered production lines run: >- - cargo +nightly-2026-08-01 llvm-cov report + cargo +nightly-2026-08-18 llvm-cov report --branch --text --show-missing-lines From bb303b70f5a97bdfaebeea4ed9ae96143fd9e47e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 19 Aug 2026 05:05:23 -0700 Subject: [PATCH 2/8] ci: track the pinned Rust toolchain --- .github/dependabot.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..d331df5fd --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: "rust-toolchain" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 1 From 94aa3781275a959e7900d13a0d3cd168f11651f3 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 19 Aug 2026 05:05:53 -0700 Subject: [PATCH 3/8] test: lock Rust toolchain freshness contracts --- tests/test_rust_toolchain_contract.py | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/test_rust_toolchain_contract.py diff --git a/tests/test_rust_toolchain_contract.py b/tests/test_rust_toolchain_contract.py new file mode 100644 index 000000000..f60867e31 --- /dev/null +++ b/tests/test_rust_toolchain_contract.py @@ -0,0 +1,39 @@ +"""Regression contracts for the reproducible Rust compiler baseline.""" + +from __future__ import annotations + +import tomllib +import unittest +from pathlib import Path + + +REPOSITORY_ROOT = Path(__file__).resolve().parents[1] +RUST_TOOLCHAIN = REPOSITORY_ROOT / "rust-toolchain.toml" +CI_WORKFLOW = REPOSITORY_ROOT / ".github" / "workflows" / "ci.yml" +DEPENDABOT = REPOSITORY_ROOT / ".github" / "dependabot.yml" + + +class RustToolchainContractTests(unittest.TestCase): + """Keep stable builds reproducible and branch coverage intentionally fresh.""" + + def test_stable_toolchain_is_exact_and_automatically_tracked(self) -> None: + """The stable compiler changes only through a reviewable manifest update.""" + + manifest = tomllib.loads(RUST_TOOLCHAIN.read_text(encoding="utf-8")) + self.assertEqual(manifest["toolchain"]["channel"], "1.97.1") + + dependabot = DEPENDABOT.read_text(encoding="utf-8") + self.assertIn('package-ecosystem: "rust-toolchain"', dependabot) + self.assertIn('directory: "/"', dependabot) + self.assertIn('interval: "weekly"', dependabot) + + def test_branch_coverage_uses_one_current_date_pinned_nightly(self) -> None: + """Every branch-coverage command uses the same reviewed nightly snapshot.""" + + workflow = CI_WORKFLOW.read_text(encoding="utf-8") + self.assertEqual(workflow.count("nightly-2026-08-18"), 3) + self.assertNotIn("nightly-2026-08-01", workflow) + + +if __name__ == "__main__": # pragma: no cover + unittest.main() From 824bd81d6cceb7a2322cdaf4899c96828e3b4721 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 19 Aug 2026 05:06:17 -0700 Subject: [PATCH 4/8] docs: record Rust toolchain freshness policy --- docs/doctoring/rust-toolchain-freshness.md | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/doctoring/rust-toolchain-freshness.md diff --git a/docs/doctoring/rust-toolchain-freshness.md b/docs/doctoring/rust-toolchain-freshness.md new file mode 100644 index 000000000..de566637e --- /dev/null +++ b/docs/doctoring/rust-toolchain-freshness.md @@ -0,0 +1,43 @@ +# Rust toolchain freshness and reproducibility + +## Decision + +OriginWeave keeps Rust `1.97.1` as the exact stable compiler baseline. As of +2026-08-19 this is the current stable point release, so the generic compiler +suggestion to upgrade does not justify replacing it with a floating `stable` +channel. + +Production line, region, and function coverage remains on the stable compiler. +Branch coverage uses the independently date-pinned `nightly-2026-08-18` +toolchain because upstream `cargo-llvm-cov` still identifies Rust branch +coverage as unstable and nightly-only. Every branch-coverage command must use +the same date pin, and exact-head CI must prove that `llvm-tools-preview`, the +pinned `cargo-llvm-cov` release, the workspace, and the coverage verifier remain +compatible before merge. + +The root `rust-toolchain.toml` is tracked through GitHub Dependabot's +`rust-toolchain` ecosystem. Toolchain changes therefore arrive as reviewable +pull requests rather than silently changing underneath local or CI builds. +Date-pinned branch-coverage nightly updates remain explicit infrastructure +changes and must preserve the repository contract test. + +## Failure interpretation + +The historical OriginWeave coverage failure at PR #192 predecessor head +`ccb7d31dfe7654bab800d463c2391cc1a19c7d74` was not proof that the compiler was +too old. The compiler emitted the generic note while rejecting a non-stable +const conversion in test code. The current PR #192 head moved that conversion +out of a constant and passed the complete native CI workflow. Toolchain +freshness and source compatibility are therefore maintained as separate +controls. + +## References + +GitHub. (2026). *Dependabot supports updates for Rust toolchains*. GitHub +Changelog. https://github.blog/changelog/ + +Rust Project Developers. (2026, July 16). *Announcing Rust 1.97.1*. Rust Blog. +https://blog.rust-lang.org/2026/07/16/Rust-1.97.1/ + +Taiki Endo and contributors. (2026). *cargo-llvm-cov* (Version 0.8.6) +[Computer software]. GitHub. https://github.com/taiki-e/cargo-llvm-cov From cab590d713fbba6dfd50d975c9a8370d79053d3b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 19 Aug 2026 06:38:43 -0700 Subject: [PATCH 5/8] ci: apply the reviewed nightly pin to autonomous development --- .../workflows/apply-rust-nightly-refresh.yml | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/apply-rust-nightly-refresh.yml diff --git a/.github/workflows/apply-rust-nightly-refresh.yml b/.github/workflows/apply-rust-nightly-refresh.yml new file mode 100644 index 000000000..0f005979a --- /dev/null +++ b/.github/workflows/apply-rust-nightly-refresh.yml @@ -0,0 +1,58 @@ +name: Apply Rust nightly refresh once + +on: + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + refresh-owned-branch: + if: >- + github.repository == 'ContextualWisdomLab/OriginWeave' && + github.event.pull_request.head.repo.full_name == github.repository && + github.event.pull_request.head.ref == 'agent/rust-toolchain-refresh-2026-08-19' && + github.event.pull_request.user.login == 'seonghobae' + runs-on: ubuntu-24.04 + timeout-minutes: 10 + permissions: + contents: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event.pull_request.head.ref }} + fetch-depth: 0 + persist-credentials: true + - name: Replace only the reviewed nightly snapshot + env: + EXPECTED_HEAD: ${{ github.event.pull_request.head.sha }} + HEAD_BRANCH: ${{ github.event.pull_request.head.ref }} + run: | + set -euo pipefail + test "$(git rev-parse HEAD)" = "$EXPECTED_HEAD" + python3 - <<'PY' + from pathlib import Path + + path = Path('.github/workflows/hourly-product-development.yml') + source = path.read_text(encoding='utf-8') + old = 'nightly-2026-08-01' + new = 'nightly-2026-08-18' + count = source.count(old) + if count == 0: + print('Autonomous development workflow already uses the reviewed nightly.') + else: + path.write_text(source.replace(old, new), encoding='utf-8') + print(f'Replaced {count} exact nightly selector(s).') + PY + git diff --check + if git diff --quiet -- .github/workflows/hourly-product-development.yml; then + exit 0 + fi + changed="$(git diff --name-only)" + test "$changed" = ".github/workflows/hourly-product-development.yml" + git config user.name "Seongho Bae" + git config user.email "me@seonghobae.me" + git add .github/workflows/hourly-product-development.yml + git commit -m "ci: refresh autonomous Rust nightly" + git push origin "HEAD:${HEAD_BRANCH}" From deac81f35718aea1fbd4303ce1da310c94fa6f09 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 19 Aug 2026 06:40:24 -0700 Subject: [PATCH 6/8] ci: materialize autonomous nightly refresh artifact --- .../workflows/apply-rust-nightly-refresh.yml | 52 ++++++++----------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/.github/workflows/apply-rust-nightly-refresh.yml b/.github/workflows/apply-rust-nightly-refresh.yml index 0f005979a..f393f6889 100644 --- a/.github/workflows/apply-rust-nightly-refresh.yml +++ b/.github/workflows/apply-rust-nightly-refresh.yml @@ -1,4 +1,4 @@ -name: Apply Rust nightly refresh once +name: Materialize Rust nightly refresh once on: pull_request: @@ -8,7 +8,7 @@ permissions: contents: read jobs: - refresh-owned-branch: + materialize-owned-branch: if: >- github.repository == 'ContextualWisdomLab/OriginWeave' && github.event.pull_request.head.repo.full_name == github.repository && @@ -16,43 +16,35 @@ jobs: github.event.pull_request.user.login == 'seonghobae' runs-on: ubuntu-24.04 timeout-minutes: 10 - permissions: - contents: write steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - ref: ${{ github.event.pull_request.head.ref }} - fetch-depth: 0 - persist-credentials: true - - name: Replace only the reviewed nightly snapshot - env: - EXPECTED_HEAD: ${{ github.event.pull_request.head.sha }} - HEAD_BRANCH: ${{ github.event.pull_request.head.ref }} + ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false + - name: Materialize only the reviewed nightly snapshot run: | set -euo pipefail - test "$(git rev-parse HEAD)" = "$EXPECTED_HEAD" python3 - <<'PY' from pathlib import Path - path = Path('.github/workflows/hourly-product-development.yml') - source = path.read_text(encoding='utf-8') + source_path = Path('.github/workflows/hourly-product-development.yml') + source = source_path.read_text(encoding='utf-8') old = 'nightly-2026-08-01' new = 'nightly-2026-08-18' count = source.count(old) - if count == 0: - print('Autonomous development workflow already uses the reviewed nightly.') - else: - path.write_text(source.replace(old, new), encoding='utf-8') - print(f'Replaced {count} exact nightly selector(s).') + if count != 2: + raise SystemExit(f'expected exactly 2 predecessor selectors, found {count}') + output = Path('nightly-refresh-artifact/hourly-product-development.yml') + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(source.replace(old, new), encoding='utf-8') + refreshed = output.read_text(encoding='utf-8') + if old in refreshed or refreshed.count(new) < 2: + raise SystemExit('nightly refresh artifact failed its replacement contract') PY - git diff --check - if git diff --quiet -- .github/workflows/hourly-product-development.yml; then - exit 0 - fi - changed="$(git diff --name-only)" - test "$changed" = ".github/workflows/hourly-product-development.yml" - git config user.name "Seongho Bae" - git config user.email "me@seonghobae.me" - git add .github/workflows/hourly-product-development.yml - git commit -m "ci: refresh autonomous Rust nightly" - git push origin "HEAD:${HEAD_BRANCH}" + - name: Upload exact refreshed workflow + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: hourly-rust-nightly-${{ github.event.pull_request.head.sha }} + path: nightly-refresh-artifact/hourly-product-development.yml + if-no-files-found: error + retention-days: 1 From 5aa9581ef2bc18e02f839ee22b39b67ed7ef3efe Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 20:41:19 +0900 Subject: [PATCH 7/8] fix(ci): align hourly coverage nightly pin --- .github/workflows/hourly-product-development.yml | 4 ++-- CHANGELOG.md | 1 + docs/doctoring/rust-toolchain-freshness.md | 5 +++-- tests/test_rust_toolchain_contract.py | 5 +++++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/hourly-product-development.yml b/.github/workflows/hourly-product-development.yml index 672754c69..396af4a95 100644 --- a/.github/workflows/hourly-product-development.yml +++ b/.github/workflows/hourly-product-development.yml @@ -154,7 +154,7 @@ jobs: run: | set -euo pipefail rustup toolchain install 1.97.1 --profile minimal --component clippy,rustfmt - rustup toolchain install nightly-2026-08-01 --profile minimal --component llvm-tools-preview + rustup toolchain install nightly-2026-08-18 --profile minimal --component llvm-tools-preview cargo +1.97.1 install cargo-llvm-cov --version 0.8.6 --locked archive="${RUNNER_TEMP}/opencode-linux-x64.tar.gz" curl -fsSL -o "$archive" \ @@ -894,7 +894,7 @@ jobs: cargo +1.97.1 test --locked --workspace --all-targets cargo +1.97.1 clippy --locked --workspace --all-targets -- -D warnings RUSTDOCFLAGS='-D warnings' cargo +1.97.1 doc --locked --workspace --no-deps - cargo +nightly-2026-08-01 llvm-cov \ + cargo +nightly-2026-08-18 llvm-cov \ --locked --workspace --all-features --branch --json --summary-only \ --output-path "${RUNNER_TEMP}/coverage.json" python3 scripts/ci/verify_coverage.py "${RUNNER_TEMP}/coverage.json" diff --git a/CHANGELOG.md b/CHANGELOG.md index d17419927..35e15a860 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ All notable changes to OriginWeave are documented in this file. The format follo ### Changed +- Aligned the hourly product-development branch-coverage toolchain with the reviewed `nightly-2026-08-18` pin and corrected the official Dependabot Rust-toolchain reference. - Separated logical origin authority from resolved network destination authority; an origin grant no longer implies permission to connect to every resolver result. - Separated resolved-address authorization from direct transport evidence; an approved IP now becomes a usable stream only after the operating system reports the exact requested IP and port. - Separated exact TCP peer proof from authenticated TLS service identity; an observed peer becomes an authenticated HTTPS stream only after explicit-root, fixed-time, SAN-bound WebPKI verification over that same stream. diff --git a/docs/doctoring/rust-toolchain-freshness.md b/docs/doctoring/rust-toolchain-freshness.md index de566637e..a00e7fb08 100644 --- a/docs/doctoring/rust-toolchain-freshness.md +++ b/docs/doctoring/rust-toolchain-freshness.md @@ -33,8 +33,9 @@ controls. ## References -GitHub. (2026). *Dependabot supports updates for Rust toolchains*. GitHub -Changelog. https://github.blog/changelog/ +GitHub. (2025, August 19). *Dependabot now supports Rust toolchain updates*. +GitHub Changelog. +https://github.blog/changelog/2025-08-19-dependabot-now-supports-rust-toolchain-updates/ Rust Project Developers. (2026, July 16). *Announcing Rust 1.97.1*. Rust Blog. https://blog.rust-lang.org/2026/07/16/Rust-1.97.1/ diff --git a/tests/test_rust_toolchain_contract.py b/tests/test_rust_toolchain_contract.py index f60867e31..3a635c368 100644 --- a/tests/test_rust_toolchain_contract.py +++ b/tests/test_rust_toolchain_contract.py @@ -10,6 +10,7 @@ REPOSITORY_ROOT = Path(__file__).resolve().parents[1] RUST_TOOLCHAIN = REPOSITORY_ROOT / "rust-toolchain.toml" CI_WORKFLOW = REPOSITORY_ROOT / ".github" / "workflows" / "ci.yml" +HOURLY_WORKFLOW = REPOSITORY_ROOT / ".github" / "workflows" / "hourly-product-development.yml" DEPENDABOT = REPOSITORY_ROOT / ".github" / "dependabot.yml" @@ -34,6 +35,10 @@ def test_branch_coverage_uses_one_current_date_pinned_nightly(self) -> None: self.assertEqual(workflow.count("nightly-2026-08-18"), 3) self.assertNotIn("nightly-2026-08-01", workflow) + hourly_workflow = HOURLY_WORKFLOW.read_text(encoding="utf-8") + self.assertEqual(hourly_workflow.count("nightly-2026-08-18"), 2) + self.assertNotIn("nightly-2026-08-01", hourly_workflow) + if __name__ == "__main__": # pragma: no cover unittest.main() From e95477dd57e0b86c75b7ee037dab63ea111e2ed6 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 20:45:05 +0900 Subject: [PATCH 8/8] fix(ci): make nightly refresh idempotent --- .github/workflows/apply-rust-nightly-refresh.yml | 15 +++++++++++---- CHANGELOG.md | 2 +- tests/test_rust_toolchain_contract.py | 9 +++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/apply-rust-nightly-refresh.yml b/.github/workflows/apply-rust-nightly-refresh.yml index f393f6889..7f3186b39 100644 --- a/.github/workflows/apply-rust-nightly-refresh.yml +++ b/.github/workflows/apply-rust-nightly-refresh.yml @@ -31,12 +31,19 @@ jobs: source = source_path.read_text(encoding='utf-8') old = 'nightly-2026-08-01' new = 'nightly-2026-08-18' - count = source.count(old) - if count != 2: - raise SystemExit(f'expected exactly 2 predecessor selectors, found {count}') + old_count = source.count(old) + new_count = source.count(new) + if old_count == 2 and new_count == 0: + refreshed_source = source.replace(old, new) + elif old_count == 0 and new_count == 2: + refreshed_source = source + else: + raise SystemExit( + f'expected exactly two selectors in one state, found old={old_count}, new={new_count}' + ) output = Path('nightly-refresh-artifact/hourly-product-development.yml') output.parent.mkdir(parents=True, exist_ok=True) - output.write_text(source.replace(old, new), encoding='utf-8') + output.write_text(refreshed_source, encoding='utf-8') refreshed = output.read_text(encoding='utf-8') if old in refreshed or refreshed.count(new) < 2: raise SystemExit('nightly refresh artifact failed its replacement contract') diff --git a/CHANGELOG.md b/CHANGELOG.md index 35e15a860..879c3407e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ All notable changes to OriginWeave are documented in this file. The format follo ### Changed -- Aligned the hourly product-development branch-coverage toolchain with the reviewed `nightly-2026-08-18` pin and corrected the official Dependabot Rust-toolchain reference. +- Aligned the hourly product-development branch-coverage toolchain and its one-shot materializer with the reviewed `nightly-2026-08-18` pin, and corrected the official Dependabot Rust-toolchain reference. - Separated logical origin authority from resolved network destination authority; an origin grant no longer implies permission to connect to every resolver result. - Separated resolved-address authorization from direct transport evidence; an approved IP now becomes a usable stream only after the operating system reports the exact requested IP and port. - Separated exact TCP peer proof from authenticated TLS service identity; an observed peer becomes an authenticated HTTPS stream only after explicit-root, fixed-time, SAN-bound WebPKI verification over that same stream. diff --git a/tests/test_rust_toolchain_contract.py b/tests/test_rust_toolchain_contract.py index 3a635c368..058add241 100644 --- a/tests/test_rust_toolchain_contract.py +++ b/tests/test_rust_toolchain_contract.py @@ -11,6 +11,7 @@ RUST_TOOLCHAIN = REPOSITORY_ROOT / "rust-toolchain.toml" CI_WORKFLOW = REPOSITORY_ROOT / ".github" / "workflows" / "ci.yml" HOURLY_WORKFLOW = REPOSITORY_ROOT / ".github" / "workflows" / "hourly-product-development.yml" +REFRESH_WORKFLOW = REPOSITORY_ROOT / ".github" / "workflows" / "apply-rust-nightly-refresh.yml" DEPENDABOT = REPOSITORY_ROOT / ".github" / "dependabot.yml" @@ -39,6 +40,14 @@ def test_branch_coverage_uses_one_current_date_pinned_nightly(self) -> None: self.assertEqual(hourly_workflow.count("nightly-2026-08-18"), 2) self.assertNotIn("nightly-2026-08-01", hourly_workflow) + def test_nightly_refresh_accepts_only_old_or_already_refreshed_source(self) -> None: + """The one-shot materializer remains valid after the source is refreshed.""" + workflow = REFRESH_WORKFLOW.read_text(encoding="utf-8") + self.assertIn("old_count = source.count(old)", workflow) + self.assertIn("new_count = source.count(new)", workflow) + self.assertIn("if old_count == 2 and new_count == 0:", workflow) + self.assertIn("elif old_count == 0 and new_count == 2:", workflow) + if __name__ == "__main__": # pragma: no cover unittest.main()