From abd0e37796f76c8b3f9c8060cabbc7ab7b181ae2 Mon Sep 17 00:00:00 2001 From: adit chandra Date: Wed, 14 Oct 2026 13:22:29 -0700 Subject: [PATCH] Record AWS-only owner approval for PIG 0.3.6 --- CI.md | 2 +- RELEASING.md | 8 +++++--- releases/acceptance/0.3.6.json | 14 ++++++++++++++ supervisor/pig_supervisor/publication.py | 4 ++-- tests/test_publication.py | 14 +++++++------- 5 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 releases/acceptance/0.3.6.json diff --git a/CI.md b/CI.md index 499548b..529cd7e 100644 --- a/CI.md +++ b/CI.md @@ -61,7 +61,7 @@ The Lease duration is shortened explicitly in handoff tests to avoid a five-minute wait. These checks do not exercise analyzer migrations or prove cloud identity, database TLS, trace persistence, analysis, or Dashboard delivery. The 0.3.0 publication gate requires real AWS installation and canonical acceptance. -Versions 0.3.1, 0.3.3, 0.3.4, and 0.3.5 permit explicit AWS-only owner sign-off in place of +Versions 0.3.1, 0.3.3, 0.3.4, 0.3.5, and 0.3.6 permit explicit AWS-only owner sign-off in place of stored reports. This does not establish a live Python-to-Go upgrade or canonical analysis acceptance. Azure and GCP remain experimental. Other versions retain the full three-cloud gate described in [RELEASING.md](RELEASING.md). diff --git a/RELEASING.md b/RELEASING.md index a3c7c7b..dafb5cd 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -7,7 +7,7 @@ The [stable catalog](catalog/stable.json) selects published releases. Local tests are not installation acceptance. Versions 0.3.0 and 0.3.1 are AWS-only releases. Report-backed acceptance covers a real AWS clean installation and canonical pipeline, plus the unattended 0.3.0 to 0.3.1 patch update -for 0.3.1. Versions 0.3.1, 0.3.3, 0.3.4, and 0.3.5 may use the explicit AWS-only owner sign-off +for 0.3.1. Versions 0.3.1, 0.3.3, 0.3.4, 0.3.5, and 0.3.6 may use the explicit AWS-only owner sign-off described below. The 0.3.3 approval leaves live analysis acceptance pending. Azure and GCP support remains experimental; these releases do not establish cloud validation for their native adapters or deployment modules. @@ -86,14 +86,14 @@ check can pass. No customer secret belongs in this repository or its evidence. A reviewer checks report contents. The workflow validates structure, binding, and freshness; it does not independently execute or audit the evidence URLs. - **Owner sign-off for 0.3.1, 0.3.3, 0.3.4, and 0.3.5:** the release owner may explicitly approve AWS-only + **Owner sign-off for 0.3.1, 0.3.3, 0.3.4, 0.3.5, and 0.3.6:** the release owner may explicitly approve AWS-only publication and stable promotion in place of stored test reports. Retain all exact source, image, and requirements identities, omit the cloud reports, and supply `ownerSignOff` with `approvedBy`, timezone-aware `approvedAt`, `scope: "aws-only"`, and a `statement` explaining the approval. This is an approval record, not a claim that report-backed testing was verified. It must not contain `testedAt`, invented report URLs, or advertised rollback paths. - The exception applies only to 0.3.1, 0.3.3, 0.3.4, and 0.3.5; image execution, capabilities, + The exception applies only to 0.3.1, 0.3.3, 0.3.4, 0.3.5, and 0.3.6; image execution, capabilities, artifact integrity, anonymous access, and catalog review remain mandatory. The 0.3.3 record must document pending canonical analysis acceptance and the unverified cloud lifecycle checks. It does not certify Azure or GCP support. @@ -104,6 +104,8 @@ check can pass. No customer secret belongs in this repository or its evidence. The 0.3.5 record binds the owner's AWS-only release authorization to verified candidates and lists the unverified installation, upgrade, recovery, and canonical analysis checks. + The 0.3.6 record also identifies the unverified environment-contract bootstrap + and keeps analysis disabled with canonical acceptance pending. 5. Compute `requirementsDigest` as SHA-256 of the requirements model's canonical JSON: parse `releases/requirements/VERSION.json` with `Requirements`, dump with aliases, then serialize with sorted keys and compact separators. This internal diff --git a/releases/acceptance/0.3.6.json b/releases/acceptance/0.3.6.json new file mode 100644 index 0000000..e2eab09 --- /dev/null +++ b/releases/acceptance/0.3.6.json @@ -0,0 +1,14 @@ +{ + "version": "0.3.6", + "sourceCommit": "db79db5a2c8a0e882bc888a870d6b407e5d5e76e", + "analyzerImage": "ghcr.io/promptless/pig-trace-analyzer@sha256:0379f9d768597a08334e5854c2cd39ffbc3817ef737eb30494d080a28416481e", + "supervisorImage": "ghcr.io/promptless/pig-supervisor@sha256:b326ba6a8680cc4b594278b1a62098da613e7f0dd38113c56eeaf725eab79033", + "requirementsDigest": "6e54a80a4a4122f81184ac18eb83602d684bf27520f65cb642520be01cb0dbd9", + "rollbackTo": [], + "ownerSignOff": { + "approvedBy": "adit-chandra", + "approvedAt": "2026-10-14T20:21:41Z", + "scope": "aws-only", + "statement": "The release owner explicitly approved the version-specific policy exception for AWS-only publication and stable promotion of PIG 0.3.6 after reviewing these exact source and image identities and the missing live acceptance reports. Candidate verification confirmed anonymous image access, supervisor version and OCI revision, and executed analyzer deployment capabilities. This owner sign-off replaces stored acceptance reports. Live clean installation, canonical trace analysis and hosted and Dashboard acknowledgement, patch, minor and major upgrades including the 0.3.4 environment-contract bootstrap and Python-to-Go upgrade, pause/pin, blocked resume, secret rotation, supervisor self-update, and recovery remain unverified for these artifacts. Analysis remains disabled by owner policy and canonical acceptance remains pending. No tested rollback paths are advertised. Azure and GCP remain experimental and are not certified by this approval." + } +} diff --git a/supervisor/pig_supervisor/publication.py b/supervisor/pig_supervisor/publication.py index 5d86667..5f28c0a 100644 --- a/supervisor/pig_supervisor/publication.py +++ b/supervisor/pig_supervisor/publication.py @@ -28,7 +28,7 @@ INITIAL_RELEASE = "0.3.0" INSTALL_CHECKS = frozenset({"install", "canonicalAcceptance"}) AWS_PATCH_RELEASE = "0.3.1" -OWNER_SIGN_OFF_RELEASES = frozenset({"0.3.1", "0.3.3", "0.3.4", "0.3.5"}) +OWNER_SIGN_OFF_RELEASES = frozenset({"0.3.1", "0.3.3", "0.3.4", "0.3.5", "0.3.6"}) PATCH_CHECKS = INSTALL_CHECKS | {"patchUpdate"} CHECKS = frozenset( { @@ -92,7 +92,7 @@ def release_coverage(self): aws_patch = self.version == AWS_PATCH_RELEASE if self.owner_sign_off is not None: if self.version not in OWNER_SIGN_OFF_RELEASES: - raise ValueError("owner sign-off is permitted only for AWS-only 0.3.1, 0.3.3, 0.3.4, and 0.3.5") + raise ValueError("owner sign-off is permitted only for AWS-only 0.3.1, 0.3.3, 0.3.4, 0.3.5, and 0.3.6") if any(cloud is not None for cloud in (self.eks, self.aks, self.gke)): raise ValueError("owner sign-off must not be presented as cloud test evidence") if self.rollback_to: diff --git a/tests/test_publication.py b/tests/test_publication.py index f9c8e3d..edf07a8 100644 --- a/tests/test_publication.py +++ b/tests/test_publication.py @@ -117,7 +117,7 @@ def owner_sign_off_data(version="0.3.1"): return data -@pytest.mark.parametrize("version", ["0.3.1", "0.3.3", "0.3.4", "0.3.5"]) +@pytest.mark.parametrize("version", ["0.3.1", "0.3.3", "0.3.4", "0.3.5", "0.3.6"]) def test_owner_sign_off_accepts_exact_aws_patch_artifacts_without_claiming_tests(version): data = owner_sign_off_data(version) accepted = validate_evidence(data, version, NOW) @@ -128,15 +128,15 @@ def test_owner_sign_off_accepts_exact_aws_patch_artifacts_without_claiming_tests validate_evidence(data, version, NOW) -@pytest.mark.parametrize("version", ["0.3.0", "0.3.2", "0.3.6", "1.0.0"]) +@pytest.mark.parametrize("version", ["0.3.0", "0.3.2", "0.3.7", "1.0.0"]) def test_owner_sign_off_is_not_a_general_release_bypass(version): data = owner_sign_off_data() data["version"] = version - with pytest.raises(ValueError, match="only for AWS-only 0.3.1, 0.3.3, 0.3.4, and 0.3.5"): + with pytest.raises(ValueError, match="only for AWS-only 0.3.1, 0.3.3, 0.3.4, 0.3.5, and 0.3.6"): validate_evidence(data, version, NOW) -@pytest.mark.parametrize("version", ["0.3.1", "0.3.3", "0.3.4", "0.3.5"]) +@pytest.mark.parametrize("version", ["0.3.1", "0.3.3", "0.3.4", "0.3.5", "0.3.6"]) @pytest.mark.parametrize("cloud", ["eks", "aks", "gke"]) def test_owner_sign_off_cannot_mix_with_test_reports_or_rollback(version, cloud): data = owner_sign_off_data(version) @@ -150,14 +150,14 @@ def test_owner_sign_off_cannot_mix_with_test_reports_or_rollback(version, cloud) validate_evidence(data, version, NOW) -@pytest.mark.parametrize("version", ["0.3.1", "0.3.3", "0.3.4", "0.3.5"]) +@pytest.mark.parametrize("version", ["0.3.1", "0.3.3", "0.3.4", "0.3.5", "0.3.6"]) @pytest.mark.parametrize("offset", [-1, 15]) def test_owner_sign_off_requires_recent_approval(version, offset): with pytest.raises(ValueError, match="fourteen days"): validate_evidence(owner_sign_off_data(version), version, NOW + timedelta(days=offset)) -@pytest.mark.parametrize("version", ["0.3.1", "0.3.3", "0.3.4", "0.3.5"]) +@pytest.mark.parametrize("version", ["0.3.1", "0.3.3", "0.3.4", "0.3.5", "0.3.6"]) @pytest.mark.parametrize( ("field", "value"), [("approvedBy", " "), ("statement", ""), ("scope", "all-clouds"), ("approvedAt", "2026-09-15T00:00:00")], @@ -169,7 +169,7 @@ def test_owner_sign_off_requires_explicit_owner_scope_statement_and_timezone(ver validate_evidence(data, version, NOW) -@pytest.mark.parametrize("version", ["0.3.2", "0.3.3", "0.3.4", "0.3.5", "1.0.0"]) +@pytest.mark.parametrize("version", ["0.3.2", "0.3.3", "0.3.4", "0.3.5", "0.3.6", "1.0.0"]) def test_later_releases_retain_full_three_cloud_lifecycle_gate(version): data, _ = evidence_data() data["version"] = version