From df28e9c9b060d6829387d4d59b33f52520246656 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 30 May 2026 05:50:01 +0000 Subject: [PATCH] chore: sync public mirror from internal --- CHANGELOG.md | 13 +- .../release-surface-conformance.json | 15 + docs/protocols/release-surface-conformance.md | 2 +- package.json | 594 +++++++++--------- scripts/check-release-surface-conformance.mjs | 28 + scripts/plan-ci-checks.mjs | 4 + test/scripts/ci-guardrails.test.ts | 76 ++- .../release-surface-conformance.test.ts | 47 ++ 8 files changed, 478 insertions(+), 301 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb13476df..b0e76daab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,15 +21,24 @@ versioning when releases are cut. ### Changed +- Gate public mirror published verification scripts (#2361). - Rerun release-auth checks. -- Sync release mirror for main. +- Remove timing flake from rust tui tests. +- Lock A2A stage gate evidence ids. +- Gate published replay evidence verifier. +- Give ghcr image builds more headroom. +- Document live smoke evidence inputs. +- Move Slack scenarios to Platform runtime refs (#2347). ### Fixed -- Refresh maestro from release metadata on startup (#695). +- Refresh maestro from release metadata on startup (#2360). - Verify full deprecation range on rerun. - Make npm deprecation reruns idempotent. - Bundle Codex app-server integration. +- Lock tui rust dependencies for public ci. +- Retire ensemble footer mode (#2350). +- Consume runtime signals only (#2349). ## [0.10.47] - 2026-05-29 diff --git a/docs/protocols/release-surface-conformance.json b/docs/protocols/release-surface-conformance.json index ea630f529..6a1f8347f 100644 --- a/docs/protocols/release-surface-conformance.json +++ b/docs/protocols/release-surface-conformance.json @@ -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", @@ -208,6 +222,7 @@ "npm run check:release-surface", "public install docs", "registry install smokes", + "public-only published verification scripts", "public mirror" ] } diff --git a/docs/protocols/release-surface-conformance.md b/docs/protocols/release-surface-conformance.md index 2c947e4d6..1dede15b7 100644 --- a/docs/protocols/release-surface-conformance.md +++ b/docs/protocols/release-surface-conformance.md @@ -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 diff --git a/package.json b/package.json index 1e89e3ccf..e087c76fb 100644 --- a/package.json +++ b/package.json @@ -1,299 +1,299 @@ { - "name": "@evalops/maestro", - "description": "Maestro by EvalOps - Deterministic coding agent with TUI/CLI and Web UI for AI-assisted development", - "version": "0.10.48", - "private": false, - "type": "module", - "workspaces": [ - "packages/*" - ], - "bin": { - "maestro": "dist/cli.js" - }, - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "files": [ - "dist", - "skills" - ], - "maestroRuntimeWorkspaces": [ - "@evalops/contracts", - "@evalops/tui" - ], - "scripts": { - "clean": "node ./scripts/clean-paths.js dist ./tmp/tsbuildinfo/composer.tsbuildinfo", - "prepare": "husky", - "postinstall": "node -e \"const fs=require('node:fs');const cp=require('node:child_process');if(!fs.existsSync('./scripts/ensure-deps.js')||!fs.existsSync('./packages/contracts/package.json'))process.exit(0);const r=cp.spawnSync(process.execPath,['./scripts/ensure-deps.js','--no-install'],{stdio:'inherit'});process.exit(r.status??1);\"", - "install:local": "node ./scripts/install-client.js", - "prebuild": "node ./scripts/ensure-deps.js && node ./scripts/session-wire-format-codegen.mjs && node ./scripts/headless-protocol-codegen.mjs && bun run generate:headless-proto:buf", - "build": "node ./scripts/ensure-dir.js ./tmp/tsbuildinfo && tsc -b tsconfig.build.json --force && bun build ./src/cli.ts --target node --packages external --external tree-sitter --external tree-sitter-bash --outfile dist/cli.js && node ./scripts/bundle-runtime-deps.mjs && node ./scripts/copy-themes.js && node ./scripts/copy-db-migrations.js", - "start": "node --enable-source-maps dist/cli.js", - "start:native": "MAESTRO_AGENT_SCRIPT=\"$(pwd)/dist/cli.js\" ./packages/tui-rs/target/release/maestro-tui", - "dev": "node ./scripts/headless-protocol-codegen.mjs && bun run generate:headless-proto:buf && node ./scripts/ensure-dir.js ./tmp/tsbuildinfo && tsc -b tsconfig.build.json --watch --preserveWatchOutput", - "dev:all": "concurrently --names \"cli,test\" --prefix-colors \"cyan,yellow\" \"npm run dev\" \"npm run test:watch\"", - "test:watch": "node ./scripts/run-vitest.js --watch", - "test:fast": "VITEST_FAST=1 node ./scripts/run-vitest.js --run", - "lint": "biome check . && npm run lint:evals", - "setup:worktree": "node scripts/setup-worktree.mjs", - "check:headless-proto:generated": "node scripts/check-headless-proto-generated.mjs", - "verify:headless-proto:sync": "node scripts/verify-headless-proto-sync.mjs", - "lint:headless-proto": "buf lint && bun run verify:headless-proto:sync && bun run check:headless-proto:generated", - "check:drift-surfaces": "node scripts/check-drift-prone-surfaces.mjs", - "check:staged-rollout": "node scripts/check-staged-rollout.mjs", - "check:context-manifest": "tsx scripts/check-context-manifest-contract.ts", - "check:session-wire-contract": "tsx scripts/check-session-wire-contract.ts", - "check:cli-runtime-conformance": "tsx scripts/check-cli-runtime-conformance.ts", - "check:rpc-protocol-conformance": "tsx scripts/check-rpc-protocol-conformance.ts", - "check:session-replay-fixtures": "tsx scripts/check-session-replay-fixtures.ts", - "check:agent-trajectory-fixtures": "tsx scripts/check-agent-trajectory-fixtures.ts", - "check:agent-trajectory-replay-fixtures": "tsx scripts/check-agent-trajectory-replay-fixtures.ts", - "check:agent-trajectory-score-fixtures": "tsx scripts/check-agent-trajectory-score-fixtures.ts", - "check:agent-trajectory-inspection-fixtures": "tsx scripts/check-agent-trajectory-inspection-fixtures.ts", - "check:agent-trajectory-scenario-fixtures": "tsx scripts/check-agent-trajectory-scenario-fixtures.ts", - "check:slack-teammate-runtime-scenarios": "tsx scripts/check-slack-teammate-runtime-scenarios.ts", - "check:scripted-scenario-fixtures": "tsx scripts/check-scripted-scenario-fixtures.ts", - "check:evidence-integrity": "tsx scripts/check-evidence-integrity.ts", - "check:maestro-release-gate-events": "tsx scripts/check-maestro-release-gate-events.ts", - "check:scenario-replay-gate": "node scripts/run-scenario-replay-gate.mjs", - "check:codex-parity": "node scripts/check-codex-parity-conformance.mjs", - "check:codex-operating-layer": "node scripts/check-codex-operating-layer-conformance.mjs", - "check:platform-runtime-conformance": "node scripts/check-platform-runtime-conformance.mjs", - "check:release-surface": "node scripts/check-release-surface-conformance.mjs", - "lint:evals": "bun run lint:headless-proto && node scripts/ensure-deps.js --no-install --workspace @evalops/contracts && node scripts/verify-evals.js && node scripts/verify-tool-versions.js && node scripts/validate-system-paths.js && node scripts/validate-package-boundaries.js && node scripts/validate-public-package-deps.js && node scripts/check-public-surface-boundary.mjs && npm run check:context-manifest && npm run check:session-wire-contract && npm run check:cli-runtime-conformance && npm run check:rpc-protocol-conformance && npm run check:evidence-integrity && npm run check:maestro-release-gate-events && npm run check:session-replay-fixtures && npm run check:agent-trajectory-fixtures && npm run check:agent-trajectory-replay-fixtures && npm run check:agent-trajectory-score-fixtures && npm run check:agent-trajectory-inspection-fixtures && npm run check:agent-trajectory-scenario-fixtures && npm run check:slack-teammate-runtime-scenarios && npm run check:scripted-scenario-fixtures && node scripts/session-wire-format-codegen.mjs --check && node scripts/headless-protocol-codegen.mjs --check && npm run check:app-server-schema && npm run check:drift-surfaces && npm run check:staged-rollout && npm run check:codex-parity && npm run check:codex-operating-layer && npm run check:platform-runtime-conformance && npm run check:release-surface && npm run developer-surface:check", - "platform:sdk-smoke": "tsx scripts/check-platform-sdk-contract.ts", - "platform:agentruntime-e2e": "tsx scripts/smoke-platform-agentruntime-lifecycle.ts", - "platform:timeline-e2e": "tsx scripts/smoke-platform-timeline-e2e.ts", - "platform:a2a-delegation-live": "tsx scripts/smoke-platform-a2a-delegation-live.ts", - "platform:a2a-evidence-verify": "tsx scripts/verify-platform-a2a-live-evidence.ts", - "developer-surface:check": "node scripts/check-developer-surface.mjs", - "format": "biome format .", - "check": "npm run lint && npm run check --workspaces --if-present && tsc -p tsconfig.build.json --noEmit", - "evals": "npm run build && node scripts/run-evals.js", - "evals:skill-package": "bunx tsx scripts/evals/run-skill-package-evals.ts", - "evals:pipeline-tool-integration": "bun run build && bunx tsx scripts/evals/run-pipeline-tool-integration-evals.ts", - "evals:shared-memory-integration": "bun run build && bunx tsx scripts/evals/run-shared-memory-integration-evals.ts", - "evals:platform-fermata-scenario-suite": "bun run build && bunx tsx scripts/evals/run-platform-fermata-scenario-suite.ts", - "evals:openrouter-live-smoke": "bun run build && bunx tsx scripts/evals/run-openrouter-live-smoke.ts", - "evals:openrouter-approvals-judge": "bun run build && bunx tsx scripts/evals/run-openrouter-approvals-judge-evals.ts", - "evals:openrouter-tool-surface-judge": "bun run build && bunx tsx scripts/evals/run-openrouter-tool-surface-judge-evals.ts", - "telemetry:report": "node scripts/telemetry-report.js", - "device-identity:harness": "MAESTRO_DEVICE_IDENTITY_ALLOW_TEST_HELPER=1 node ./scripts/run-vitest.js --run test/oauth-device-identity-harness.test.ts", - "generate-models": "bun scripts/generate-models.ts", - "generate:headless-protocol": "node scripts/headless-protocol-codegen.mjs", - "generate:app-server-schema": "tsx scripts/app-server-schema-codegen.ts", - "check:app-server-schema": "tsx scripts/app-server-schema-codegen.ts --check", - "generate:session-wire-format": "node scripts/session-wire-format-codegen.mjs", - "check:session-wire-format:generated": "node scripts/session-wire-format-codegen.mjs --check", - "generate:headless-proto:buf": "buf generate --template buf.gen.yaml && bunx biome check --write --unsafe packages/contracts/src/proto/maestro/v1/headless_pb.ts", - "test": "node ./scripts/run-vitest.js --run", - "test:coverage": "node ./scripts/run-vitest.js --run --coverage", - "prepublishOnly": "npm run clean && npm run build && npm run verify:runtime-deps", - "bun:install": "bun install", - "bun:cli": "bun run ./src/cli.ts", - "bun:watch": "bun run --watch ./src/cli.ts", - "web": "node dist/web-server.js", - "web:rust-control": "packages/control-plane-rs/target/release/maestro-control-plane", - "web:dev": "node ./scripts/ensure-deps.js --workspace @evalops/contracts && concurrently --names \"server,ui\" --prefix-colors \"blue,green\" \"tsx --watch src/web-server.ts\" \"bun run dev:web\"", - "web:dev:local": "MAESTRO_WEB_REQUIRE_KEY=0 MAESTRO_WEB_REQUIRE_REDIS=0 MAESTRO_WEB_ORIGIN=http://localhost:3000 npm run web:dev", - "bun:lint": "bunx biome check . && bun run lint:evals", - "bun:test": "node ./scripts/run-vitest.js --run", - "bun:test:fast": "VITEST_FAST=1 node ./scripts/run-vitest.js --run", - "bun:check": "bun run bun:lint && bunx tsc -p tsconfig.build.json --noEmit", - "bun:compile": "npm run build && bun build ./dist/cli.js --compile --external tree-sitter --external tree-sitter-bash --outfile dist/maestro-bun", - "bun:compile:bytecode": "npm run build && bun build ./dist/cli.js --compile --bytecode --external tree-sitter --external tree-sitter-bash --outfile dist/maestro-bun-bytecode", - "bun:evals": "bun run build && bun run ./scripts/run-evals.js", - "compile:binary": "npm run bun:compile && echo \"Binary ready at dist/maestro-bun\"", - "cli": "node ./dist/cli.js", - "verify-build": "bun scripts/verify-build.ts", - "verify-build:packages": "VERIFY_PACKAGES=1 bun scripts/verify-build.ts", - "release:check": "node scripts/release-readiness.js release", - "release:check:ci": "node scripts/release-readiness.js ci", - "ci:plan": "node scripts/plan-ci-checks.mjs", - "pr:ready": "node scripts/pr-ready-to-merge.mjs", - "pr:feedback": "node scripts/pr-feedback-audit.mjs", - "verify:runtime-deps": "node scripts/check-runtime-deps.js && node scripts/check-docker-runtime-workspaces.mjs && node scripts/check-packed-bundled-workspaces.mjs", - "tui": "npm run cli", - "verify": "npm run format && npm run lint && npm run test && npm run build && npm run smoke && npm run telemetry:report", - "smoke": "node scripts/smoke-cli.js", - "smoke:local-e2e": "node scripts/smoke-cli.js", - "smoke:codex-app-server-live": "node scripts/smoke-codex-app-server-live.mjs", - "smoke:fathom-cua-mcp": "tsx scripts/smoke-fathom-cua-mcp.ts", - "smoke:event-bus": "tsx scripts/smoke-maestro-event-bus.ts", - "smoke:a2a-local": "tsx scripts/smoke-maestro-a2a-local.ts", - "smoke:a2a-local-swarm": "tsx scripts/smoke-maestro-a2a-local-swarm.ts", - "smoke:a2a-input-required": "tsx scripts/smoke-maestro-a2a-input-required.ts", - "smoke:a2a-tmux": "bash scripts/smoke-maestro-a2a-tmux.sh", - "a2a": "tsx src/cli.ts a2a", - "a2a:codex-bridge": "python3 scripts/codex-a2a-bridge.py", - "a2a:peer": "tsx src/cli.ts a2a", - "smoke:headless": "node scripts/smoke-headless.js", - "smoke:exec-replay-e2e": "node scripts/smoke-exec-replay-e2e.js", - "headless:responsiveness": "node scripts/headless-responsiveness-harness.js", - "smoke:pack": "node scripts/smoke-packed-cli.js", - "metadata:sync": "node scripts/sync-package-metadata.js", - "metadata:check": "node scripts/sync-package-metadata.js --check", - "cutover:check": "node scripts/check-package-cutover-readiness.js", - "factory:import": "npm run build && node dist/scripts/import-factory-config.js", - "factory:export": "npm run build && node dist/scripts/export-factory-config.js", - "version:patch": "node scripts/version.js patch", - "version:minor": "node scripts/version.js minor", - "version:major": "node scripts/version.js major", - "version:sync": "node scripts/sync-versions.js", - "openapi:generate": "bun scripts/generate-openapi.ts", - "openapi:check": "bun scripts/generate-openapi.ts --check", - "openapi:serve": "bun scripts/serve-openapi.ts", - "nix:update-hash": "bash scripts/update-nix-hash.sh", - "dev:web": "bun run --filter @evalops/maestro-web dev", - "dev:tui": "bun run --filter @evalops/tui dev", - "dev:packages": "concurrently --names \"tui,web\" --prefix-colors \"magenta,green\" \"bun run dev:tui\" \"bun run dev:web\"", - "guardian": "bash scripts/guardian.sh", - "guardian:install-hook": "node scripts/install-guardian-hook.js", - "build:all": "bun run --filter @evalops/contracts build && bun run --filter @evalops/consumer build && bun run --filter @evalops/tui build && bun run --filter @evalops/maestro-web build && bun run build && bun run --filter @evalops/ai build", - "test:all": "npm run test && npm run test --workspaces --if-present", - "db:generate": "MAESTRO_DATABASE_TYPE=postgres drizzle-kit generate", - "db:migrate": "bun run src/db/migrate.ts", - "db:migrate:status": "bun run -e \"import('./src/db/migrate.js').then(m => m.getMigrationStatus()).then(console.log)\"", - "db:studio": "drizzle-kit studio", - "db:seed": "bun run src/db/seed.ts", - "db:check": "bun run src/db/check.ts", - "vscode:build": "npx nx run vscode-extension:build", - "vscode:package": "npx nx run vscode-extension:package", - "vscode:publish": "npx nx run vscode-extension:publish", - "tui-rs:build": "cd packages/tui-rs && cargo build --release", - "control-plane-rs:build": "cd packages/control-plane-rs && cargo build --release --bin maestro-control-plane", - "control-plane-rs:check": "cd packages/control-plane-rs && cargo check --bin maestro-control-plane", - "rust:harness": "bash scripts/rust-local-harness.sh", - "tui-rs:build:debug": "cd packages/tui-rs && cargo build", - "tui-rs:check": "cd packages/tui-rs && cargo check", - "tui-rs:test": "cd packages/tui-rs && cargo test", - "release:verify:published": "node scripts/smoke-registry-install.js", - "release:verify:published:e2e": "node scripts/smoke-published-replay-e2e.js", - "release:verify:published:evidence": "node scripts/verify-published-replay-evidence.js", - "release:deprecate": "node scripts/deprecate-release.js" - }, - "dependencies": { - "@aws-sdk/client-bedrock-runtime": "^3.1020.0", - "@bufbuild/protobuf": "^2.11.0", - "@crosscopy/clipboard": "^0.2.8", - "@modelcontextprotocol/sdk": "^1.29.0", - "@openai/codex": "^0.135.0", - "@opentelemetry/api": "^1.9.1", - "@opentelemetry/auto-instrumentations-node": "^0.76.0", - "@opentelemetry/resources": "^2.7.1", - "@opentelemetry/sdk-node": "0.218.0", - "@opentelemetry/semantic-conventions": "^1.41.1", - "@sentry/node": "^10.53.1", - "@sinclair/typebox": "^0.34.49", - "ajv": "^8.18.0", - "ajv-formats": "^3.0.1", - "bcrypt": "^6.0.0", - "chalk": "^5.6.2", - "clipboardy": "^4.0.0", - "diff": "^8.0.4", - "dotenv": "^16.6.1", - "drizzle-orm": "0.45.2", - "exceljs": "^4.4.0", - "fflate": "^0.8.2", - "glob": "^13.0.6", - "ioredis": "^5.10.1", - "jiti": "^2.6.1", - "jose": "^6.2.2", - "js-yaml": "^4.1.1", - "jsonc-parser": "^3.3.1", - "jsonwebtoken": "^9.0.3", - "jszip": "^3.10.1", - "luxon": "^3.7.2", - "mammoth": "^1.12.0", - "marked": "^17.0.5", - "mime-types": "^3.0.2", - "minimatch": "^10.2.5", - "nats": "^2.29.3", - "openai": "^6.33.0", - "otplib": "^13.4.0", - "partial-json": "^0.1.7", - "pdf-parse": "^2.4.5", - "postgres": "^3.4.8", - "smol-toml": "^1.6.1", - "string-width": "^8.2.0", - "uuid": "^14.0.0", - "vscode-jsonrpc": "^8.2.1", - "ws": "^8.20.0", - "yaml": "^2.8.3", - "zod": "^4.3.6", - "zod-validation-error": "^5.0.0" - }, - "devDependencies": { - "@bufbuild/buf": "^1.67.0", - "@bufbuild/protoc-gen-es": "2.12.0", - "@biomejs/biome": "^1.9.4", - "@google/genai": "^1.50.1", - "@smithy/types": "^4.13.1", - "@types/bcrypt": "^6.0.0", - "@types/diff": "^7.0.2", - "@types/js-yaml": "^4.0.9", - "@types/jsonwebtoken": "^9.0.10", - "@types/luxon": "^3.7.1", - "@types/mime-types": "^3.0.1", - "@types/node": "^24.12.0", - "@types/pdf-parse": "^1.1.5", - "@types/uuid": "^11.0.0", - "@vitest/coverage-v8": "^4.1.2", - "concurrently": "^9.2.1", - "drizzle-kit": "1.0.0-beta.21", - "esbuild": "^0.27.4", - "fast-check": "^4.6.0", - "google-auth-library": "^10.6.2", - "husky": "^9.1.7", - "nx": "22.6.5", - "tsx": "^4.21.0", - "typescript": "^5.9.3", - "vitest": "^4.1.2" - }, - "keywords": [ - "maestro", - "evalops", - "ai", - "llm", - "cli", - "tui", - "agent" - ], - "author": "EvalOps", - "license": "BUSL-1.1", - "maestro": { - "canonicalPackageName": "@evalops/maestro", - "packageAliases": [ - "@evalops/maestro", - "@evalops-jh/maestro" - ] - }, - "repository": { - "type": "git", - "url": "git+https://github.com/evalops/maestro.git" - }, - "engines": { - "node": ">=20.0.0", - "bun": ">=1.1.0" - }, - "overrides": { - "jws": ">=4.0.1", - "rollup": ">=4.59.0", - "koa": ">=2.16.4", - "axios": ">=1.15.0", - "follow-redirects": ">=1.16.0", - "@isaacs/brace-expansion": ">=5.0.1", - "picomatch": ">=4.0.4", - "qs": ">=6.14.2" - }, - "optionalDependencies": { - "sharp": "0.34.5", - "tree-sitter": "^0.25.0", - "tree-sitter-bash": "^0.25.1" - }, - "packageManager": "bun@1.3.6", - "trustedDependencies": [ - "electron", - "tree-sitter", - "tree-sitter-bash" - ] + "name": "@evalops/maestro", + "description": "Maestro by EvalOps - Deterministic coding agent with TUI/CLI and Web UI for AI-assisted development", + "version": "0.10.48", + "private": false, + "type": "module", + "workspaces": [ + "packages/*" + ], + "bin": { + "maestro": "dist/cli.js" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "skills" + ], + "maestroRuntimeWorkspaces": [ + "@evalops/contracts", + "@evalops/tui" + ], + "scripts": { + "clean": "node ./scripts/clean-paths.js dist ./tmp/tsbuildinfo/composer.tsbuildinfo", + "prepare": "husky", + "postinstall": "node -e \"const fs=require('node:fs');const cp=require('node:child_process');if(!fs.existsSync('./scripts/ensure-deps.js')||!fs.existsSync('./packages/contracts/package.json'))process.exit(0);const r=cp.spawnSync(process.execPath,['./scripts/ensure-deps.js','--no-install'],{stdio:'inherit'});process.exit(r.status??1);\"", + "install:local": "node ./scripts/install-client.js", + "prebuild": "node ./scripts/ensure-deps.js && node ./scripts/session-wire-format-codegen.mjs && node ./scripts/headless-protocol-codegen.mjs && bun run generate:headless-proto:buf", + "build": "node ./scripts/ensure-dir.js ./tmp/tsbuildinfo && tsc -b tsconfig.build.json --force && bun build ./src/cli.ts --target node --packages external --external tree-sitter --external tree-sitter-bash --outfile dist/cli.js && node ./scripts/bundle-runtime-deps.mjs && node ./scripts/copy-themes.js && node ./scripts/copy-db-migrations.js", + "start": "node --enable-source-maps dist/cli.js", + "start:native": "MAESTRO_AGENT_SCRIPT=\"$(pwd)/dist/cli.js\" ./packages/tui-rs/target/release/maestro-tui", + "dev": "node ./scripts/headless-protocol-codegen.mjs && bun run generate:headless-proto:buf && node ./scripts/ensure-dir.js ./tmp/tsbuildinfo && tsc -b tsconfig.build.json --watch --preserveWatchOutput", + "dev:all": "concurrently --names \"cli,test\" --prefix-colors \"cyan,yellow\" \"npm run dev\" \"npm run test:watch\"", + "test:watch": "node ./scripts/run-vitest.js --watch", + "test:fast": "VITEST_FAST=1 node ./scripts/run-vitest.js --run", + "lint": "biome check . && npm run lint:evals", + "setup:worktree": "node scripts/setup-worktree.mjs", + "check:headless-proto:generated": "node scripts/check-headless-proto-generated.mjs", + "verify:headless-proto:sync": "node scripts/verify-headless-proto-sync.mjs", + "lint:headless-proto": "buf lint && bun run verify:headless-proto:sync && bun run check:headless-proto:generated", + "check:drift-surfaces": "node scripts/check-drift-prone-surfaces.mjs", + "check:staged-rollout": "node scripts/check-staged-rollout.mjs", + "check:context-manifest": "tsx scripts/check-context-manifest-contract.ts", + "check:session-wire-contract": "tsx scripts/check-session-wire-contract.ts", + "check:cli-runtime-conformance": "tsx scripts/check-cli-runtime-conformance.ts", + "check:rpc-protocol-conformance": "tsx scripts/check-rpc-protocol-conformance.ts", + "check:session-replay-fixtures": "tsx scripts/check-session-replay-fixtures.ts", + "check:agent-trajectory-fixtures": "tsx scripts/check-agent-trajectory-fixtures.ts", + "check:agent-trajectory-replay-fixtures": "tsx scripts/check-agent-trajectory-replay-fixtures.ts", + "check:agent-trajectory-score-fixtures": "tsx scripts/check-agent-trajectory-score-fixtures.ts", + "check:agent-trajectory-inspection-fixtures": "tsx scripts/check-agent-trajectory-inspection-fixtures.ts", + "check:agent-trajectory-scenario-fixtures": "tsx scripts/check-agent-trajectory-scenario-fixtures.ts", + "check:slack-teammate-runtime-scenarios": "tsx scripts/check-slack-teammate-runtime-scenarios.ts", + "check:scripted-scenario-fixtures": "tsx scripts/check-scripted-scenario-fixtures.ts", + "check:evidence-integrity": "tsx scripts/check-evidence-integrity.ts", + "check:maestro-release-gate-events": "tsx scripts/check-maestro-release-gate-events.ts", + "check:scenario-replay-gate": "node scripts/run-scenario-replay-gate.mjs", + "check:codex-parity": "node scripts/check-codex-parity-conformance.mjs", + "check:codex-operating-layer": "node scripts/check-codex-operating-layer-conformance.mjs", + "check:platform-runtime-conformance": "node scripts/check-platform-runtime-conformance.mjs", + "check:release-surface": "node scripts/check-release-surface-conformance.mjs", + "lint:evals": "bun run lint:headless-proto && node scripts/ensure-deps.js --no-install --workspace @evalops/contracts && node scripts/verify-evals.js && node scripts/verify-tool-versions.js && node scripts/validate-system-paths.js && node scripts/validate-package-boundaries.js && node scripts/validate-public-package-deps.js && node scripts/check-public-surface-boundary.mjs && npm run check:context-manifest && npm run check:session-wire-contract && npm run check:cli-runtime-conformance && npm run check:rpc-protocol-conformance && npm run check:evidence-integrity && npm run check:maestro-release-gate-events && npm run check:session-replay-fixtures && npm run check:agent-trajectory-fixtures && npm run check:agent-trajectory-replay-fixtures && npm run check:agent-trajectory-score-fixtures && npm run check:agent-trajectory-inspection-fixtures && npm run check:agent-trajectory-scenario-fixtures && npm run check:slack-teammate-runtime-scenarios && npm run check:scripted-scenario-fixtures && node scripts/session-wire-format-codegen.mjs --check && node scripts/headless-protocol-codegen.mjs --check && npm run check:app-server-schema && npm run check:drift-surfaces && npm run check:staged-rollout && npm run check:codex-parity && npm run check:codex-operating-layer && npm run check:platform-runtime-conformance && npm run check:release-surface && npm run developer-surface:check", + "platform:sdk-smoke": "tsx scripts/check-platform-sdk-contract.ts", + "platform:agentruntime-e2e": "tsx scripts/smoke-platform-agentruntime-lifecycle.ts", + "platform:timeline-e2e": "tsx scripts/smoke-platform-timeline-e2e.ts", + "platform:a2a-delegation-live": "tsx scripts/smoke-platform-a2a-delegation-live.ts", + "platform:a2a-evidence-verify": "tsx scripts/verify-platform-a2a-live-evidence.ts", + "developer-surface:check": "node scripts/check-developer-surface.mjs", + "format": "biome format .", + "check": "npm run lint && npm run check --workspaces --if-present && tsc -p tsconfig.build.json --noEmit", + "evals": "npm run build && node scripts/run-evals.js", + "evals:skill-package": "bunx tsx scripts/evals/run-skill-package-evals.ts", + "evals:pipeline-tool-integration": "bun run build && bunx tsx scripts/evals/run-pipeline-tool-integration-evals.ts", + "evals:shared-memory-integration": "bun run build && bunx tsx scripts/evals/run-shared-memory-integration-evals.ts", + "evals:platform-fermata-scenario-suite": "bun run build && bunx tsx scripts/evals/run-platform-fermata-scenario-suite.ts", + "evals:openrouter-live-smoke": "bun run build && bunx tsx scripts/evals/run-openrouter-live-smoke.ts", + "evals:openrouter-approvals-judge": "bun run build && bunx tsx scripts/evals/run-openrouter-approvals-judge-evals.ts", + "evals:openrouter-tool-surface-judge": "bun run build && bunx tsx scripts/evals/run-openrouter-tool-surface-judge-evals.ts", + "telemetry:report": "node scripts/telemetry-report.js", + "device-identity:harness": "MAESTRO_DEVICE_IDENTITY_ALLOW_TEST_HELPER=1 node ./scripts/run-vitest.js --run test/oauth-device-identity-harness.test.ts", + "generate-models": "bun scripts/generate-models.ts", + "generate:headless-protocol": "node scripts/headless-protocol-codegen.mjs", + "generate:app-server-schema": "tsx scripts/app-server-schema-codegen.ts", + "check:app-server-schema": "tsx scripts/app-server-schema-codegen.ts --check", + "generate:session-wire-format": "node scripts/session-wire-format-codegen.mjs", + "check:session-wire-format:generated": "node scripts/session-wire-format-codegen.mjs --check", + "generate:headless-proto:buf": "buf generate --template buf.gen.yaml && bunx biome check --write --unsafe packages/contracts/src/proto/maestro/v1/headless_pb.ts", + "test": "node ./scripts/run-vitest.js --run", + "test:coverage": "node ./scripts/run-vitest.js --run --coverage", + "prepublishOnly": "npm run clean && npm run build && npm run verify:runtime-deps", + "bun:install": "bun install", + "bun:cli": "bun run ./src/cli.ts", + "bun:watch": "bun run --watch ./src/cli.ts", + "web": "node dist/web-server.js", + "web:rust-control": "packages/control-plane-rs/target/release/maestro-control-plane", + "web:dev": "node ./scripts/ensure-deps.js --workspace @evalops/contracts && concurrently --names \"server,ui\" --prefix-colors \"blue,green\" \"tsx --watch src/web-server.ts\" \"bun run dev:web\"", + "web:dev:local": "MAESTRO_WEB_REQUIRE_KEY=0 MAESTRO_WEB_REQUIRE_REDIS=0 MAESTRO_WEB_ORIGIN=http://localhost:3000 npm run web:dev", + "bun:lint": "bunx biome check . && bun run lint:evals", + "bun:test": "node ./scripts/run-vitest.js --run", + "bun:test:fast": "VITEST_FAST=1 node ./scripts/run-vitest.js --run", + "bun:check": "bun run bun:lint && bunx tsc -p tsconfig.build.json --noEmit", + "bun:compile": "npm run build && bun build ./dist/cli.js --compile --external tree-sitter --external tree-sitter-bash --outfile dist/maestro-bun", + "bun:compile:bytecode": "npm run build && bun build ./dist/cli.js --compile --bytecode --external tree-sitter --external tree-sitter-bash --outfile dist/maestro-bun-bytecode", + "bun:evals": "bun run build && bun run ./scripts/run-evals.js", + "compile:binary": "npm run bun:compile && echo \"Binary ready at dist/maestro-bun\"", + "cli": "node ./dist/cli.js", + "verify-build": "bun scripts/verify-build.ts", + "verify-build:packages": "VERIFY_PACKAGES=1 bun scripts/verify-build.ts", + "release:check": "node scripts/release-readiness.js release", + "release:check:ci": "node scripts/release-readiness.js ci", + "ci:plan": "node scripts/plan-ci-checks.mjs", + "pr:ready": "node scripts/pr-ready-to-merge.mjs", + "pr:feedback": "node scripts/pr-feedback-audit.mjs", + "verify:runtime-deps": "node scripts/check-runtime-deps.js && node scripts/check-docker-runtime-workspaces.mjs && node scripts/check-packed-bundled-workspaces.mjs", + "tui": "npm run cli", + "verify": "npm run format && npm run lint && npm run test && npm run build && npm run smoke && npm run telemetry:report", + "smoke": "node scripts/smoke-cli.js", + "smoke:local-e2e": "node scripts/smoke-cli.js", + "smoke:codex-app-server-live": "node scripts/smoke-codex-app-server-live.mjs", + "smoke:fathom-cua-mcp": "tsx scripts/smoke-fathom-cua-mcp.ts", + "smoke:event-bus": "tsx scripts/smoke-maestro-event-bus.ts", + "smoke:a2a-local": "tsx scripts/smoke-maestro-a2a-local.ts", + "smoke:a2a-local-swarm": "tsx scripts/smoke-maestro-a2a-local-swarm.ts", + "smoke:a2a-input-required": "tsx scripts/smoke-maestro-a2a-input-required.ts", + "smoke:a2a-tmux": "bash scripts/smoke-maestro-a2a-tmux.sh", + "a2a": "tsx src/cli.ts a2a", + "a2a:codex-bridge": "python3 scripts/codex-a2a-bridge.py", + "a2a:peer": "tsx src/cli.ts a2a", + "smoke:headless": "node scripts/smoke-headless.js", + "smoke:exec-replay-e2e": "node scripts/smoke-exec-replay-e2e.js", + "headless:responsiveness": "node scripts/headless-responsiveness-harness.js", + "smoke:pack": "node scripts/smoke-packed-cli.js", + "metadata:sync": "node scripts/sync-package-metadata.js", + "metadata:check": "node scripts/sync-package-metadata.js --check", + "cutover:check": "node scripts/check-package-cutover-readiness.js", + "factory:import": "npm run build && node dist/scripts/import-factory-config.js", + "factory:export": "npm run build && node dist/scripts/export-factory-config.js", + "version:patch": "node scripts/version.js patch", + "version:minor": "node scripts/version.js minor", + "version:major": "node scripts/version.js major", + "version:sync": "node scripts/sync-versions.js", + "openapi:generate": "bun scripts/generate-openapi.ts", + "openapi:check": "bun scripts/generate-openapi.ts --check", + "openapi:serve": "bun scripts/serve-openapi.ts", + "nix:update-hash": "bash scripts/update-nix-hash.sh", + "dev:web": "bun run --filter @evalops/maestro-web dev", + "dev:tui": "bun run --filter @evalops/tui dev", + "dev:packages": "concurrently --names \"tui,web\" --prefix-colors \"magenta,green\" \"bun run dev:tui\" \"bun run dev:web\"", + "guardian": "bash scripts/guardian.sh", + "guardian:install-hook": "node scripts/install-guardian-hook.js", + "build:all": "bun run --filter @evalops/contracts build && bun run --filter @evalops/consumer build && bun run --filter @evalops/tui build && bun run --filter @evalops/maestro-web build && bun run build && bun run --filter @evalops/ai build", + "test:all": "npm run test && npm run test --workspaces --if-present", + "db:generate": "MAESTRO_DATABASE_TYPE=postgres drizzle-kit generate", + "db:migrate": "bun run src/db/migrate.ts", + "db:migrate:status": "bun run -e \"import('./src/db/migrate.js').then(m => m.getMigrationStatus()).then(console.log)\"", + "db:studio": "drizzle-kit studio", + "db:seed": "bun run src/db/seed.ts", + "db:check": "bun run src/db/check.ts", + "vscode:build": "npx nx run vscode-extension:build", + "vscode:package": "npx nx run vscode-extension:package", + "vscode:publish": "npx nx run vscode-extension:publish", + "tui-rs:build": "cd packages/tui-rs && cargo build --release", + "control-plane-rs:build": "cd packages/control-plane-rs && cargo build --release --bin maestro-control-plane", + "control-plane-rs:check": "cd packages/control-plane-rs && cargo check --bin maestro-control-plane", + "rust:harness": "bash scripts/rust-local-harness.sh", + "tui-rs:build:debug": "cd packages/tui-rs && cargo build", + "tui-rs:check": "cd packages/tui-rs && cargo check", + "tui-rs:test": "cd packages/tui-rs && cargo test", + "release:verify:published": "node scripts/smoke-registry-install.js", + "release:verify:published:e2e": "node scripts/smoke-published-replay-e2e.js", + "release:verify:published:evidence": "node scripts/verify-published-replay-evidence.js", + "release:deprecate": "node scripts/deprecate-release.js" + }, + "dependencies": { + "@aws-sdk/client-bedrock-runtime": "^3.1020.0", + "@bufbuild/protobuf": "^2.11.0", + "@crosscopy/clipboard": "^0.2.8", + "@modelcontextprotocol/sdk": "^1.29.0", + "@openai/codex": "^0.135.0", + "@opentelemetry/api": "^1.9.1", + "@opentelemetry/auto-instrumentations-node": "^0.76.0", + "@opentelemetry/resources": "^2.7.1", + "@opentelemetry/sdk-node": "0.218.0", + "@opentelemetry/semantic-conventions": "^1.41.1", + "@sentry/node": "^10.53.1", + "@sinclair/typebox": "^0.34.49", + "ajv": "^8.18.0", + "ajv-formats": "^3.0.1", + "bcrypt": "^6.0.0", + "chalk": "^5.6.2", + "clipboardy": "^4.0.0", + "diff": "^8.0.4", + "dotenv": "^16.6.1", + "drizzle-orm": "0.45.2", + "exceljs": "^4.4.0", + "fflate": "^0.8.2", + "glob": "^13.0.6", + "ioredis": "^5.10.1", + "jiti": "^2.6.1", + "jose": "^6.2.2", + "js-yaml": "^4.1.1", + "jsonc-parser": "^3.3.1", + "jsonwebtoken": "^9.0.3", + "jszip": "^3.10.1", + "luxon": "^3.7.2", + "mammoth": "^1.12.0", + "marked": "^17.0.5", + "mime-types": "^3.0.2", + "minimatch": "^10.2.5", + "nats": "^2.29.3", + "openai": "^6.33.0", + "otplib": "^13.4.0", + "partial-json": "^0.1.7", + "pdf-parse": "^2.4.5", + "postgres": "^3.4.8", + "smol-toml": "^1.6.1", + "string-width": "^8.2.0", + "uuid": "^14.0.0", + "vscode-jsonrpc": "^8.2.1", + "ws": "^8.20.0", + "yaml": "^2.8.3", + "zod": "^4.3.6", + "zod-validation-error": "^5.0.0" + }, + "devDependencies": { + "@bufbuild/buf": "^1.67.0", + "@bufbuild/protoc-gen-es": "2.12.0", + "@biomejs/biome": "^1.9.4", + "@google/genai": "^1.50.1", + "@smithy/types": "^4.13.1", + "@types/bcrypt": "^6.0.0", + "@types/diff": "^7.0.2", + "@types/js-yaml": "^4.0.9", + "@types/jsonwebtoken": "^9.0.10", + "@types/luxon": "^3.7.1", + "@types/mime-types": "^3.0.1", + "@types/node": "^24.12.0", + "@types/pdf-parse": "^1.1.5", + "@types/uuid": "^11.0.0", + "@vitest/coverage-v8": "^4.1.2", + "concurrently": "^9.2.1", + "drizzle-kit": "1.0.0-beta.21", + "esbuild": "^0.27.4", + "fast-check": "^4.6.0", + "google-auth-library": "^10.6.2", + "husky": "^9.1.7", + "nx": "22.6.5", + "tsx": "^4.21.0", + "typescript": "^5.9.3", + "vitest": "^4.1.2" + }, + "keywords": [ + "maestro", + "evalops", + "ai", + "llm", + "cli", + "tui", + "agent" + ], + "author": "EvalOps", + "license": "BUSL-1.1", + "maestro": { + "canonicalPackageName": "@evalops/maestro", + "packageAliases": [ + "@evalops/maestro", + "@evalops-jh/maestro" + ] + }, + "repository": { + "type": "git", + "url": "git+https://github.com/evalops/maestro.git" + }, + "engines": { + "node": ">=20.0.0", + "bun": ">=1.1.0" + }, + "overrides": { + "jws": ">=4.0.1", + "rollup": ">=4.59.0", + "koa": ">=2.16.4", + "axios": ">=1.15.0", + "follow-redirects": ">=1.16.0", + "@isaacs/brace-expansion": ">=5.0.1", + "picomatch": ">=4.0.4", + "qs": ">=6.14.2" + }, + "optionalDependencies": { + "sharp": "0.34.5", + "tree-sitter": "^0.25.0", + "tree-sitter-bash": "^0.25.1" + }, + "packageManager": "bun@1.3.6", + "trustedDependencies": [ + "electron", + "tree-sitter", + "tree-sitter-bash" + ] } diff --git a/scripts/check-release-surface-conformance.mjs b/scripts/check-release-surface-conformance.mjs index 1dbd0b561..25d9a17e0 100644 --- a/scripts/check-release-surface-conformance.mjs +++ b/scripts/check-release-surface-conformance.mjs @@ -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", @@ -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, ) { @@ -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; diff --git a/scripts/plan-ci-checks.mjs b/scripts/plan-ci-checks.mjs index ab8b34fb2..b48a50e1d 100755 --- a/scripts/plan-ci-checks.mjs +++ b/scripts/plan-ci-checks.mjs @@ -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); @@ -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), diff --git a/test/scripts/ci-guardrails.test.ts b/test/scripts/ci-guardrails.test.ts index a86714566..2aba90168 100644 --- a/test/scripts/ci-guardrails.test.ts +++ b/test/scripts/ci-guardrails.test.ts @@ -174,7 +174,7 @@ describe("planCiChecks", () => { coverage: false, lightPrChecks: true, prChecks: true, - publicMirror: false, + publicMirror: true, rustHostedConformance: false, }); expect( @@ -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({ @@ -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", @@ -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(); @@ -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( diff --git a/test/scripts/release-surface-conformance.test.ts b/test/scripts/release-surface-conformance.test.ts index fa4ce217e..5fd0dfc31 100644 --- a/test/scripts/release-surface-conformance.test.ts +++ b/test/scripts/release-surface-conformance.test.ts @@ -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(),