Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CI.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
8 changes: 5 additions & 3 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down
14 changes: 14 additions & 0 deletions releases/acceptance/0.3.6.json
Original file line number Diff line number Diff line change
@@ -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."
}
}
4 changes: 2 additions & 2 deletions supervisor/pig_supervisor/publication.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
{
Expand Down Expand Up @@ -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:
Expand Down
14 changes: 7 additions & 7 deletions tests/test_publication.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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")],
Expand All @@ -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
Expand Down
Loading