diff --git a/.github/scripts/test_ci_workflow.py b/.github/scripts/test_ci_workflow.py index bdefae7..2a2169f 100644 --- a/.github/scripts/test_ci_workflow.py +++ b/.github/scripts/test_ci_workflow.py @@ -885,6 +885,44 @@ def test_ci_workflow_guard_is_run_by_ci(self) -> None: self.assertIn("python3 .github/scripts/claims_gate.py", text) self.assertIn("python3 .github/scripts/test_milestone_b_exit_checklist.py", text) + def test_v0_3_release_candidate_guards_run_in_pr_ci(self) -> None: + text = workflow_text() + contract_target = "make app-answer-release-contract PYTHON=python3" + policy_guard = "python3 .github/scripts/test_python_public_api_policy.py" + release_prep_guard = "python3 .github/scripts/test_app_answer_release_release_prep.py" + decision_guard = "python3 .github/scripts/test_v0_3_0_release_approval_decision.py" + activation_guard = "python3 .github/scripts/test_v0_3_0_version_activation.py" + source_guard = "python3 .github/scripts/test_validation_record_source.py" + + for guard in ( + policy_guard, + release_prep_guard, + decision_guard, + activation_guard, + source_guard, + "python3 .github/scripts/public_boundary_claims_gate.py", + "python3 .github/scripts/check_release_boundary_paths.py", + "python3 .github/scripts/validation_record_integrity.py", + ): + self.assertIn(guard, text) + self.assertEqual(1, text.count(guard), guard) + + self.assertLess(text.index(contract_target), text.index(policy_guard)) + self.assertLess(text.index(policy_guard), text.index(release_prep_guard)) + self.assertLess(text.index(release_prep_guard), text.index(decision_guard)) + self.assertLess(text.index(decision_guard), text.index(activation_guard)) + self.assertLess(text.index(activation_guard), text.index(source_guard)) + self.assertLess(text.index(source_guard), text.index("python3 .github/scripts/test_milestone_d_internal_contracts.py")) + self.assertLess( + text.index("python3 .github/scripts/public_boundary_claims_gate.py"), + text.index("python3 .github/scripts/check_release_boundary_paths.py"), + ) + self.assertLess( + text.index("python3 .github/scripts/check_release_boundary_paths.py"), + text.index("python3 .github/scripts/validation_record_integrity.py"), + ) + self.assertIn("fetch-depth: 0", text) + if __name__ == "__main__": unittest.main() diff --git a/.github/scripts/test_v0_3_0_version_activation.py b/.github/scripts/test_v0_3_0_version_activation.py index 8645a0c..94ac4b5 100644 --- a/.github/scripts/test_v0_3_0_version_activation.py +++ b/.github/scripts/test_v0_3_0_version_activation.py @@ -21,6 +21,7 @@ VALIDATION_README = ROOT / "docs/validation/README.md" EXECUTION_STATUS = ROOT / "docs/execution-status.md" PUBLIC_RELEASE_CHECKLIST = ROOT / "docs/public-release-checklist.md" +RELEASE_PREP = ROOT / "docs/v0-3-0-release-prep.md" MAKEFILE = ROOT / "Makefile" README = ROOT / "README.md" CLAIMS = ROOT / "docs/public-boundary-claims.json" @@ -188,6 +189,14 @@ def test_v0_3_release_prep_runs_activation_guard_after_decision_guard(self) -> N self.assertLess(block.index(decision_guard), block.index(activation_guard)) self.assertLess(block.index(activation_guard), block.index(claims)) + def test_release_prep_keeps_current_artifact_workflow_out_of_scope(self) -> None: + text = normalized(RELEASE_PREP) + + self.assertIn("`.github/workflows/release.yml` artifact workflow", text) + self.assertIn('`--expected-version "ethos 0.2.0"`', text) + self.assertIn("Do not use that workflow as evidence for `0.3.0` CLI artifact readiness", text) + self.assertIn("separate CLI artifact lane", text) + if __name__ == "__main__": unittest.main() diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 562564a..1c8f90e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,6 +88,16 @@ jobs: run: python3 .github/scripts/test_evidence_anchor_v1_contract.py - name: App answer release contract target run: make app-answer-release-contract PYTHON=python3 + - name: Python public API policy tests + run: python3 .github/scripts/test_python_public_api_policy.py + - name: App answer release release-prep tests + run: python3 .github/scripts/test_app_answer_release_release_prep.py + - name: v0.3.0 release approval decision tests + run: python3 .github/scripts/test_v0_3_0_release_approval_decision.py + - name: v0.3.0 version activation tests + run: python3 .github/scripts/test_v0_3_0_version_activation.py + - name: Validation record source tests + run: python3 .github/scripts/test_validation_record_source.py - name: Milestone D internal contract target tests run: python3 .github/scripts/test_milestone_d_internal_contracts.py - name: Milestone B closeout validation record tests @@ -366,8 +376,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - run: python3 .github/scripts/test_public_surface_posture.py - run: python3 .github/scripts/claims_gate.py + - run: python3 .github/scripts/public_boundary_claims_gate.py + - run: python3 .github/scripts/check_release_boundary_paths.py + - run: python3 .github/scripts/validation_record_integrity.py dco: runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index dfb1969..86d5979 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +- boundary-exception: harden v0.3.0 release-candidate CI guards and document the current release + workflow artifact smoke pin while keeping `cargo publish`, PyPI upload, npm publish, GitHub + Release artifact publication, release/package tags, installable `0.3.0` wording, hosted, + production, Windows, bundled PDFium, benchmark, `ethos-doc`, `ethos-rag`, and DocuShell + integration blocked. - boundary-exception: activate v0.3.0 release-candidate source versions for Rust workspace and Python package metadata while keeping npm at `0.2.1` and keeping `cargo publish`, PyPI upload, npm publish, GitHub Release artifact publication, release/package tags, installable `0.3.0` diff --git a/docs/v0-3-0-release-prep.md b/docs/v0-3-0-release-prep.md index 703a52f..d9ed82d 100644 --- a/docs/v0-3-0-release-prep.md +++ b/docs/v0-3-0-release-prep.md @@ -73,6 +73,13 @@ The target runs the workspace Rust test suite, app-answer-release contract guard surface checks, 0.3.0 approval and activation guards, public posture checks, claims gates, and diff hygiene. +### 3a. Keep The Artifact Workflow Out Of Scope + +The current `.github/workflows/release.yml` artifact workflow remains pinned to the published +`0.2.x` CLI artifact lane and still smokes `--expected-version "ethos 0.2.0"`. Do not use that +workflow as evidence for `0.3.0` CLI artifact readiness until a separate CLI artifact lane updates +the expected version, records package evidence, and closes the release boundary. + ### 4. Gather Package Evidence Before Any Publication Decision Before any public package or artifact decision, record exact evidence for the surfaces that are in