diff --git a/CHANGELOG.d/central-hourly-admission-contract.md b/CHANGELOG.d/central-hourly-admission-contract.md new file mode 100644 index 000000000..b6bc32144 --- /dev/null +++ b/CHANGELOG.d/central-hourly-admission-contract.md @@ -0,0 +1 @@ +- The hourly commercial-development quality contract now follows the protected-main centralized admission boundary: `cwl-org-commercial-entrypoint: v1` plus repository-local `workflow_dispatch`/`dry_run` remain required, while repository-local `schedule`/`cron` triggers are explicitly forbidden. The operations runbook now assigns recurring cadence and disablement to the central CWL scheduler/admission owner without changing TEPP workflow credentials, queue gates, verification, or late-publication controls. diff --git a/CHANGELOG.d/rustls-tls-handshake-advisory.md b/CHANGELOG.d/rustls-tls-handshake-advisory.md new file mode 100644 index 000000000..662aa6f8f --- /dev/null +++ b/CHANGELOG.d/rustls-tls-handshake-advisory.md @@ -0,0 +1,6 @@ +# rustls TLS 1.3 handshake advisory repair + +- The workspace `rustls` pin moves from `=0.23.43` to `=0.23.45`, clearing RUSTSEC-2026-0285 / GHSA-2mjx-qc3c-rqvc, whose affected TLS 1.3 path could accept handshake messages across encryption-level boundaries. +- The pin reaches TEPP through `service_tls` directly and through `sqlx-core`, so this is a repository-wide dependency-policy prerequisite rather than a leaf TLS-only change. +- `CVE-2025-61730` is intentionally not attributed to `rustls`; the RustSec advisory mentions it only as the functionally similar Go `crypto/tls` issue. +- This fragment preserves the security release note while #526 remains stacked on #523; the surviving root changelog can absorb it after the parent lands without carrying the former incorrect CVE attribution. diff --git a/Cargo.lock b/Cargo.lock index 454a7d612..1b4fed0cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1446,9 +1446,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustls" -version = "0.23.43" +version = "0.23.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" +checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" dependencies = [ "once_cell", "ring", diff --git a/Cargo.toml b/Cargo.toml index dac992821..b8da76d0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -143,7 +143,7 @@ sha2 = { version = "=0.10.9", default-features = false } uuid = { version = "=1.24.0", features = ["serde", "v7"] } tokio = { version = "=1.47.1", default-features = false, features = ["rt-multi-thread", "macros", "time"] } sqlx = { version = "=0.8.6", default-features = false, features = ["runtime-tokio", "postgres", "tls-rustls-ring-webpki"] } -rustls = { version = "=0.23.43", default-features = false, features = ["std", "tls12", "ring"] } +rustls = { version = "=0.23.45", default-features = false, features = ["std", "tls12", "ring"] } [workspace.lints.rust] unsafe_code = "deny" diff --git a/docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md b/docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md index cd78f1ca8..820f235f2 100644 --- a/docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md +++ b/docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md @@ -6,12 +6,13 @@ issue. It is separate from the deterministic minute-17 quality sentinel and never merges, releases, deploys, approves, or changes reviewer credentials. -## Schedule and queue behavior +## Admission and queue behavior -`.github/workflows/hourly-nim-product-development.yml` runs at minute 47 of every -hour and supports `workflow_dispatch` with `dry_run=true`. The nonzero minute -avoids the busiest scheduler boundary. A repository-scoped concurrency group -does not cancel an active run. +`.github/workflows/hourly-nim-product-development.yml` is the TEPP dispatchable +commercial entrypoint and supports `workflow_dispatch` with `dry_run=true`. +Recurring cadence is supplied by the central CWL scheduler/admission owner; the +repository workflow intentionally has no local `schedule` or `cron` trigger. A +repository-scoped concurrency group does not cancel an active run. Before checkout or model execution, the proposal job reads at most one open pull request and one open issue. Unreadable inventory, any open PR or issue, any @@ -55,7 +56,7 @@ Do not place GitHub App credentials in the proposal or verifier jobs. Do not reuse the existing review App or alter its variable, secret, identity, or provider route. Do not configure `COPILOT_GITHUB_TOKEN`. -A manual dry run verifies scheduling, queue, and prompt contracts without model +A manual dry run verifies admission, queue, and prompt contracts without model or publication credentials. Missing production credentials leave the hourly developer disabled rather than falling back to `GITHUB_TOKEN`. @@ -160,10 +161,12 @@ write token. ## Disablement and rollback -Disable scheduled development by disabling the workflow, removing its schedule, -or removing any one of the five provider credentials. Removing any provider key -stops model execution; removing the Maintainer App values stops publication. -The minute-17 deterministic quality sentinel continues independently. +Recurring cadence is disabled at the central CWL scheduler/admission owner; the +TEPP repository workflow owns no local schedule to remove. Repository-side +execution can be disabled by disabling the workflow or removing any one of the +five provider credentials. Removing any provider key stops model execution; +removing the Maintainer App values stops publication. The minute-17 deterministic +quality sentinel continues independently. Rollback a faulty workflow through a reviewed revert PR. Do not edit branch protection, review workflows, or release workflows as an incident shortcut. @@ -177,7 +180,7 @@ references them. inference broker could keep upstream secrets outside the runner. - Each configured provider may process repository source; operators must review confidentiality, retention, regional, and contractual obligations for every - provider before enabling the schedule. + provider before enabling the centrally owned cadence. - The verifier executes untrusted code on an ephemeral hosted runner with outbound network access, but receives no publication, provider, OIDC, artifact/cache runtime, command-file, or reviewer credential. diff --git a/tests/quality/test_hourly_nim_product_development.py b/tests/quality/test_hourly_nim_product_development.py index e2a1a03a0..68d04d688 100644 --- a/tests/quality/test_hourly_nim_product_development.py +++ b/tests/quality/test_hourly_nim_product_development.py @@ -37,12 +37,12 @@ class HourlyNimProductDevelopmentContractTests(unittest.TestCase): """Structural tests for the credential-separated product-development loop.""" def test_hourly_workflow_schedule_credentials_and_queue_gate(self) -> None: - """Run at minute 47 with provider discovery and fail closed around inventory.""" + """Require central admission and fail closed around inventory and credentials.""" text = _text(WORKFLOW) bootstrap = _text(BOOTSTRAP) for token in ( - 'cron: "47 * * * *"', + "# cwl-org-commercial-entrypoint: v1", "workflow_dispatch:", "dry_run:", "hourly-nim-product-development-${{ github.repository }}", @@ -79,6 +79,8 @@ def test_hourly_workflow_schedule_credentials_and_queue_gate(self) -> None: self.assertIn(token, text) for token in ("discover_all_models", "register_credential", "PROVIDER_CREDENTIAL_NAMES"): self.assertIn(token, bootstrap) + self.assertNotIn("schedule:", text) + self.assertNotIn("cron:", text) self.assertNotIn("COPILOT_GITHUB_TOKEN", text) self.assertNotIn("CONTEXTUAL_ORCHESTRATOR_TOKEN=", text) self.assertEqual(text.count("gh pr create"), 1) @@ -278,6 +280,7 @@ def test_hourly_queue_reflects_current_open_inventory(self) -> None: for pull_request in (93, 94, 97, 101, 102, 104, 108, 109, 111, 112): with self.subTest(pull_request=pull_request): self.assertNotIn(f"PR #{pull_request}", runbook) + def test_bootstrap_registers_each_provider_key_and_removes_environment_values(self) -> None: """Exercise the real bootstrap loop with a key-counting KV double."""