Restore trustworthy governance signals

This commit is contained in:
pulse-triage[bot]
2026-08-31 00:51:20 +01:00
parent 79967177ea
commit eb0d17c282
8 changed files with 188 additions and 90 deletions
+9 -6
View File
@@ -22,9 +22,11 @@ the generated shell program.
Workflows triggered by `pull_request` cannot reference confidential repository
secrets. Canonical governance therefore keeps its pull-request checks local to
the public checkout. `canonical-private-governance.yml` performs cross-repo
status, control-plane, subsystem-registry, mobile compatibility, and
repo-governance checks only after a push to `main`, so unmerged pull-request
code cannot replace the instructions that receive `WORKFLOW_PAT`.
status, control-plane, subsystem-registry, subsystem-contract, mobile
compatibility, and repo-governance checks only after a push to `main`, so
unmerged pull-request code cannot replace the instructions that receive
`WORKFLOW_PAT`. The public job still audits contract structure and every public
path; only private path existence is deferred to that credential-isolated job.
`PULSE_LICENSE_PUBLIC_KEY` is the sole explicit PR exception because that
legacy secret value is intentionally non-confidential.
@@ -39,9 +41,10 @@ checksummed release asset and SSH signature, re-verify release and build
attestations, and require the exact Docker Hub, GHCR, and OCI Helm identities
to remain equal to the digests committed at activation. Stable Docker Hub and
GHCR discovery aliases (`latest`, major, and major-minor) must also retain
those identities. Every run retains a
machine-readable evidence packet for 90 days, including partial outcomes when
a check fails. Six-hour lock-watch evidence explicitly records its narrower
those identities. Every run requests 90-day retention for a machine-readable
evidence packet, including partial outcomes when a check fails; GitHub applies
the repository's configured retention maximum and reports any clamp in the
workflow warning. Six-hour lock-watch evidence explicitly records its narrower
`release_lock` mode and skipped full-surface checks. The job is read-only and
requires the public `PULSE_UPDATE_SIGNING_PUBLIC_KEY` repository variable.
+3 -1
View File
@@ -136,7 +136,9 @@ jobs:
run: go test ./internal/mutationregistry ./internal/ai/tools -run 'Test(EveryRegisteredMutationHasDisposition|InfrastructureAPIRoutesResolveToRegistry|TransportCommandCatalogsResolveToRegistry|PatrolJobRegistrationResolvesToRegistry|RuntimeCandidateAuditNegativeFixtures|ActionRouteMethodAuthorityIsExactAndLookalikesFailClosed|NonAdmittingTransportMessagesCannotCarryDispatchAuthority|UnknownTransportLookalikeFailsClosed|RegisteredModelMutationSchemasResolveToClosedRegistry|RetiredMutationAliasesCannotShadowExtensions)' -count=1
- name: Run contract audit
run: python3 scripts/release_control/contract_audit.py --check
# Cross-repository path existence is checked with the credential-isolated
# sibling checkouts after merge. Keep PR validation scoped to public truth.
run: python3 scripts/release_control/contract_audit.py --check --repo-scope pulse
- name: Run canonical completion guard unit tests
run: python3 scripts/release_control/canonical_completion_guard_test.py
@@ -109,6 +109,9 @@ jobs:
- name: Run complete cross-repository registry audit
run: python3 scripts/release_control/registry_audit.py --check
- name: Run complete cross-repository contract audit
run: python3 scripts/release_control/contract_audit.py --check
- name: Run repo governance guardrail tests
env:
PULSE_REPO_ROOT_PULSE: ${{ github.workspace }}/repos/pulse
+26 -20
View File
@@ -66,13 +66,16 @@ jobs:
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2026-03-10' \
"repos/${REPOSITORY}/releases/latest" > "${release_json}"
jq -e '
(.id | type == "number") and
(.tag_name | type == "string" and test("^v[0-9]+\\.[0-9]+\\.[0-9]+$")) and
(.target_commitish | type == "string" and test("^[0-9a-f]{40}$")) and
.draft == false and .prerelease == false and .immutable == true and
(.published_at | type == "string" and length > 0)
' "${release_json}" >/dev/null
if ! jq -e '
(.id | type == "number") and
(.tag_name | type == "string" and test("^v[0-9]+\\.[0-9]+\\.[0-9]+$")) and
(.target_commitish | type == "string" and test("^[0-9a-f]{40}$")) and
.draft == false and .prerelease == false and .immutable == true and
(.published_at | type == "string" and length > 0)
' "${release_json}" >/dev/null; then
echo "::error::Advertised latest release failed the immutable stable identity contract. It must be a published, non-draft vX.Y.Z release locked immutable and bound to a 40-character source commit; inspect release.json in the continuity evidence."
exit 1
fi
tag="$(jq -r '.tag_name' "${release_json}")"
release_id="$(jq -r '.id' "${release_json}")"
@@ -82,19 +85,22 @@ jobs:
--pattern release-activation.json \
--dir release-continuity-evidence
jq -e \
--arg tag "${tag}" \
--arg release_id "${release_id}" \
--arg source_sha "${source_sha}" \
'.schema_version == 1 and .tag == $tag and
.release_id == $release_id and .target_commitish == $source_sha and
(.source_release_run_id | test("^[0-9]+$")) and
(.convergence_run_id | test("^[0-9]+$")) and
(.r2_prefix | type == "string" and length > 0) and
(.server_image_digest | test("^sha256:[0-9a-f]{64}$")) and
(.control_plane_image_digest | test("^sha256:[0-9a-f]{64}$")) and
(.helm_chart_digest | test("^sha256:[0-9a-f]{64}$"))' \
"${marker}" >/dev/null
if ! jq -e \
--arg tag "${tag}" \
--arg release_id "${release_id}" \
--arg source_sha "${source_sha}" \
'.schema_version == 1 and .tag == $tag and
.release_id == $release_id and .target_commitish == $source_sha and
(.source_release_run_id | test("^[0-9]+$")) and
(.convergence_run_id | test("^[0-9]+$")) and
(.r2_prefix | type == "string" and length > 0) and
(.server_image_digest | test("^sha256:[0-9a-f]{64}$")) and
(.control_plane_image_digest | test("^sha256:[0-9a-f]{64}$")) and
(.helm_chart_digest | test("^sha256:[0-9a-f]{64}$"))' \
"${marker}" >/dev/null; then
echo "::error::release-activation.json does not bind the advertised stable tag, release, source commit, convergence runs, and published artifact digests."
exit 1
fi
echo "tag=${tag}" >> "${GITHUB_OUTPUT}"
echo "release_id=${release_id}" >> "${GITHUB_OUTPUT}"
@@ -1826,6 +1826,7 @@ func TestCanonicalCompletionGuardIsWiredIntoPreCommit(t *testing.T) {
"Contract Metadata",
"audit_contract_payload",
"contract metadata",
"--repo-scope",
"--check",
})
@@ -1868,7 +1869,7 @@ func TestCanonicalGovernanceRunsInCI(t *testing.T) {
"python3 scripts/release_control/canonical_completion_guard.py --files-from-stdin",
"python3 scripts/release_control/browser_verification_guard.py",
"python3 scripts/release_control/registry_audit.py --check --repo-scope pulse",
"python3 scripts/release_control/contract_audit.py --check",
"python3 scripts/release_control/contract_audit.py --check --repo-scope pulse",
"python3 scripts/release_control/readiness_assertion_guard.py --active-target --proof-type automated",
"python3 scripts/release_control/readiness_assertion_guard.py --active-target --proof-type hybrid",
"go test ./internal/repoctl -count=1",
@@ -1907,6 +1908,7 @@ func TestCanonicalGovernanceRunsInCI(t *testing.T) {
"python3 scripts/release_control/status_audit.py --check",
"python3 scripts/release_control/control_plane_audit.py --check",
"python3 scripts/release_control/registry_audit.py --check",
"python3 scripts/release_control/contract_audit.py --check",
"go test ./internal/repoctl -count=1",
})
if strings.Contains(privateWorkflow, "pull_request:") || strings.Contains(privateWorkflow, "workflow_dispatch:") {
@@ -160,7 +160,9 @@ func TestSecurityScanRevalidatesLatestStableDelivery(t *testing.T) {
"docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5",
`"repos/${REPOSITORY}/releases/latest"`,
`.draft == false and .prerelease == false and .immutable == true`,
"Advertised latest release failed the immutable stable identity contract",
`.release_id == $release_id and .target_commitish == $source_sha`,
"release-activation.json does not bind the advertised stable tag",
`./scripts/verify-github-release-integrity.sh`,
`./scripts/validate-published-release.sh`,
`PULSE_UPDATE_SIGNING_PUBLIC_KEY: ${{ vars.PULSE_UPDATE_SIGNING_PUBLIC_KEY }}`,
+43 -1
View File
@@ -170,11 +170,15 @@ def validate_repo_path_token(
errors: list[str],
repo_roots: dict[str, Path],
default_repo_id: str,
audited_repo_ids: set[str] | None = None,
) -> None:
resolved = resolve_repo_path_token(token, repo_roots=repo_roots, default_repo_id=default_repo_id)
if resolved is None:
errors.append(f"{rel} {heading} contains non-clean repo-relative path {token!r}")
return
repo_id = token.split(":", 1)[0] if ":" in token else default_repo_id
if audited_repo_ids is not None and repo_id not in audited_repo_ids:
return
if not resolved.exists():
errors.append(f"{rel} {heading} references missing path {token!r}")
return
@@ -214,6 +218,7 @@ def audit_contract_text(
*,
repo_roots: dict[str, Path],
default_repo_id: str,
audited_repo_ids: set[str] | None = None,
) -> tuple[dict[str, Any], list[str]]:
errors: list[str] = []
path_references: list[dict[str, str]] = []
@@ -270,6 +275,7 @@ def audit_contract_text(
errors=errors,
repo_roots=repo_roots,
default_repo_id=default_repo_id,
audited_repo_ids=audited_repo_ids,
)
path_references.append({"heading": heading, "path": token})
if heading == "## Extension Points":
@@ -283,6 +289,7 @@ def audit_contract_text(
errors=errors,
repo_roots=repo_roots,
default_repo_id=default_repo_id,
audited_repo_ids=audited_repo_ids,
)
path_references.append({"heading": heading, "path": token})
@@ -339,6 +346,7 @@ def audit_contract_payload(
status_payload: dict[str, Any],
contract_texts: dict[str, str],
repo_root: Path | None = None,
audited_repo_ids: set[str] | None = None,
) -> dict[str, Any]:
errors: list[str] = []
warnings: list[str] = []
@@ -388,6 +396,7 @@ def audit_contract_payload(
contract_texts[rel],
repo_roots=repo_roots,
default_repo_id=default_repo_id,
audited_repo_ids=audited_repo_ids,
)
errors.extend(parse_errors)
metadata = parsed.get("metadata")
@@ -513,6 +522,7 @@ def audit_contract_payload(
errors=errors,
repo_roots=repo_roots,
default_repo_id=default_repo_id,
audited_repo_ids=audited_repo_ids,
)
actual_shared_paths.append(shared_path)
if shared_path in seen_shared_paths:
@@ -590,6 +600,16 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
action="store_true",
help="Read subsystem contracts from the git index instead of the working tree.",
)
parser.add_argument(
"--repo-scope",
action="append",
default=[],
metavar="REPO_ID",
help=(
"Audit paths for one available repository. Repeat to audit multiple "
"repositories; the default audits the complete active profile."
),
)
return parser.parse_args(argv)
@@ -615,11 +635,33 @@ def render_pretty(report: dict[str, Any]) -> str:
def main(argv: list[str] | None = None) -> int:
args = parse_args(list(argv or []))
status_payload = load_status_payload(staged=args.staged)
active_repos = [
repo_id
for repo_id in status_payload.get("scope", {}).get("active_repos", [])
if isinstance(repo_id, str) and repo_id.strip()
] or [canonical_repo_id(REPO_ROOT)]
local_repo = canonical_repo_id(REPO_ROOT)
requested_repos = args.repo_scope or active_repos
scope_errors: list[str] = []
if len(requested_repos) != len(set(requested_repos)):
scope_errors.append("--repo-scope must not contain duplicate repository ids")
unknown_repos = sorted(set(requested_repos) - set(active_repos), key=str.casefold)
if unknown_repos:
scope_errors.append(
"--repo-scope contains repositories outside the active profile: "
+ ", ".join(unknown_repos)
)
if local_repo not in requested_repos:
scope_errors.append(f"--repo-scope must include the local control-plane repository {local_repo!r}")
report = audit_contract_payload(
registry_payload=load_registry_payload(staged=args.staged),
status_payload=load_status_payload(staged=args.staged),
status_payload=status_payload,
contract_texts=tracked_contract_files(staged=args.staged),
audited_repo_ids=set(requested_repos) if args.repo_scope else None,
)
report["errors"] = scope_errors + report["errors"]
output = render_pretty(report) if args.pretty else json.dumps(report, indent=2, sort_keys=True)
print(output)
if args.check and report["errors"]:
+99 -61
View File
@@ -20,10 +20,75 @@ class ContractAuditTest(unittest.TestCase):
env=env,
)
def cross_repo_contract_fixture(
self,
private_path: str = "pulse-mobile:src/relay/client.ts",
) -> tuple[dict, dict, dict[str, str]]:
registry_payload = {
"subsystems": [
{
"id": "relay-runtime",
"lane": "L7",
"contract": "docs/release-control/v6/internal/subsystems/relay-runtime.md",
}
]
}
status_payload = {
"scope": {"active_repos": ["pulse", "pulse-mobile"]},
"lanes": [{"id": "L7"}],
}
contract_texts = {
"docs/release-control/v6/internal/subsystems/relay-runtime.md": f"""# Relay Runtime Contract
## Contract Metadata
```json
{{
"subsystem_id": "relay-runtime",
"lane": "L7",
"contract_file": "docs/release-control/v6/internal/subsystems/relay-runtime.md",
"status_file": "docs/release-control/v6/internal/status.json",
"registry_file": "docs/release-control/v6/internal/subsystems/registry.json",
"dependency_subsystem_ids": []
}}
```
## Purpose
Own relay runtime truth.
## Canonical Files
1. `{private_path}`
## Shared Boundaries
1. None.
## Extension Points
1. Add mobile relay reconnect behavior through `pulse-mobile:src/relay/`
## Forbidden Paths
1. Ad hoc mobile relay reconnect state.
## Completion Obligations
1. Keep mobile relay runtime changes tied to tests.
## Current State
Cross-repo relay ownership is explicit.
""",
}
return registry_payload, status_payload, contract_texts
def test_parse_args_accepts_staged_flag(self) -> None:
args = parse_args(["--check", "--staged"])
args = parse_args(["--check", "--staged", "--repo-scope", "pulse"])
self.assertTrue(args.check)
self.assertTrue(args.staged)
self.assertEqual(args.repo_scope, ["pulse"])
def test_audit_contract_payload_accepts_valid_contracts(self) -> None:
registry_payload = {
@@ -314,66 +379,7 @@ Canonical alert identity is live runtime truth.
)
def test_audit_contract_payload_accepts_cross_repo_contract_paths(self) -> None:
registry_payload = {
"subsystems": [
{
"id": "relay-runtime",
"lane": "L7",
"contract": "docs/release-control/v6/internal/subsystems/relay-runtime.md",
}
]
}
status_payload = {
"scope": {
"active_repos": ["pulse", "pulse-mobile"],
},
"lanes": [{"id": "L7"}],
}
contract_texts = {
"docs/release-control/v6/internal/subsystems/relay-runtime.md": """# Relay Runtime Contract
## Contract Metadata
```json
{
"subsystem_id": "relay-runtime",
"lane": "L7",
"contract_file": "docs/release-control/v6/internal/subsystems/relay-runtime.md",
"status_file": "docs/release-control/v6/internal/status.json",
"registry_file": "docs/release-control/v6/internal/subsystems/registry.json",
"dependency_subsystem_ids": []
}
```
## Purpose
Own relay runtime truth.
## Canonical Files
1. `pulse-mobile:src/relay/client.ts`
## Shared Boundaries
1. None.
## Extension Points
1. Add mobile relay reconnect behavior through `pulse-mobile:src/relay/`
## Forbidden Paths
1. Ad hoc mobile relay reconnect state.
## Completion Obligations
1. Keep mobile relay runtime changes tied to tests.
## Current State
Cross-repo relay ownership is explicit.
""",
}
registry_payload, status_payload, contract_texts = self.cross_repo_contract_fixture()
report = audit_contract_payload(
registry_payload=registry_payload,
@@ -383,6 +389,38 @@ Cross-repo relay ownership is explicit.
self.assertEqual(report["errors"], [])
def test_scoped_audit_defers_missing_private_paths_to_private_governance(self) -> None:
missing_path = "pulse-mobile:src/relay/definitely-missing.ts"
registry_payload, status_payload, contract_texts = self.cross_repo_contract_fixture(missing_path)
full_report = audit_contract_payload(
registry_payload=registry_payload,
status_payload=status_payload,
contract_texts=contract_texts,
)
scoped_report = audit_contract_payload(
registry_payload=registry_payload,
status_payload=status_payload,
contract_texts=contract_texts,
audited_repo_ids={"pulse"},
)
self.assertIn(f"references missing path '{missing_path}'", "\n".join(full_report["errors"]))
self.assertEqual(scoped_report["errors"], [])
def test_scoped_audit_still_rejects_unclean_private_path_tokens(self) -> None:
unclean_path = "pulse-mobile:../client.ts"
registry_payload, status_payload, contract_texts = self.cross_repo_contract_fixture(unclean_path)
report = audit_contract_payload(
registry_payload=registry_payload,
status_payload=status_payload,
contract_texts=contract_texts,
audited_repo_ids={"pulse"},
)
self.assertIn(f"contains non-clean repo-relative path '{unclean_path}'", "\n".join(report["errors"]))
def test_audit_contract_payload_isolates_local_paths_and_resolves_siblings_from_linked_worktree(self) -> None:
with tempfile.TemporaryDirectory() as tmpdir:
workspace = Path(tmpdir) / "workspace"