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
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ fail-closed and only pauses when the agent actually proposed a reviewed output.
│ ├── approval-summary/ # Safe-outputs summary renderer (bundled to approval-summary.js; end-of-Agent-job summary tab)
│ ├── github-app-token/ # GitHub App token minter (bundled to github-app-token.js; mints installation token in Agent + Detection when engine.github-app-token is set)
│ ├── executor-e2e/ # Stage 3 safe-output E2E test harness (not a bundle; runs deterministic scenarios against a real ADO project and files a GitHub issue on failure)
│ ├── compiler-smoke-e2e/ # Deterministic compiler-candidate smoke E2E orchestrator (not a bundle): stages a compiler candidate, pushes to a short-lived `ado-aw-mirror` branch, queues the five FIXED "candidate lane" pipeline definitions, and asserts they go green. Consumes fixtures from `tests/compiler-smoke-e2e/`; built to `test-bin/` by `build:compiler-smoke-e2e`, listed in `NON_BUNDLE_DIRS`.
│ ├── compiler-smoke-e2e/ # Deterministic compiler-candidate smoke E2E orchestrator (not a bundle): stages a compiler candidate, pushes to a short-lived `ado-aw-mirror` branch, queues the four FIXED "candidate lane" pipeline definitions, and asserts they go green. Consumes fixtures from `tests/compiler-smoke-e2e/`; built to `test-bin/` by `build:compiler-smoke-e2e`, listed in `NON_BUNDLE_DIRS`.
│ ├── prepare-pr-base/ # create-pull-request preparer (bundled to prepare-pr-base.js): Agent mode uses ADO diff metadata + bounded dual-ref fallback to make the merge-base reachable; SafeOutputs mode fetches only the target worktree tip
│ ├── trigger-e2e/ # Test-only gate-spec / trigger-evaluation harness (not a bundle): mirrors Rust `Fact::ALL` in `gate-spec.ts`; `fact-catalog.gen.json` is generated by `export-fact-catalog` and drift-guarded by CI
│ └── shared/ # Shared modules across bundles (auth, ado-client, env-facts, types.gen.ts)
Expand Down Expand Up @@ -512,7 +512,7 @@ not regenerate them with `cargo run -- compile` from an unreleased checkout:
their runtime integrity step downloads the released compiler, so development
output can drift even while Cargo still reports the same semver. Compiler PRs
and nightly `main` are exercised by `tests/compiler-smoke-e2e/`, which
recompiles all five workflows in a temporary worktree and stages them on an
recompiles four selected workflows in a temporary worktree and stages them on an
ephemeral `ado-aw-mirror` ref. The release workflow updates the checked-in
locks only after matching release assets exist.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ function baseEnv(overrides: Record<string, string | undefined> = {}): NodeJS.Pro
COMPILER_SMOKE_CANARY_DEFINITION_ID: "2601",
COMPILER_SMOKE_AZURE_CLI_DEFINITION_ID: "2602",
COMPILER_SMOKE_NOOP_TARGET_DEFINITION_ID: "2603",
COMPILER_SMOKE_JANITOR_DEFINITION_ID: "2604",
COMPILER_SMOKE_REPORTER_DEFINITION_ID: "2605",
...overrides,
};
Expand All @@ -35,7 +34,6 @@ describe("loadConfig", () => {
canary: 2601,
"azure-cli": 2602,
"noop-target": 2603,
janitor: 2604,
"smoke-failure-reporter": 2605,
});
expect(config.concurrency).toBe(5);
Expand All @@ -59,7 +57,6 @@ describe("loadConfig", () => {
"COMPILER_SMOKE_CANARY_DEFINITION_ID",
"COMPILER_SMOKE_AZURE_CLI_DEFINITION_ID",
"COMPILER_SMOKE_NOOP_TARGET_DEFINITION_ID",
"COMPILER_SMOKE_JANITOR_DEFINITION_ID",
"COMPILER_SMOKE_REPORTER_DEFINITION_ID",
]) {
it(`rejects a missing ${name}`, () => {
Expand All @@ -84,7 +81,7 @@ describe("loadConfig", () => {
});

it("rejects a non-integer fixture definition id", () => {
expect(() => loadConfig(baseEnv({ COMPILER_SMOKE_JANITOR_DEFINITION_ID: "12.5" }))).toThrow(
expect(() => loadConfig(baseEnv({ COMPILER_SMOKE_REPORTER_DEFINITION_ID: "12.5" }))).toThrow(
/positive integer/,
);
});
Expand All @@ -104,11 +101,10 @@ describe("loadConfig", () => {
loadConfig(
baseEnv({
COMPILER_SMOKE_AZURE_CLI_DEFINITION_ID: "2601",
COMPILER_SMOKE_NOOP_TARGET_DEFINITION_ID: "2604",
COMPILER_SMOKE_JANITOR_DEFINITION_ID: "2604",
COMPILER_SMOKE_REPORTER_DEFINITION_ID: "2603",
}),
),
).toThrow(/canary/);
).toThrow(/2601 used by \[canary, azure-cli\].*2603 used by \[noop-target, smoke-failure-reporter\]/);
});

describe("COMPILER_SMOKE_CONCURRENCY bounds", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ describe("fixturePaths", () => {
});

describe("ALL_FIXTURES", () => {
it("has exactly the five fixtures in the required stable order", () => {
it("has exactly the four fixtures in the required stable order", () => {
expect(ALL_FIXTURES.map((f) => f.name)).toEqual([
"canary",
"azure-cli",
"noop-target",
"janitor",
"smoke-failure-reporter",
]);
});
Expand All @@ -32,9 +31,9 @@ describe("ALL_FIXTURES", () => {
});

describe("allowedChangedPaths", () => {
it("contains exactly the five md files, five lock files, and .gitattributes", () => {
it("contains exactly the four md files, four lock files, and .gitattributes", () => {
const allowed = allowedChangedPaths();
expect(allowed.size).toBe(11);
expect(allowed.size).toBe(9);
expect(allowed.has(".gitattributes")).toBe(true);
for (const f of ALL_FIXTURES) {
expect(allowed.has(f.relMd)).toBe(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const baseEnv = {
COMPILER_SMOKE_CANARY_DEFINITION_ID: "3001",
COMPILER_SMOKE_AZURE_CLI_DEFINITION_ID: "3002",
COMPILER_SMOKE_NOOP_TARGET_DEFINITION_ID: "3003",
COMPILER_SMOKE_JANITOR_DEFINITION_ID: "3004",
COMPILER_SMOKE_REPORTER_DEFINITION_ID: "3005",
COMPILER_SMOKE_CHILD_TIMEOUT_MS: "5000",
COMPILER_SMOKE_POLL_MS: "1",
Expand Down Expand Up @@ -79,8 +78,6 @@ vi.mock("../git.js", async (importOriginal) => {
"tests/safe-outputs/azure-cli.lock.yml",
"tests/safe-outputs/noop-target.md",
"tests/safe-outputs/noop-target.lock.yml",
"tests/safe-outputs/janitor.md",
"tests/safe-outputs/janitor.lock.yml",
"tests/safe-outputs/smoke-failure-reporter.md",
"tests/safe-outputs/smoke-failure-reporter.lock.yml",
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ describe("renderResultsTable", () => {

it("preserves the caller's declaration order", () => {
const table = renderResultsTable([
result({ name: "janitor", definitionId: 2604 }),
result({ name: "smoke-failure-reporter", definitionId: 2604 }),
result({ name: "canary", definitionId: 2601 }),
]);
const janitorIdx = table.indexOf("janitor");
const reporterIdx = table.indexOf("smoke-failure-reporter");
const canaryIdx = table.indexOf("canary");
expect(janitorIdx).toBeGreaterThan(-1);
expect(canaryIdx).toBeGreaterThan(janitorIdx);
expect(reporterIdx).toBeGreaterThan(-1);
expect(canaryIdx).toBeGreaterThan(reporterIdx);
});

it("renders a '-' placeholder for missing buildId/url", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,12 @@ describe("runFixtures", () => {
it("respects the configured concurrency (never more than N builds polled in parallel)", async () => {
let inFlight = 0;
let maxInFlight = 0;
const fixtureNames = ["canary", "azure-cli", "noop-target", "janitor"] as const;
const fixtureNames = [
"canary",
"azure-cli",
"noop-target",
"smoke-failure-reporter",
] as const;
const buildIds = [701, 702, 703, 704];

const client: FixtureBuildClient = {
Expand Down
10 changes: 4 additions & 6 deletions scripts/ado-script/src/compiler-smoke-e2e/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* Environment configuration for the deterministic compiler-smoke E2E harness.
*
* This harness stages the compiler candidate produced by the current build as
* a pinned `supply-chain.pipeline-artifact` source across five real,
* registered ADO pipeline fixtures (canary, azure-cli, noop-target, janitor,
* a pinned `supply-chain.pipeline-artifact` source across four registered ADO
* pipeline fixtures (canary, azure-cli, noop-target, and
* smoke-failure-reporter), pushes the staged candidate to a per-run branch on
* a mirror repo, queues all five, and asserts they all go green.
* a mirror repo, queues all four, and asserts they all go green.
*
* Strict, fail-closed parsing lives here so every other module can trust a
* fully validated {@link CompilerSmokeConfig} rather than re-checking env
Expand All @@ -32,7 +32,6 @@ export const FIXTURE_NAMES = [
"canary",
"azure-cli",
"noop-target",
"janitor",
"smoke-failure-reporter",
] as const;

Expand All @@ -59,7 +58,7 @@ export interface CompilerSmokeConfig {
readonly adoAwBin: string;
/** Pipeline artifact name pinned into each fixture's supply-chain config. */
readonly artifactName: string;
/** ADO Git repo hosting the five registered fixture pipeline definitions. */
/** ADO Git repo hosting the four registered fixture pipeline definitions. */
readonly mirrorRepo: string;
/** Registered ADO pipeline definition id, keyed by fixture name. */
readonly definitionIds: Readonly<Record<FixtureName, number>>;
Expand Down Expand Up @@ -89,7 +88,6 @@ const DEFINITION_ID_ENV_BY_FIXTURE: Readonly<Record<FixtureName, string>> = {
canary: "COMPILER_SMOKE_CANARY_DEFINITION_ID",
"azure-cli": "COMPILER_SMOKE_AZURE_CLI_DEFINITION_ID",
"noop-target": "COMPILER_SMOKE_NOOP_TARGET_DEFINITION_ID",
janitor: "COMPILER_SMOKE_JANITOR_DEFINITION_ID",
"smoke-failure-reporter": "COMPILER_SMOKE_REPORTER_DEFINITION_ID",
};

Expand Down
18 changes: 9 additions & 9 deletions scripts/ado-script/src/compiler-smoke-e2e/fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/**
* Manifest of the five fixed compiler-smoke fixtures.
* Manifest of the four fixed compiler-smoke fixtures.
*
* These are the same five agentic-pipeline sources documented in
* `tests/safe-outputs/README.md` (canary, azure-cli, noop-target, janitor,
* smoke-failure-reporter) — this harness does not invent its own fixture
* content. It reads the exact files from the detached candidate worktree
* (an exact checkout of `BUILD_SOURCEVERSION`, at
* These are selected release-backed agentic-pipeline sources documented in
* `tests/safe-outputs/README.md` (canary, azure-cli, noop-target, and
* smoke-failure-reporter). The weekly janitor remains in the release lane but
* is not part of candidate checks. The harness reads the exact files from the
* detached candidate worktree (an exact checkout of `BUILD_SOURCEVERSION`, at
* `<worktree>/tests/safe-outputs/<name>.md` — never from
* `BUILD_SOURCESDIRECTORY`, which may sit at a different commit), stages a
* pinned `supply-chain.pipeline-artifact` transform of each onto the mirror
* repo, recompiles, and queues the five FIXED "candidate lane" pipeline
* repo, recompiles, and queues the four FIXED "candidate lane" pipeline
* definitions tracked in `tests/compiler-smoke-e2e/REGISTERED.md` (distinct
* from the release-backed definitions those same sources also feed).
*
Expand Down Expand Up @@ -38,12 +38,12 @@ export function fixturePaths(name: FixtureName): FixturePaths {
};
}

/** All five fixtures in the stable declaration order used throughout the harness. */
/** All four fixtures in the stable declaration order used throughout the harness. */
export const ALL_FIXTURES: readonly FixturePaths[] = FIXTURE_NAMES.map(fixturePaths);

/**
* The exact set of repo-relative paths the candidate-staging commit is
* allowed to touch: the five markdown sources, their five compiled locks,
* allowed to touch: the four markdown sources, their four compiled locks,
* and the compiler-managed `.gitattributes` block. Any other changed path
* fails the run before it pushes anything.
*/
Expand Down
6 changes: 3 additions & 3 deletions scripts/ado-script/src/compiler-smoke-e2e/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
*
* Stages the compiler candidate produced by the current build (PR or
* nightly `main`) as a pinned `supply-chain.pipeline-artifact` source across
* the five real fixtures documented in `tests/safe-outputs/README.md`
* (canary, azure-cli, noop-target, janitor, smoke-failure-reporter), pushes
* four release-backed fixtures documented in `tests/safe-outputs/README.md`
* (canary, azure-cli, noop-target, and smoke-failure-reporter), pushes
* the staged candidate to a short-lived branch on the mirror repo, queues
* the five FIXED "candidate lane" pipeline definitions (tracked in
* the four FIXED "candidate lane" pipeline definitions (tracked in
* `tests/compiler-smoke-e2e/REGISTERED.md`), and asserts they all go green.
*
* See `config.ts` for the full required/optional env var contract.
Expand Down
2 changes: 1 addition & 1 deletion scripts/ado-script/src/compiler-smoke-e2e/runner.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Bounded-concurrency queue/poll/cancel state machine for the five staged
* Bounded-concurrency queue/poll/cancel state machine for the staged
* fixture builds.
*
* Contract:
Expand Down
6 changes: 3 additions & 3 deletions scripts/ado-script/src/compiler-smoke-e2e/stale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
* (`COMPILER_SMOKE_STALE_REF_HOURS`), and (c) that parent build is
* terminal. Note that (c) is NOT by itself proof the orchestration it
* started is done — an abruptly canceled/killed parent process can reach a
* terminal ADO build status while the five fixture builds it queued are
* still running. The scanner therefore also queries each of the five FIXED
* terminal ADO build status while the fixture builds it queued are still
* running. The scanner therefore also queries each configured FIXED
* child definitions on the ref's exact branch (see
* `listBuildsForDefinitionBranch`) and inspects their statuses directly;
* only when every child build found there is ALSO terminal (or none exist)
Expand Down Expand Up @@ -157,7 +157,7 @@ export async function scanStaleRefs(opts: ScanStaleRefsOptions): Promise<StaleRe
}

// The orchestrator's own run is old enough and terminal, but that alone
// does not prove the five fixture ("child") builds it queued on this
// does not prove the fixture ("child") builds it queued on this
// exact branch have also finished — an abruptly cancelled orchestrator
// run can "complete" while its queued children keep running. Check
// every fixed child definition on this exact branch before declaring
Expand Down
2 changes: 1 addition & 1 deletion scripts/rotate-agentplayground-secrets.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ param(
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

$copilotDefinitionIds = @(2545, 2546, 2547, 2548, 2549, 2554, 2555, 2556, 2557, 2558)
$copilotDefinitionIds = @(2545, 2546, 2547, 2548, 2549, 2554, 2555, 2556, 2558)
$reporterDefinitionIds = @(2549, 2558)
$executorDefinitionIds = @(2550)
$triggerDefinitionIds = @(2551)
Expand Down
21 changes: 11 additions & 10 deletions tests/compiler-smoke-e2e/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Candidate compiler agentic smoke

This suite validates compiler changes before release. It builds `ado-aw` and
`ado-script` from the exact pull-request or `main` commit, recompiles every
workflow under [`tests/safe-outputs/`](../safe-outputs/), and queues five fixed
AgentPlayground definitions against the regenerated YAML.
`ado-script` from the exact pull-request or `main` commit, recompiles four
selected workflows under [`tests/safe-outputs/`](../safe-outputs/) (canary,
azure-cli, noop-target, and failure reporter), and queues four fixed
AgentPlayground definitions against the regenerated YAML. The weekly janitor
remains covered by the release-backed lane and is intentionally excluded here.

It complements rather than replaces the release-backed daily smoke:

Expand All @@ -27,7 +29,7 @@ binary cannot drift.
`ado-aw-linux-x64`, `awf-linux-x64`, `ado-script.zip`, `checksums.txt`, and
`provenance.json`.
4. The test-only `compiler-smoke-e2e` TypeScript harness creates a detached
worktree, adds an exact `supply-chain.pipeline-artifact` source to all five
worktree, adds an exact `supply-chain.pipeline-artifact` source to all four
smoke files, removes their schedules, recompiles them with the candidate
compiler, and runs `ado-aw check`. Both compiler subprocesses receive
`ADO_AW_COMPILE_REMOTE_URL` set to the target `ado-aw-mirror` URL, so
Expand All @@ -36,7 +38,7 @@ binary cannot drift.
5. The harness pushes the worktree commit to
`refs/heads/ado-aw-smoke-candidate/<producer-build-id>` in the Azure Repo
`ado-aw-mirror`.
6. Five fixed child definitions are queued concurrently with both that ref and
6. Four fixed child definitions are queued concurrently with both that ref and
its exact commit SHA. Each generated pipeline downloads and verifies the
artifact from the still-running producer build.
7. The harness waits for all children, cancels non-terminal runs after a
Expand Down Expand Up @@ -79,10 +81,10 @@ to that manifest.

The definitions are registered against `ado-aw-mirror`, not GitHub. Their
default branch is the permanent inert ref
`refs/heads/ado-aw-smoke-candidate-base`, whose five lock-file paths contain
`refs/heads/ado-aw-smoke-candidate-base`, whose four lock-file paths contain
hand-authored `trigger: none`, `pr: none`, schedule-free placeholders. A child
therefore runs only when the orchestrator explicitly supplies a candidate ref.
The checked-in [`inert-child.yml`](inert-child.yml) is copied to those five
The checked-in [`inert-child.yml`](inert-child.yml) is copied to those four
paths when the base ref is created.

See [`REGISTERED.md`](REGISTERED.md) for definition IDs and variables.
Expand All @@ -93,7 +95,7 @@ The principal behind `agent-playground-write`, used only after artifact
publication, needs:

- Contribute/Create branch/Delete refs on `ado-aw-mirror`;
- Queue builds and Stop builds on the five child definitions;
- Queue builds and Stop builds on the four child definitions;
- Read builds and artifacts in AgentPlayground.

Child build identities need Code Read on `ado-aw-mirror` and Build Read on the
Expand All @@ -117,7 +119,6 @@ Set these non-secret variables on the orchestrator:
COMPILER_SMOKE_CANARY_DEFINITION_ID
COMPILER_SMOKE_AZURE_CLI_DEFINITION_ID
COMPILER_SMOKE_NOOP_TARGET_DEFINITION_ID
COMPILER_SMOKE_JANITOR_DEFINITION_ID
COMPILER_SMOKE_REPORTER_DEFINITION_ID
```

Expand Down Expand Up @@ -149,7 +150,7 @@ The full live contract requires AgentPlayground and the fixed definitions:

1. the producer remains in progress after publishing its artifact;
2. every child downloads the exact producer `run-id`;
3. all five children succeed;
3. all four children succeed;
4. child provenance identifies the producer definition, build, and source SHA;
5. the per-run mirror ref is removed.

Expand Down
8 changes: 5 additions & 3 deletions tests/compiler-smoke-e2e/REGISTERED.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ These definitions live in
| `Candidate compiler smoke - canary` | `ado-aw-mirror` | `tests/safe-outputs/canary.lock.yml` | `2554` |
| `Candidate compiler smoke - azure-cli` | `ado-aw-mirror` | `tests/safe-outputs/azure-cli.lock.yml` | `2555` |
| `Candidate compiler smoke - noop-target` | `ado-aw-mirror` | `tests/safe-outputs/noop-target.lock.yml` | `2556` |
| `Candidate compiler smoke - janitor` | `ado-aw-mirror` | `tests/safe-outputs/janitor.lock.yml` | `2557` |
| `Candidate compiler smoke - failure reporter` | `ado-aw-mirror` | `tests/safe-outputs/smoke-failure-reporter.lock.yml` | `2558` |

All five child definitions use
All four child definitions use
`refs/heads/ado-aw-smoke-candidate-base` as their default branch. The ref is
permanent and inert; the harness never deletes it. Its seed commit is
`2b5fa7c336bd1f55a867cfc281e665472730b84c`.

Candidate janitor definition `2557` was retired. The release-backed janitor
definition `2548` remains scheduled weekly and is not part of this lane.

## Security record

Before protected resources are authorized, record the verified fork settings
Expand All @@ -43,7 +45,7 @@ Release-smoke definitions `2545`-`2549` and scheduled trigger E2E definition
independent of the candidate compiler PR lane.

Definition `2559` uses the `github.com_githubnext` GitHub service connection
and stores the five child definition IDs as non-secret definition variables.
and stores the four child definition IDs as non-secret definition variables.

Every child definition needs its own secret `GITHUB_TOKEN` for Copilot CLI
authentication. Definition `2558` additionally needs
Expand Down
Loading
Loading