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
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,24 @@ versioning when releases are cut.

### Changed

- Gate public mirror published verification scripts (#2361). <!-- maestro-release-note:e47d3cb174d4 -->
- Rerun release-auth checks. <!-- maestro-release-note:79b5f14693f4 -->
- Sync release mirror for main. <!-- maestro-release-note:b4c37a629b19 -->
- Remove timing flake from rust tui tests. <!-- maestro-release-note:6afafcde7a15 -->
- Lock A2A stage gate evidence ids. <!-- maestro-release-note:73e227c68bf2 -->
- Gate published replay evidence verifier. <!-- maestro-release-note:52a6ef07d804 -->
- Give ghcr image builds more headroom. <!-- maestro-release-note:96aca1a604dc -->
- Document live smoke evidence inputs. <!-- maestro-release-note:123a4a481fad -->
- Move Slack scenarios to Platform runtime refs (#2347). <!-- maestro-release-note:61245c594cdb -->

### Fixed

- Refresh maestro from release metadata on startup (#695). <!-- maestro-release-note:ede92baf8649 -->
- Refresh maestro from release metadata on startup (#2360). <!-- maestro-release-note:0a81cbc261ba -->
- Verify full deprecation range on rerun. <!-- maestro-release-note:26ad24a575d0 -->
- Make npm deprecation reruns idempotent. <!-- maestro-release-note:c8c4d44560c3 -->
- Bundle Codex app-server integration. <!-- maestro-release-note:657ca196960f -->
- Lock tui rust dependencies for public ci. <!-- maestro-release-note:3b7472e79f22 -->
- Retire ensemble footer mode (#2350). <!-- maestro-release-note:c71b0f4cd7b8 -->
- Consume runtime signals only (#2349). <!-- maestro-release-note:539894730a32 -->

## [0.10.47] - 2026-05-29

Expand Down
15 changes: 15 additions & 0 deletions docs/protocols/release-surface-conformance.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,20 @@
"npm publish"
]
},
{
"area": "public-mirror-package-scripts",
"path": "scripts/prepare-public-release-mirror.mjs",
"evidenceType": "source",
"anchors": [
"pkg.scripts[\"release:verify:published\"] =",
"\"node scripts/smoke-registry-install.js\";",
"pkg.scripts[\"release:verify:published:e2e\"] =",
"\"node scripts/smoke-published-replay-e2e.js\";",
"pkg.scripts[\"release:verify:published:evidence\"] =",
"\"node scripts/verify-published-replay-evidence.js\";",
"pkg.scripts[\"release:deprecate\"] = \"node scripts/deprecate-release.js\";"
]
},
{
"area": "public-mirror-contract",
"path": "scripts/check-release-mirror-contract.mjs",
Expand Down Expand Up @@ -208,6 +222,7 @@
"npm run check:release-surface",
"public install docs",
"registry install smokes",
"public-only published verification scripts",
"public mirror"
]
}
Expand Down
2 changes: 1 addition & 1 deletion docs/protocols/release-surface-conformance.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ npm run check:release-surface
| published replay verifier | The evidence verifier must keep npm and Bun installer coverage, replay modes, ToolExecution checks, queryable observability traces, AgentRuntime lifecycle checks, and the release-gate assertion wired. |
| release readiness | local release gates continue to build, verify runtime deps, pack-smoke, and replay-smoke. |
| tag release | the already-published package path cannot pass on `npm view` alone; it must run npm and Bun registry install smokes plus published replay evidence validation. |
| public mirror | the sanitized public tree, release-helper mirror sync, mirror contract, and fallback publish workflow keep their guardrails. |
| public mirror | the sanitized public tree, release-helper mirror sync, public-only published verification scripts, mirror contract, and fallback publish workflow keep their guardrails. |

## Completion Bar

Expand Down
594 changes: 297 additions & 297 deletions package.json

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions scripts/check-release-surface-conformance.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const requiredAreas = [
"release-workflow",
"tag-release-workflow",
"public-mirror-workflow",
"public-mirror-package-scripts",
"public-mirror-contract",
"prepared-public-mirror",
"release-surface-docs",
Expand Down Expand Up @@ -67,6 +68,16 @@ const publishedReplayReleaseGateRequiredAnchors = [
"Published replay release gate failed",
];

const publicMirrorPackageScriptRequiredAnchors = [
'pkg.scripts["release:verify:published"] =',
'"node scripts/smoke-registry-install.js";',
'pkg.scripts["release:verify:published:e2e"] =',
'"node scripts/smoke-published-replay-e2e.js";',
'pkg.scripts["release:verify:published:evidence"] =',
'"node scripts/verify-published-replay-evidence.js";',
'pkg.scripts["release:deprecate"] = "node scripts/deprecate-release.js";',
];

export function loadReleaseSurfaceConformanceManifest(
manifestPath = defaultManifestPath,
) {
Expand Down Expand Up @@ -173,6 +184,23 @@ export function checkReleaseSurfaceConformance({
}
}
}
if (check.area === "public-mirror-package-scripts") {
if (check.path !== "scripts/prepare-public-release-mirror.mjs") {
failures.push(
`${label} must use scripts/prepare-public-release-mirror.mjs as public mirror package-script evidence`,
);
}
if (check.evidenceType !== "source") {
failures.push(
`${label} must use source evidence for public mirror package-script validation`,
);
}
for (const requiredAnchor of publicMirrorPackageScriptRequiredAnchors) {
if (!check.anchors?.includes(requiredAnchor)) {
failures.push(`${label} must anchor ${requiredAnchor}`);
}
}
}
if (!Array.isArray(check.anchors) || check.anchors.length === 0) {
failures.push(`${label} must list at least one anchor`);
continue;
Expand Down
4 changes: 4 additions & 0 deletions scripts/plan-ci-checks.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ const RELEASE_SURFACE_CONFORMANCE_FILES = new Set([
"docs/protocols/release-surface-conformance.json",
"docs/protocols/release-surface-conformance.md",
]);
const PUBLIC_MIRROR_GUARDRAIL_TEST_FILES = new Set([
"test/scripts/ci-guardrails.test.ts",
]);

function isPackageManifest(path) {
return path === "package.json" || /^packages\/[^/]+\/package\.json$/.test(path);
Expand Down Expand Up @@ -321,6 +324,7 @@ export function planCiChecks({ eventName, labels = [], changedFiles = [] }) {
labelSet.has("run-pr-checks") || ciInfrastructureOnly || !rustOnlySource;
const publicMirror =
labelSet.has("run-public-mirror") ||
files.some((path) => PUBLIC_MIRROR_GUARDRAIL_TEST_FILES.has(path)) ||
files.some(
(path) =>
!isCiInfrastructureOnlyPath(path) && !shouldSkipPublicMirrorForPath(path),
Expand Down
76 changes: 75 additions & 1 deletion test/scripts/ci-guardrails.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ describe("planCiChecks", () => {
coverage: false,
lightPrChecks: true,
prChecks: true,
publicMirror: false,
publicMirror: true,
rustHostedConformance: false,
});
expect(
Expand Down Expand Up @@ -431,6 +431,21 @@ describe("planCiChecks", () => {
});
});

it("keeps mirrored CI guardrail test changes eligible for public mirror checks", () => {
expect(
planCiChecks({
eventName: "pull_request",
changedFiles: ["test/scripts/ci-guardrails.test.ts"],
}),
).toMatchObject({
coverage: false,
lightPrChecks: true,
prChecks: true,
publicMirror: true,
rustHostedConformance: false,
});
});

it("skips coverage for colocated package test-only changes", () => {
expect(
planCiChecks({
Expand Down Expand Up @@ -1256,6 +1271,10 @@ describe("ci workflow guardrails", () => {
const metadataIndex = steps.findIndex(
(step) => step.name === "Generate version metadata",
);
const authIndex = steps.findIndex(
(step) =>
step.name === "Authenticate to Google Cloud for release metadata",
);
const authStep = steps.find(
(step) =>
step.name === "Authenticate to Google Cloud for release metadata",
Expand All @@ -1266,12 +1285,19 @@ describe("ci workflow guardrails", () => {
const gcsStep = steps[gcsIndex];
const run = gcsStep?.run ?? "";

if (!isPublicValidationWorkflow(workflow)) {
expect(canaryJob).toBeUndefined();
return;
}

expect(canaryJob).toBeDefined();
expect(canaryJob?.needs).toContain("publish");
expect(canaryJob?.permissions?.["id-token"]).toBe("write");
expect(validateIndex).toBeGreaterThan(-1);
expect(metadataIndex).toBeGreaterThan(validateIndex);
expect(authIndex).toBeGreaterThan(metadataIndex);
expect(gcsIndex).toBeGreaterThan(metadataIndex);
expect(gcsIndex).toBeGreaterThan(authIndex);
expect(authStep).toBeDefined();
expect(authStep?.uses).toContain("google-github-actions/auth@");
expect(gcsStep).toBeDefined();
Expand Down Expand Up @@ -1688,6 +1714,54 @@ describe("ci workflow guardrails", () => {
expect(syncStep?.run).toContain("scripts/sync-public-companion-branch.mjs");
});

it("runs prepared public mirror guardrails during PR mirror validation", () => {
const workflow = parse(
readFileSync(new URL("../../.github/workflows/ci.yml", import.meta.url), {
encoding: "utf8",
}),
) as Workflow;
if (isPublicValidationWorkflow(workflow)) {
expect(workflow.jobs?.["public-release-mirror"]).toBeUndefined();
return;
}
const steps = workflow.jobs?.["public-release-mirror"]?.steps ?? [];
const stepNames = steps.map((step) => step.name ?? step.id ?? "");
const verifyIndex = stepNames.indexOf(
"Verify mirrored release files match public repo",
);
const prepareIndex = stepNames.indexOf(
"Prepare public mirror tree for guardrails",
);
const syncIndex = stepNames.indexOf(
"Sync release manifest files into prepared public tree",
);
const smokeIndex = stepNames.indexOf("Smoke prepared public mirror tree");
const setupBunIndex = stepNames.indexOf(
"Setup Bun for prepared public mirror guardrails",
);
const guardrailIndex = stepNames.indexOf(
"Run prepared public mirror CI guardrails",
);

expect(verifyIndex).toBeGreaterThanOrEqual(0);
expect(prepareIndex).toBeGreaterThan(verifyIndex);
expect(syncIndex).toBeGreaterThan(prepareIndex);
expect(smokeIndex).toBeGreaterThan(syncIndex);
expect(setupBunIndex).toBeGreaterThan(smokeIndex);
expect(guardrailIndex).toBeGreaterThan(setupBunIndex);
expect(steps[prepareIndex]?.run).toContain(
"scripts/prepare-public-release-mirror.mjs",
);
expect(steps[syncIndex]?.run).toContain("scripts/sync-release-mirror.mjs");
expect(steps[smokeIndex]?.run).toContain(
"scripts/check-prepared-public-mirror-tree.mjs",
);
expect(steps[setupBunIndex]?.uses).toBe("./.github/actions/setup-bun-nx");
expect(steps[guardrailIndex]?.run).toContain(
"scripts/run-prepared-public-mirror-guardrails.mjs",
);
});

it("registry-smokes real public release mirror fallback publishes", () => {
const workflow = parse(
readFileSync(
Expand Down
47 changes: 47 additions & 0 deletions test/scripts/release-surface-conformance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,53 @@ describe("release-surface conformance", () => {
);
});

it("requires public mirror package scripts to expose published verification aliases", () => {
tempDir = join(
tmpdir(),
`release-surface-public-scripts-${process.pid}-${Date.now()}`,
);
mkdirSync(join(tempDir, "scripts"), { recursive: true });
writeFileSync(
join(tempDir, "scripts/prepare-public-release-mirror.mjs"),
[
'pkg.scripts["release:verify:published"] =',
'"node scripts/smoke-registry-install.js";',
'pkg.scripts["release:verify:published:e2e"] =',
'"node scripts/smoke-published-replay-e2e.js";',
'pkg.scripts["release:verify:published:evidence"] =',
'"node scripts/verify-published-replay-evidence.js";',
'pkg.scripts["release:deprecate"] = "node scripts/deprecate-release.js";',
].join("\n"),
"utf8",
);

const failures = checkReleaseSurfaceConformance({
rootDir: tempDir,
manifest: {
version: 1,
checks: [
{
area: "public-mirror-package-scripts",
path: "scripts/prepare-public-release-mirror.mjs",
evidenceType: "source",
anchors: [
'pkg.scripts["release:verify:published"] =',
'"node scripts/smoke-registry-install.js";',
'pkg.scripts["release:verify:published:e2e"] =',
'"node scripts/smoke-published-replay-e2e.js";',
'"node scripts/verify-published-replay-evidence.js";',
'pkg.scripts["release:deprecate"] = "node scripts/deprecate-release.js";',
],
},
],
},
});

expect(failures).toContain(
'public-mirror-package-scripts: scripts/prepare-public-release-mirror.mjs must anchor pkg.scripts["release:verify:published:evidence"] =',
);
});

it("rejects release-surface gates that can swallow failures", () => {
tempDir = join(
tmpdir(),
Expand Down
Loading