Ctrl K
ComunidadGuías…

scripts/verify-cf-smoke.mjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * Cloudflare-target smoke gate: builds the CF bundle, boots it under a real
 * workerd (`wrangler dev`) against the in-memory fake Slack + fake provider
 * backend, and drives the full Slack-native first-run story — programmatic app
 * creation, confidential bot OAuth, signed Events proof, first-Owner OIDC —
 * then signed Slack events end-to-end. Asserts the parts that only
 * workerd can prove:
 *
 *   1. a deploy-minted setup capability creates no person or browser session,
 *      while exact installer OIDC creates the first Owner and session last,
 *   2. the DO-backed config store seeds and serves /admin/api/agents,
 *   3. the app boots healthy with no Slack installation and Events fail closed,
 *   4. app creation, bot install, issued scopes, directory/channel probes,
 *      separately signed Events proof, and OIDC all use the exact fake realm,
 *   4. a signed synthetic app_mention verifies against the STORED signing
 *      secret, is admitted, and the turn delivers a final to (fake) Slack
 *      through the in-process dispatch + waitUntil path,
 *   5. an identical redelivery is deduped by the DO claim store,
 *   6. a workerd RESTART (same --persist-to) still dedupes the original
 *      event, still verifies with the stored secret, and still admits an
 *      implicit thread reply — Durable Object state survives the process,
 *   7. a tampered signature is rejected (the stored secret is really used).
 *
 * No secrets, no external traffic: every outbound URL points at 127.0.0.1.
 * Exit 0 on success, 1 with diagnostics on failure. The default/core run
 * builds and structurally validates Sandbox before rebuilding and booting core;
 * SMOKE_SKIP_BUILD=1 is available only to an explicit Sandbox-profile run that
 * reuses an existing dist-cf artifact for iteration speed.
 */
import { spawn, spawnSync } from 'node:child_process';
import { createHash, generateKeyPairSync } from 'node:crypto';
import { existsSync, mkdtempSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import vm from 'node:vm';
import { hasScheduledComposition } from './worker-artifact.mjs';
import { readBuildIdentity } from './lib/build-identity.mjs';

import {
  REPO_ROOT,
  SIGNING_SECRET,
  EVENTS_PATH,
  assertNodeVersion,
  getFreePort,
  loadFake,
  loadTsModule,
  postSignedEvent,
  delay,
} from './lib/offline-harness.mjs';
import { runDrainCheck } from './lib/cf-drain-check.mjs';
import {
  cloudflareSmokeTelemetryDevVars,
  withCloudflareSmokeTelemetryBindings,
} from './lib/cf-smoke-telemetry.mjs';
import {
  classifyCloudflareDeploymentProfile,
  resolveCloudflareDeploymentProfile,
} from './cloudflare-deployment-profile.mjs';
import {
  mintSetupCapability,
  SETUP_CAPABILITY_DIGEST_BINDING,
  SETUP_CAPABILITY_ISSUED_AT_BINDING,
} from '../src/auth/setup-capability.mjs';

const WRANGLER_BIN = join(REPO_ROOT, 'node_modules', '.bin', 'wrangler');
const CF_OUTPUT_DIR = join(REPO_ROOT, 'dist-cf');
export const CF_WRANGLER_CONFIG = join(CF_OUTPUT_DIR, 'chickpea', 'wrangler.json');
const CF_SMOKE_WRANGLER_CONFIG = join(CF_OUTPUT_DIR, 'chickpea', 'wrangler.smoke.json');
export const CF_AI_SMOKE_CONFIG = join(CF_OUTPUT_DIR, 'chickpea', 'wrangler.ai-smoke.json');
export const PERSIST_DIR = mkdtempSync(join(tmpdir(), 'chickpea-cf-smoke-'));
const AUTH_SECRET = '9d'.repeat(32);
const PUBLIC_ORIGIN = 'https://chickpea-smoke.invalid';
export const WORKSPACE = 'T0SMOKE';
export const APP_ID = 'A0SMOKE';
export const BOT_USER_ID = 'UBOTSMOKE';
export const OWNER_USER_ID = 'UOWNERSMOKE';
export const ONBOARDING_DM_CHANNEL = 'DSMOKEONBOARDING';
export const OAUTH_CLIENT_ID = '123456.789012';
export const OAUTH_CLIENT_SECRET = 'fake-confidential-client-secret';
export const OAUTH_CONFIGURATION_TOKEN = 'xoxe.fake-workerd-configuration-token';
export const OAUTH_BOT_TOKEN = 'xoxb-fake-workerd-bot-token';
const RECOVERY_TOKEN = '5c'.repeat(32);
export const CHANNEL = 'C0SMOKE';
const AI_CHANNEL = 'C0SMOKEAI';
const MENTION_TS = '1782770400.000100';
const MEMORY_TS = '1782770450.000100';
const AI_MENTION_TS = '1782770100.000100';
export const PORT = process.env.SMOKE_WRANGLER_PORT ? Number(process.env.SMOKE_WRANGLER_PORT) : await getFreePort();
const AI_SMOKE_SERVICE = 'chickpea-ai-smoke-stub';
const AI_SMOKE_REPLY = 'workers-ai-binding-smoke::gateway-disabled';
const AI_SMOKE_RPC_FLAG = 'enable_abortsignal_rpc';
const USAGE_PRE_DELIVERY_BUDGET_MS = 100;
const AGENT_BINDINGS = [
  ['FLUE_CHICKPEA_SLACK_V2_AGENT', 'FlueChickpeaSlackV2Agent'],
  ['FLUE_CHICKPEA_ROUTINE_INTENT_V2_AGENT', 'FlueChickpeaRoutineIntentV2Agent'],
  ['FLUE_CHICKPEA_ROUTINE_EXECUTION_V2_AGENT', 'FlueChickpeaRoutineExecutionV2Agent'],
  ['FLUE_CHICKPEA_TEST_TURN_V1_AGENT', 'FlueChickpeaTestTurnV1Agent'],
];
const BETA_FLUE_CLASSES = [
  'FlueRegistry',
  'FlueSlackThreadAgent',
  'FlueRoutineIntentAgent',
  'FlueRoutineWorkflow',
];
const RETIRED_AUTH_CLASSES = ['AuthGuard'];

// Slow-turn case: a distinct channel + thread whose provider reply is held, so
// the events ack must return before the turn and the DO alarm relay delivers it.
const SLOW_CHANNEL = 'C0SMOKESLOW';
const SLOW_MENTION_TS = '1782771000.000100';
const GEMINI_MENTION_TS = '1782771200.000100';
// Local workerd does not cancel waitUntil at ~30s (checked 2026-09-24: a 40s
// waitUntil completed under `wrangler dev`), so a hold past 30s proves nothing
// here. The hold only has to exceed the 10s fast-ack bound so an inline turn
// would fail that check. Overridable for iteration; keep it above 10s.
const SLOW_TURN_DELAY_MS = Number(process.env.SMOKE_SLOW_TURN_DELAY_MS ?? 12_000);
// Which turn executor this run proves: the default (runner, variable unset)
// or the SLACK_TAG_TURN_EXECUTOR=alarm emergency fallback.
if (![undefined, '', 'runner', 'alarm'].includes(process.env.SMOKE_TURN_EXECUTOR)) {
  throw new Error('SMOKE_TURN_EXECUTOR must be runner (the default) or alarm.');
}
const SMOKE_TURN_EXECUTOR = process.env.SMOKE_TURN_EXECUTOR === 'alarm' ? 'alarm' : 'runner';
if (!(SLOW_TURN_DELAY_MS > 10_000)) {
  throw new Error('SMOKE_SLOW_TURN_DELAY_MS must exceed the 10000 ms fast-ack bound.');
}

export const failures = [];
let adminCookie = '';
export let defaultAgentMention = '';
export function setDefaultAgentMention(mention) {
  defaultAgentMention = mention;
}
function check(ok, label, detail = '') {
  const status = ok ? 'ok  ' : 'FAIL';
  console.log(`  [${status}] ${label}${detail ? ` — ${detail}` : ''}`);
  if (!ok) failures.push(label);
}

function sameArray(actual, expected) {
  return (
    Array.isArray(actual) &&
    actual.length === expected.length &&
    actual.every((value, index) => value === expected[index])
  );
}

export function buildCloudflareTarget(profile, { reuseExisting = false } = {}) {
  if (reuseExisting && process.env.SMOKE_SKIP_BUILD === '1' && existsSync(CF_WRANGLER_CONFIG)) {
    console.log(`• SMOKE_SKIP_BUILD=1 — reusing existing ${profile} dist-cf build`);
    return;
  }
  console.log(`• building ${profile} Cloudflare target (Vite → dist-cf)…`);
  const result = spawnSync('npm', ['run', 'flue:build:cf'], {
    cwd: REPO_ROOT,
    env: { ...process.env, CHICKPEA_DEPLOY_PROFILE: profile },
    stdio: 'inherit',
  });
  if (result.status !== 0) {
    throw new Error(`${profile} flue:build:cf failed (exit ${result.status})`);
  }
}

function verifyBuildArtifacts(expectedProfile = resolveCloudflareDeploymentProfile()) {
  const config = JSON.parse(readFileSync(CF_WRANGLER_CONFIG, 'utf8'));
  let actualProfile;
  try {
    actualProfile = classifyCloudflareDeploymentProfile(config);
  } catch (error) {
    check(false, `built wrangler.json has an exact ${expectedProfile} deployment profile`, String(error));
  }
  check(
    actualProfile === expectedProfile,
    `built wrangler.json matches the requested ${expectedProfile} deployment profile`,
    `generated ${actualProfile ?? 'invalid'}`,
  );
  const artifactRoot = join(CF_OUTPUT_DIR, 'chickpea');
  const bundle = readdirSync(artifactRoot, { recursive: true })
    .filter((entry) => typeof entry === 'string' && entry.endsWith('.js'))
    .sort()
    .map((entry) => readFileSync(join(artifactRoot, entry), 'utf8'))
    .join('\n');
  const doBindings = config.durable_objects?.bindings ?? [];
  check(
    doBindings.some((b) => b.name === 'TAG_STATE' && b.class_name === 'TagStateStore'),
    'built wrangler.json carries the TAG_STATE binding',
  );
  check(
    doBindings.some((b) => b.name === 'SLACK_THREAD_RUNNER' && b.class_name === 'SlackThreadRunner'),
    'built wrangler.json carries the SLACK_THREAD_RUNNER binding',
  );
  for (const [name, className] of AGENT_BINDINGS) {
    check(
      doBindings.some((binding) => binding.name === name && binding.class_name === className),
      `built wrangler.json carries ${name}/${className}`,
    );
  }
  if (expectedProfile === 'sandbox') {
    check(
      doBindings.some((b) => b.name === 'SANDBOX' && b.class_name === 'Sandbox'),
      'Sandbox build carries the reviewed Sandbox DO binding',
    );
  } else {
    check(
      !doBindings.some((b) => b.name === 'SANDBOX' || b.class_name === 'Sandbox'),
      'core build carries no Sandbox DO binding',
    );
    check((config.containers ?? []).length === 0, 'core build declares no Container application');
  }
  const authDb = (config.d1_databases ?? []).find((binding) => binding.binding === 'AUTH_DB');
  check(
    Boolean(authDb) && String(authDb.migrations_dir ?? '').endsWith('migrations/better-auth'),
    'built wrangler.json carries AUTH_DB reviewed migrations',
  );
  const migrations = config.migrations ?? [];
  const tags = migrations.map((migration) => migration.tag);
  check(
    sameArray(tags, ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9', 'v10', 'v11', 'v12']),
    'built wrangler.json migrations use the exact append-only v1 through v12 chain',
    tags.join(','),
  );
  const sandboxMigration = migrations.find((migration) => migration.tag === 'v3');
  check(
    sameArray(sandboxMigration?.new_sqlite_classes ?? [], ['Sandbox']),
    'built wrangler.json preserves the v3 Sandbox class migration in every deployment profile',
  );
  const reset = migrations.find((migration) => migration.tag === 'v6');
  check(
    sameArray(
      [...(reset?.deleted_classes ?? [])].sort(),
      [...BETA_FLUE_CLASSES].sort(),
    ),
    'v6 deletes exactly the four beta Flue classes',
  );
  const authGuardMigration = migrations.find((migration) => migration.tag === 'v7');
  check(
    sameArray(authGuardMigration?.new_sqlite_classes ?? [], RETIRED_AUTH_CLASSES),
    'v7 preserves the AuthGuard SQLite class history',
  );
  const authGuardRetirement = migrations.find((migration) => migration.tag === 'v8');
  check(
    sameArray(authGuardRetirement?.deleted_classes ?? [], RETIRED_AUTH_CLASSES),
    'v8 retires exactly the AuthGuard class',
  );
  const gatewaySessionMigration = migrations.find((migration) => migration.tag === 'v9');
  check(
    sameArray(gatewaySessionMigration?.new_sqlite_classes ?? [], ['SlackGatewaySession']),
    'v9 adds exactly the outbound shared-app gateway session class',
  );
  const codingWorkerMigration = migrations.find((migration) => migration.tag === 'v10');
  check(
    sameArray(codingWorkerMigration?.new_sqlite_classes ?? [], ['FlueChickpeaCodingWorkerV1Agent']),
    'v10 adds exactly the coding worker Agent class',
  );
  const threadRunnerMigration = migrations.find((migration) => migration.tag === 'v11');
  check(
    sameArray(threadRunnerMigration?.new_sqlite_classes ?? [], ['SlackThreadRunner'])
      && (threadRunnerMigration?.deleted_classes ?? []).length === 0,
    'v11 adds exactly the per-thread Slack runner class',
  );
  const testTurnMigration = migrations.find((migration) => migration.tag === 'v12');
  check(
    sameArray(testTurnMigration?.new_sqlite_classes ?? [], ['FlueChickpeaTestTurnV1Agent'])
      && (testTurnMigration?.deleted_classes ?? []).length === 0,
    'v12 adds exactly the test run Agent class',
  );
  if (expectedProfile === 'sandbox') {
    const sandboxContainer = (config.containers ?? []).find(
      (container) => container.class_name === 'Sandbox',
    );
    check(
      sandboxContainer?.instance_type === 'standard-1' && sandboxContainer?.max_instances === 25,
      'Sandbox build keeps the bounded multi-thread capacity',
      sandboxContainer
        ? `${sandboxContainer.instance_type} / ${sandboxContainer.max_instances} max instances`
        : 'missing',
    );
  }
  const redirect = join(REPO_ROOT, '.wrangler', 'deploy', 'config.json');
  const redirectBody = existsSync(redirect) ? readFileSync(redirect, 'utf8') : '';
  check(redirectBody.includes('dist-cf'), '.wrangler/deploy/config.json points into dist-cf');
  check(
    existsSync(join(REPO_ROOT, 'src', 'db.node.ts')) &&
      !existsSync(join(REPO_ROOT, 'src', 'db.ts')),
    'Node-only persistence stays outside Cloudflare auto-discovery',
  );
  check(config.ai?.binding === 'AI', 'built wrangler.json carries the production AI binding');
  check(
    config.version_metadata?.binding === 'CF_VERSION_METADATA',
    'built wrangler.json carries the Worker version metadata binding',
  );
  check(
    sameArray(config.triggers?.crons ?? [], ['* * * * *']),
    'built wrangler.json carries exactly one heartbeat Cron Trigger',
  );
  check(
    !Object.hasOwn(config.vars ?? {}, 'TAG_OPENAI_SUBSCRIPTION_ENABLED'),
    'built artifact exposes no OpenAI Subscription preview gate',
  );
  check(
    Object.keys(config.vars ?? {}).sort().join(',') === 'CHICKPEA_APP_VERSION,CHICKPEA_SOURCE_COMMIT' &&
      config.vars.CHICKPEA_APP_VERSION === readBuildIdentity(REPO_ROOT).version &&
      config.vars.CHICKPEA_SOURCE_COMMIT === (readBuildIdentity(REPO_ROOT).sourceCommit ?? ''),
    'built artifact carries exact source identity and no customer-editable runtime defaults',
  );
  check(
    config.observability?.traces?.enabled === true,
    'built artifact enables Workers Traces for metadata-only Flue spans',
  );
  check(
    hasScheduledComposition(readFileSync(join(artifactRoot, config.main), 'utf8')) &&
      bundle.includes('chickpea-slack-v2') &&
      bundle.includes('chickpea-routine-intent-v2') &&
      bundle.includes('chickpea-routine-execution-v2') &&
      bundle.includes('chickpea.response-metadata') &&
      bundle.includes('@flue/runtime/cloudflare-tracing') &&
      bundle.includes('FLUE_PRIVATE_SANDBOX_COMMAND_V1'),
    'built Worker composes the heartbeat, fresh agents, and content-free tracing',
  );
  check(
    bundle.includes('routine_schedule_actions') &&
      bundle.includes('manage_scheduled_work') &&
      bundle.includes('slackScheduleActionInvoke') &&
      bundle.includes('claimDueScheduleActions') &&
      bundle.includes('schedule_action_payload_unavailable'),
    'built Worker carries the durable schedule-action ledger, tool, RPC, and alarm recovery path',
  );
}

export function writeSmokeWranglerConfigs(setup) {
  const productionConfig = JSON.parse(readFileSync(CF_WRANGLER_CONFIG, 'utf8'));
  // The production AI binding accepts the turn's AbortSignal directly. Our
  // local stand-in crosses a service-RPC boundary, so opt only the disposable
  // smoke workers into serializing that otherwise-identical argument.
  const smokeCompatibilityFlags = [
    ...new Set([...(productionConfig.compatibility_flags ?? []), AI_SMOKE_RPC_FLAG]),
  ];
  const smokeConfig = {
    ...productionConfig,
    d1_databases: (productionConfig.d1_databases ?? []).map((database) =>
      database.binding === 'AUTH_DB'
        ? { ...database, database_id: '00000000-0000-0000-0000-000000000001' }
        : database),
    vars: withCloudflareSmokeTelemetryBindings({
      ...(productionConfig.vars ?? {}),
      [SETUP_CAPABILITY_DIGEST_BINDING]: setup.digest,
      [SETUP_CAPABILITY_ISSUED_AT_BINDING]: String(setup.issuedAt),
      // Exercise exactly one internal workspace/channel through the enforced
      // ledger lane while the ordinary and slow channels remain legacy.
      SLACK_TAG_LEDGER_CANARY_CHANNELS: `${WORKSPACE}/${AI_CHANNEL}`,
      // Journeys run through per-thread SlackThreadRunner objects, the
      // default executor. SMOKE_TURN_EXECUTOR=alarm (verify:cf-smoke:alarm)
      // sets the emergency fallback so the state store's alarm path stays
      // covered.
      ...(SMOKE_TURN_EXECUTOR === 'alarm' ? { SLACK_TAG_TURN_EXECUTOR: 'alarm' } : {}),
    }),
    dev: { ...(productionConfig.dev ?? {}), enable_containers: false },
    compatibility_flags: smokeCompatibilityFlags,
    services: [
      ...(productionConfig.services ?? []).filter((service) => service.binding !== 'AI'),
      { binding: 'AI', service: AI_SMOKE_SERVICE },
    ],
  };
  // A Sandbox-profile structure smoke never calls the coding tier, and local
  // Wrangler may invoke Docker despite dev.enable_containers=false. Core has
  // no declaration; for Sandbox only, omit it from this disposable copy after
  // the exact production shape was asserted above.
  delete smokeConfig.containers;
  delete smokeConfig.ai;
  writeFileSync(CF_SMOKE_WRANGLER_CONFIG, `${JSON.stringify(smokeConfig, null, 2)}\n`);
  writeFileSync(
    CF_AI_SMOKE_CONFIG,
    `${JSON.stringify(
      {
        name: AI_SMOKE_SERVICE,
        main: '../../scripts/fixtures/cloudflare-ai-binding-smoke.mjs',
        compatibility_date: productionConfig.compatibility_date,
        compatibility_flags: smokeCompatibilityFlags,
        vars: { AI_SMOKE_REPLY },
      },
      null,
      2,
    )}\n`,
  );
}

export function writeDevVars(fakeUrl) {
  // wrangler dev reads .dev.vars from the directory of the config file it was
  // given. dist-cf is disposable build output, so writing here never touches a
  // developer's real .dev.vars in the repo root.
  //
  // Deliberately no Slack app/bot credentials here: the smoke runs the real
  // app-creation and OAuth journey. Only the independent deployment keyring
  // and local provider/API endpoints are target configuration.
  writeFileSync(
    join(CF_OUTPUT_DIR, 'chickpea', '.dev.vars'),
    [
      `CHICKPEA_AUTH_SECRET=${AUTH_SECRET}`,
      `CHICKPEA_RECOVERY_TOKEN=${RECOVERY_TOKEN}`,
      'CHICKPEA_CREDENTIAL_KEY_CURRENT_ID=key_v1',
      `CHICKPEA_CREDENTIAL_KEY_KEY_V1=${Buffer.alloc(32, 7).toString('base64url')}`,
      `SLACK_TAG_PUBLIC_URL=${PUBLIC_ORIGIN}`,
      `SLACK_API_URL=${fakeUrl}/api/`,
      `LOCAL_STUB_URL=${fakeUrl}/v1`,
      'SLACK_TAG_MODEL=local-stub/smoke-model',
      `ANTHROPIC_API_URL=${fakeUrl}`,
      `OPENAI_API_URL=${fakeUrl}/openai/v1`,
      `OPENROUTER_API_URL=${fakeUrl}/openrouter`,
      `GEMINI_API_URL=${fakeUrl}/gemini/v1beta`,
      `GEMINI_BASE_URL=${fakeUrl}/gemini/v1beta`,
      ...cloudflareSmokeTelemetryDevVars(),
      '',
    ].join('\n'),
  );
}

export function applyLocalAuthMigrations() {
  const result = spawnSync(
    WRANGLER_BIN,
    [
      'd1',
      'migrations',
      'apply',
      'AUTH_DB',
      '--local',
      '--persist-to',
      PERSIST_DIR,
      '--config',
      CF_SMOKE_WRANGLER_CONFIG,
    ],
    { cwd: REPO_ROOT, env: { ...process.env, CI: '1' }, stdio: 'inherit' },
  );
  if (result.status !== 0) {
    throw new Error(`local AUTH_DB migrations failed (exit ${result.status})`);
  }
}

export function spawnWranglerDev() {
  const child = spawn(
    WRANGLER_BIN,
    [
      'dev',
      '--config',
      CF_SMOKE_WRANGLER_CONFIG,
      '--config',
      CF_AI_SMOKE_CONFIG,
      '--port',
      String(PORT),
      // OUTSIDE dist-cf on purpose: a rebuild wipes the build output, and local
      // DO state must survive it (and the restart half of this smoke).
      '--persist-to',
      PERSIST_DIR,
      // This gate verifies the production container declaration above but
      // intentionally runs read-only model turns that never acquire one.
      // Avoid making an unrelated local Docker daemon a prerequisite.
      '--enable-containers=false',
    ],
    { cwd: REPO_ROOT, env: { ...process.env, CI: '1' }, stdio: ['ignore', 'pipe', 'pipe'] },
  );
  let output = '';
  child.stdout.on('data', (chunk) => (output += chunk));
  child.stderr.on('data', (chunk) => (output += chunk));
  return { child, getOutput: () => output };
}

export function stopWrangler(handle) {
  return new Promise((resolve) => {
    const { child } = handle;
    if (child.exitCode !== null || child.signalCode !== null) {
      resolve();
      return;
    }
    const settle = setTimeout(() => {
      child.kill('SIGKILL');
      resolve();
    }, 5000);
    child.once('exit', () => {
      clearTimeout(settle);
      resolve();
    });
    child.kill('SIGTERM');
  });
}

export async function adminFetch(baseUrl, path, init = {}) {
  const method = String(init.method ?? 'GET').toUpperCase();
  const mutation = ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method);
  const response = await fetch(`${baseUrl}${path}`, {
    ...init,
    headers: {
      ...(adminCookie ? { cookie: adminCookie } : {}),
      'content-type': 'application/json',
      ...(mutation ? { origin: PUBLIC_ORIGIN, 'sec-fetch-site': 'same-origin' } : {}),
      ...(init.headers ?? {}),
    },
  });
  const text = await response.text();
  let body;
  try {
    body = text ? JSON.parse(text) : undefined;
  } catch {
    body = text;
  }
  return { status: response.status, body };
}

async function adminPageHtml(baseUrl, path = '/admin') {
  const response = await fetch(`${baseUrl}${path}`, {
    headers: adminCookie ? { cookie: adminCookie } : {},
  });
  return response.text();
}

function formHeaders() {
  return {
    origin: PUBLIC_ORIGIN,
    'sec-fetch-site': 'same-origin',
    'content-type': 'application/x-www-form-urlencoded',
  };
}

async function postForm(baseUrl, path, fields, cookie = '') {
  return fetch(`${baseUrl}${path}`, {
    method: 'POST',
    redirect: 'manual',
    headers: { ...formHeaders(), ...(cookie ? { cookie } : {}) },
    body: new URLSearchParams(fields),
  });
}

function responseCookie(response, prefix) {
  const values = typeof response.headers.getSetCookie === 'function'
    ? response.headers.getSetCookie()
    : [response.headers.get('set-cookie') ?? ''];
  for (const value of values) {
    for (const candidate of value.split(/,(?=\s*[^;,]+=)/)) {
      const cookie = candidate.trim().split(';', 1)[0] ?? '';
      if (cookie.startsWith(prefix)) return cookie;
    }
  }
  return '';
}

function slackAuthorizationUrlFromHandoff(html) {
  const encoded = /data-slack-authorization-link href="([^"]+)"/.exec(html)?.[1];
  return new URL(encoded ? encoded.replaceAll('&', '&') : 'about:blank');
}

export async function completeSlackNativeSetup(baseUrl, eventsUrl, setup, backend) {
  const setupPage = await fetch(`${baseUrl}/admin/setup`);
  const setupHtml = await setupPage.text();
  check(
    setupPage.status === 200 &&
      setupHtml.includes('Add Chickpea to Slack') &&
      !setupHtml.includes('Resume private setup') &&
      setupHtml.includes('/admin/setup/client.js') &&
      // The customer-owned fallback's configuration-token field is a
      // type="password" input; the legacy password sign-in it guards against
      // used a named field, not an input type.
      !/name="password"|ownerEmail|sign up/i.test(setupHtml) &&
      !setupHtml.includes(setup.capability),
    'fresh setup GET renders the real Slack stage without password or capability echo',
    `HTTP ${setupPage.status}`,
  );

  // The connect surface is public and answers before Slack setup finishes, so
  // a person can hand their coding agent one line on a fresh install. It
  // renders the deployment's own public origin: SLACK_TAG_PUBLIC_URL is pinned
  // in .dev.vars, so the guide carries PUBLIC_ORIGIN, not the loopback address
  // the smoke happens to reach the Worker on.
  const connectGuide = await fetch(`${baseUrl}/connect.md`);
  const connectGuideBody = await connectGuide.text();
  const connectPage = await fetch(`${baseUrl}/connect`);
  const connectPageBody = await connectPage.text();
  const connectConditions = {
    guide: connectGuide.status === 200,
    guideType: (connectGuide.headers.get('content-type') ?? '').startsWith('text/markdown'),
    guideMcpUrl: connectGuideBody.includes(`${PUBLIC_ORIGIN}/mcp`),
    page: connectPage.status === 200,
    pagePrompt: connectPageBody.includes(
      `Connect my coding agent to my Chickpea using ${PUBLIC_ORIGIN}/connect.md`,
    ),
  };
  check(
    Object.values(connectConditions).every(Boolean),
    'public connect surface serves the coding-agent guide and its copy prompt',
    `guide HTTP ${connectGuide.status}; page HTTP ${connectPage.status}; failed: ${
      Object.entries(connectConditions).filter(([, ok]) => !ok).map(([name]) => name).join(',') || 'none'
    }`,
  );

  const opened = await postForm(baseUrl, '/admin/setup', {
    action: 'open', capability: setup.capability, destination: '/admin/channels',
  });
  const openedHtml = await opened.text();
  check(
    opened.status === 200 && openedHtml.includes('data-primary-action="gateway-install"') &&
      openedHtml.includes('Add to Slack') &&
      openedHtml.includes('Use your own Slack app instead') &&
      openedHtml.includes('Generate an App Configuration token in Slack') &&
      openedHtml.includes('href="/admin/setup/manual"'),
    'deploy capability leads with Add to Slack and keeps both customer-owned fallbacks',
    `HTTP ${opened.status}`,
  );

  const manualOpened = await postForm(baseUrl, '/admin/setup/manual', {
    action: 'open', capability: setup.capability, destination: '/admin/onboarding',
  });
  const manualHtml = await manualOpened.text();
  const manualAsset = await fetch(`${baseUrl}/admin/assets/onboarding/create-workspace.webp`);
  const manualAssetBytes = new Uint8Array(await manualAsset.arrayBuffer());
  const manualConditions = {
    page: manualOpened.status === 200,
    create: manualHtml.includes('Create Chickpea'),
    finish: manualHtml.includes('Finish creating Chickpea'),
    events: manualHtml.includes('verify the Events URL after Slack installation'),
    credentials: manualHtml.includes('Add app credentials'),
    capabilityHidden: !manualHtml.includes(setup.capability),
    asset: manualAsset.status === 200,
    assetType: manualAsset.headers.get('content-type') === 'image/webp',
    assetRiff: new TextDecoder().decode(manualAssetBytes.slice(0, 4)) === 'RIFF',
    assetSize: manualAssetBytes.byteLength > 10_000,
  };
  check(
    Object.values(manualConditions).every(Boolean),
    'separate manual journey restores its historical screens and public screenshot assets',
    `page HTTP ${manualOpened.status}; asset HTTP ${manualAsset.status}; failed: ${
      Object.entries(manualConditions).filter(([, ok]) => !ok).map(([name]) => name).join(',') || 'none'
    }`,
  );

  const created = await postForm(baseUrl, '/admin/setup', {
    action: 'create', capability: setup.capability, destination: '/admin/channels',
    configurationToken: OAUTH_CONFIGURATION_TOKEN,
  });
  const createdHtml = await created.text();
  check(
    created.status === 200 && createdHtml.includes('Continue to Slack') &&
      !createdHtml.includes(OAUTH_CONFIGURATION_TOKEN) &&
      !createdHtml.includes(OAUTH_CLIENT_SECRET),
    'programmatic app creation records write-only app credentials and advances setup',
    `HTTP ${created.status}`,
  );
  const iconUploads = backend.callsOfMethod('apps.icon.set');
  check(
    iconUploads.length === 1 && iconUploads[0].ok === true && iconUploads[0].body.app_id === APP_ID &&
      iconUploads[0].body.file_type === 'image/png' &&
      iconUploads[0].body.file_sha256 === createHash('sha256')
        .update(readFileSync(join(REPO_ROOT, 'assets', 'bot-avatar.png'))).digest('hex'),
    'the created app gets the Chickpea logo read through the Worker ASSETS binding',
    `${iconUploads.length} apps.icon.set call(s)`,
  );

  const providerCallsBeforeInstall = backend.providerCalls().length;
  const preInstall = await postSignedEvent(eventsUrl, mentionEvent('Ev_SMOKE_PRE_INSTALL', { baseApp: true }));
  await backend.quiesce();
  check(
    preInstall.status === 200 && backend.providerCalls().length === providerCallsBeforeInstall &&
      backend.finals().length === 0,
    'app-stage signing acknowledges Slack but rejects Agent work before bot OAuth',
    `HTTP ${preInstall.status}`,
  );

  const installStart = await postForm(baseUrl, '/auth/slack/install/start', {
    capability: setup.capability, destination: '/admin/channels',
  });
  const installAuthorization = slackAuthorizationUrlFromHandoff(await installStart.text());
  const installCookie = responseCookie(installStart, '__Secure-chickpea_slack_install=');
  check(
    installStart.status === 200 && installAuthorization.origin === 'https://slack.com' &&
      Boolean(installAuthorization.searchParams.get('state')) && Boolean(installCookie),
    'bot OAuth start uses a narrow browser cookie and Slack authorization state',
    `HTTP ${installStart.status}`,
  );
  const installState = installAuthorization.searchParams.get('state') ?? '';
  const installCallback = await fetch(
    `${baseUrl}/auth/slack/install/callback?state=${encodeURIComponent(installState)}&code=bot-smoke-code`,
    { redirect: 'manual', headers: { cookie: installCookie } },
  );
  check(
    installCallback.status === 303 &&
      installCallback.headers.get('location')?.includes('slack_install=waiting_events'),
    'confidential bot exchange validates app/team/bot/scopes/directory/channel before waiting on Events',
    `HTTP ${installCallback.status} location=${installCallback.headers.get('location')}`,
  );

  const challenge = await postSignedEvent(eventsUrl, {
    type: 'url_verification', challenge: 'cf-smoke-oauth-proof',
    api_app_id: APP_ID, team_id: WORKSPACE,
  });
  check(
    challenge.status === 200 && challenge.body?.challenge === 'cf-smoke-oauth-proof',
    'a separately signed URL verification promotes only the exact OAuth candidate',
    `HTTP ${challenge.status}`,
  );
  let finalized;
  for (let attempt = 0; attempt < 8; attempt += 1) {
    await delay(500);
    finalized = await postForm(baseUrl, '/auth/slack/install/finalize', {
      capability: setup.capability, destination: '/admin/channels',
    });
    if (finalized.headers.get('location')?.includes('slack_install=bot_installed')) break;
  }
  check(
    finalized?.status === 303 && finalized.headers.get('location')?.includes('slack_install=bot_installed'),
    'exact signed Events proof finalizes the encrypted bot credential revision',
    `HTTP ${String(finalized?.status)} location=${String(finalized?.headers.get('location'))}`,
  );

  const ownerStart = await postForm(baseUrl, '/auth/slack/oidc/start', {
    purpose: 'first_owner', capability: setup.capability, destination: '/admin/channels',
  });
  const ownerAuthorization = slackAuthorizationUrlFromHandoff(await ownerStart.text());
  const ownerCookie = responseCookie(ownerStart, '__Secure-chickpea_slack_oidc=');
  const state = ownerAuthorization.searchParams.get('state') ?? '';
  const nonce = ownerAuthorization.searchParams.get('nonce') ?? '';
  check(
    ownerStart.status === 200 && ownerAuthorization.origin === 'https://slack.com' &&
      ownerAuthorization.searchParams.get('team') === WORKSPACE && Boolean(ownerCookie) &&
      state.length >= 32 && nonce.length >= 32,
    'first-Owner OIDC is exact-team and independently state/nonce/browser bound',
    `HTTP ${ownerStart.status}`,
  );
  const ownerCallback = await fetch(
    `${baseUrl}/auth/slack/oidc/callback?state=${encodeURIComponent(state)}&code=${encodeURIComponent(`oidc.${nonce}`)}`,
    { headers: { cookie: ownerCookie } },
  );
  const ownerCallbackBody = await ownerCallback.text();
  adminCookie = responseCookie(ownerCallback, 'better-auth.session_token=') ||
    responseCookie(ownerCallback, '__Secure-better-auth.session_token=');
  const callbackCookieNames = (typeof ownerCallback.headers.getSetCookie === 'function'
    ? ownerCallback.headers.getSetCookie()
    : [ownerCallback.headers.get('set-cookie') ?? ''])
    .map((value) => value.trim().split('=', 1)[0])
    .filter(Boolean)
    .join(',');
  check(
    ownerCallback.status === 200 && Boolean(adminCookie) &&
      ownerCallbackBody.includes('data-slack-auth-surface="owner-complete"'),
    'exact installer OIDC creates the first Owner and only then issues a Better Auth session',
    `HTTP ${ownerCallback.status} cookies=${callbackCookieNames || 'none'} session=${Boolean(adminCookie)} ownerPage=${ownerCallbackBody.includes('data-slack-auth-surface="owner-complete"')}`,
  );

  const unauthenticated = await fetch(`${baseUrl}/admin/api/agents`);
  check(
    unauthenticated.status === 401,
    'Admin APIs still fail closed without the Slack-established browser session',
    `HTTP ${unauthenticated.status}`,
  );
}

/**
 * Same-app Slack credential recovery through the built Worker, after the
 * app's signing secret was regenerated in Slack. URL repair
 * (apps.manifest.export/update with a configuration token) and the bot token
 * exchange (oauth.v2.access, refused like Slack for a redirect the app did not
 * register) each leave the Worker through its global fetch, which workerd
 * refuses to call as a method of another object. Slack's URL check, signed
 * with the new secret, is the Events proof finalize promotes with. Runs last:
 * the recovered bundle replaces the one the earlier checks used.
 */
async function exerciseSlackRecovery(baseUrl, backend, eventsUrl) {
  const regeneratedSecret = 'regenerated-workerd-signing-secret';
  const wireStart = backend.wireLog.length;
  const slackCalls = (prefix) => backend.wireLog.slice(wireStart)
    .filter((entry) => entry.method.startsWith(prefix)).map((entry) => `${entry.method}:${entry.ok}`);
  const begun = await postForm(baseUrl, '/admin/recovery', { action: 'begin', recoveryToken: RECOVERY_TOKEN });
  const cookie = [
    responseCookie(begun, '__Secure-chickpea_slack_recovery_browser='),
    responseCookie(begun, '__Secure-chickpea_slack_recovery='),
  ].filter(Boolean).join('; ');
  check(
    begun.status === 200 && (await begun.text()).includes('name="action" value="stage"') &&
      cookie.split('; ').length === 2,
    'the deployment recovery token opens one browser-bound repair session',
    `HTTP ${begun.status}`,
  );
  const staged = await postForm(baseUrl, '/admin/recovery', {
    action: 'stage', appId: APP_ID, teamId: WORKSPACE, clientId: OAUTH_CLIENT_ID,
    clientSecret: OAUTH_CLIENT_SECRET, signingSecret: regeneratedSecret,
    configurationToken: OAUTH_CONFIGURATION_TOKEN,
  }, cookie);
  const authorization = slackAuthorizationUrlFromHandoff(await staged.text());
  const repair = slackCalls('apps.manifest.');
  check(
    staged.status === 200 && authorization.origin === 'https://slack.com' &&
      sameArray(repair, ['apps.manifest.export:true', 'apps.manifest.update:true', 'apps.manifest.export:true']),
    'recovery URL repair reaches Slack through the Worker fetch',
    `HTTP ${staged.status}; ${repair.join(',') || 'no manifest calls'}`,
  );
  // Slack sends the browser back to the redirect recovery asked for.
  const redirect = new URL(authorization.searchParams.get('redirect_uri') ?? '', baseUrl);
  const callback = await fetch(
    `${baseUrl}${redirect.pathname}?state=${
      encodeURIComponent(authorization.searchParams.get('state') ?? '')}&code=recovery-smoke-code`,
    { headers: { cookie } },
  );
  const exchanges = slackCalls('oauth.v2.access');
  check(
    callback.status === 200 && (await callback.text()).includes('name="action" value="finalize"') &&
      sameArray(exchanges, ['oauth.v2.access:true']),
    'recovery bot token exchange reaches Slack through the Worker fetch for a redirect the app registered',
    `HTTP ${callback.status}; ${exchanges.join(',') || 'no token exchange'}`,
  );
  const forged = await postSignedEvent(eventsUrl, {
    type: 'url_verification', challenge: 'cf-smoke-forged-proof',
  }, { signingSecret: 'forged-workerd-signing-secret' });
  const proof = await postSignedEvent(eventsUrl, {
    type: 'url_verification', challenge: 'cf-smoke-recovery-proof',
  }, { signingSecret: regeneratedSecret });
  const finalized = await postForm(baseUrl, '/admin/recovery', { action: 'finalize' }, cookie);
  const finalizedHtml = await finalized.text();
  check(
    forged.status === 401 && proof.status === 200 && proof.body?.challenge === 'cf-smoke-recovery-proof' &&
      finalized.status === 200 && finalizedHtml.includes('Slack connection repaired'),
    'Slack\'s URL check signed with the regenerated secret answers (a forged one does not), and finalize promotes the repair',
    `forged HTTP ${forged.status}; proof HTTP ${proof.status}; finalize HTTP ${finalized.status}`,
  );
  const [recovered, superseded] = [
    await postSignedEvent(eventsUrl, { type: 'url_verification', challenge: 'cf-smoke-after-recovery' },
      { signingSecret: regeneratedSecret }),
    await postSignedEvent(eventsUrl, { type: 'url_verification', challenge: 'cf-smoke-after-recovery' }),
  ];
  check(
    recovered.status === 200 && recovered.body?.challenge === 'cf-smoke-after-recovery' && superseded.status === 401,
    'after recovery Slack deliveries verify with the regenerated secret, not the replaced one',
    `regenerated HTTP ${recovered.status}; replaced HTTP ${superseded.status}`,
  );
}

async function completeSlackLogin(baseUrl) {
  const start = await postForm(baseUrl, '/auth/slack/oidc/start', {
    purpose: 'login', destination: '/admin',
  });
  const authorization = slackAuthorizationUrlFromHandoff(await start.text());
  const oidcCookie = responseCookie(start, '__Secure-chickpea_slack_oidc=');
  const state = authorization.searchParams.get('state') ?? '';
  const nonce = authorization.searchParams.get('nonce') ?? '';
  if (start.status !== 200 || !oidcCookie || state.length < 32 || nonce.length < 32) {
    throw new Error(`fresh Slack login did not start (HTTP ${start.status})`);
  }
  const callback = await fetch(
    `${baseUrl}/auth/slack/oidc/callback?state=${encodeURIComponent(state)}&code=${encodeURIComponent(`oidc.${nonce}`)}`,
    { redirect: 'manual', headers: { cookie: oidcCookie } },
  );
  const session = responseCookie(callback, 'better-auth.session_token=') ||
    responseCookie(callback, '__Secure-better-auth.session_token=');
  if (callback.status !== 303 || callback.headers.get('location') !== '/admin' || !session) {
    throw new Error(`fresh Slack login did not issue a session (HTTP ${callback.status})`);
  }
  return session;
}

async function renderAdminWithWorkerdState(baseUrl, path = '/admin') {
  const html = await adminPageHtml(baseUrl, path);
  const scriptSrc = html.match(/<script src="(\/admin-ui\/admin\.js\?v=[^"]+)"><\/script>/)?.[1];
  const config = html.match(
    /<script id="chickpea-admin-config" type="application\/json">([\s\S]*?)<\/script>/,
  )?.[1];
  if (!scriptSrc || !config) {
    throw new Error('admin page did not reference its application script and config');
  }
  const scriptResponse = await fetch(`${baseUrl}${scriptSrc}`);
  if (scriptResponse.status !== 200) {
    throw new Error(`admin application script unavailable (HTTP ${scriptResponse.status})`);
  }
  const script = await scriptResponse.text();
  const app = { innerHTML: '' };
  const elements = new Map([
    ['app', app],
    ['chickpea-admin-config', { textContent: config }],
  ]);
  const listeners = {};
  const document = {
    getElementById(id) {
      if (!elements.has(id)) {
        elements.set(id, { innerHTML: '', value: '', disabled: false });
      }
      return elements.get(id);
    },
    querySelector(selector) {
      if (selector === '.main-inner') return app;
      return null;
    },
    addEventListener(type, listener) {
      listeners[type] = listener;
    },
  };
  const authenticatedFetch = (path, options = {}) => {
    const url = path.startsWith('http') ? path : `${baseUrl}${path}`;
    const method = String(options.method ?? 'GET').toUpperCase();
    const mutation = ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method);
    return fetch(url, {
      ...options,
      headers: {
        ...(adminCookie ? { cookie: adminCookie } : {}),
        ...(mutation ? { origin: baseUrl, 'sec-fetch-site': 'same-origin' } : {}),
        ...(options.headers ?? {}),
      },
    });
  };
  const location = {
    pathname: path,
    search: '',
    hash: '',
    href: `${baseUrl}${path}`,
  };
  const history = {
    pushState(_state, _title, next) {
      location.pathname = String(next).split(/[?#]/, 1)[0];
    },
    replaceState(_state, _title, next) {
      location.pathname = String(next).split(/[?#]/, 1)[0];
    },
  };
  vm.runInNewContext(
    script,
    {
      document,
      fetch: authenticatedFetch,
      console,
      URLSearchParams,
      location,
      history,
      FormData: class {
        constructor(form) {
          this.form = form;
        }
        get(name) {
          return this.form?.__formData?.[name] ?? null;
        }
      },
    },
    { filename: 'admin-workerd-inline.js' },
  );
  const timeoutMs = 5000;
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    if (
      app.innerHTML.length > 0 &&
      !app.innerHTML.includes('Loading setup&hellip;') &&
      !app.innerHTML.includes('Loading Slack setup&hellip;') &&
      !app.innerHTML.includes('aria-busy="true"')
    ) {
      return { html: app.innerHTML, listeners };
    }
    await delay(10);
  }
  throw new Error(`admin inline script did not render within ${timeoutMs}ms`);
}

/** Ready = the public setup page answers from the DO-backed store (workerd + DO up). */
export async function waitForSetupReady(handle, baseUrl, timeoutMs = 90_000) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    if (handle.child.exitCode !== null) {
      throw new Error(`wrangler dev exited early (exit ${handle.child.exitCode}):\n${handle.getOutput()}`);
    }
    try {
      const response = await fetch(`${baseUrl}/admin/setup`);
      if (response.status === 200) return;
    } catch {
      // not accepting connections yet
    }
    await delay(300);
  }
  throw new Error(`wrangler dev never exposed setup:\n${handle.getOutput()}`);
}

/** Ready after setup = the authenticated Admin API answers with the persisted session. */
async function waitForAdminReady(handle, baseUrl, timeoutMs = 90_000) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    if (handle.child.exitCode !== null) {
      throw new Error(`wrangler dev exited early (exit ${handle.child.exitCode}):\n${handle.getOutput()}`);
    }
    try {
      const { status, body } = await adminFetch(baseUrl, '/admin/api/agents');
      if (status === 200 && Array.isArray(body?.agents)) return body.agents;
    } catch {
      // not accepting connections yet
    }
    await delay(300);
  }
  throw new Error(`wrangler dev never restored the authenticated Admin API:\n${handle.getOutput()}`);
}

async function measureRepresentativeStateWrite(baseUrl) {
  const samples = [];
  for (let index = 0; index < 60; index += 1) {
    const startedAt = performance.now();
    const response = await adminFetch(baseUrl, '/admin/api/sandbox/status', {
      method: 'PUT',
      body: JSON.stringify({
        enabled: false,
        allowedHosts: ['registry.npmjs.org'],
        monthlySessionCap: index,
      }),
    });
    if (response.status !== 200) {
      throw new Error(`representative state write failed (HTTP ${response.status})`);
    }
    if (index >= 10) samples.push(performance.now() - startedAt);
  }
  samples.sort((left, right) => left - right);
  const p95 = samples[Math.ceil(samples.length * 0.95) - 1] ?? Number.POSITIVE_INFINITY;
  return { count: samples.length, p95 };
}

export function mentionEvent(eventId = 'Ev_SMOKE_MENTION_1', { baseApp = false } = {}) {
  if (!baseApp && !defaultAgentMention) throw new Error('Publish the Default Agent before sending its mention.');
  return {
    token: 'verification-token-not-a-secret',
    team_id: WORKSPACE,
    api_app_id: APP_ID,
    event_id: eventId,
    event_time: 1782770400,
    type: 'event_callback',
    event: {
      type: baseApp ? 'app_mention' : 'message',
      ...(!baseApp ? { channel_type: 'channel' } : {}),
      user: OWNER_USER_ID,
      text: `${baseApp ? `<@${BOT_USER_ID}>` : defaultAgentMention} smoke: please draft a short reply`,
      ts: MENTION_TS,
      channel: CHANNEL,
      event_ts: MENTION_TS,
    },
  };
}

function onboardingDmEvent() {
  const ts = '1782770399.000001';
  return {
    token: 'verification-token-not-a-secret',
    team_id: WORKSPACE,
    api_app_id: APP_ID,
    event_id: 'Ev_SMOKE_ONBOARDING_DM_1',
    event_time: 1782770399,
    type: 'event_callback',
    event: {
      type: 'message',
      channel_type: 'im',
      user: OWNER_USER_ID,
      text: 'Give me three useful ways you can help me.',
      ts,
      channel: ONBOARDING_DM_CHANNEL,
      event_ts: ts,
    },
  };
}

function memoryRememberEvent() {
  return {
    ...mentionEvent('Ev_SMOKE_MEMORY_1'),
    event: {
      ...mentionEvent('Ev_SMOKE_MEMORY_1').event,
      text: `${defaultAgentMention} !remember release-guidance — Use the release checklist.\nRun focused tests before release.`,
      ts: MEMORY_TS,
      event_ts: MEMORY_TS,
    },
  };
}

function aiMentionEvent() {
  const payload = mentionEvent('Ev_SMOKE_AI_PRIVACY_1', { baseApp: true });
  return {
    ...payload,
    event: {
      ...payload.event,
      text: `<@${BOT_USER_ID}> privacy smoke: answer through the Workers AI binding`,
      ts: AI_MENTION_TS,
      channel: AI_CHANNEL,
      event_ts: AI_MENTION_TS,
    },
  };
}

function geminiMentionEvent() {
  const payload = mentionEvent('Ev_SMOKE_GEMINI_1');
  return {
    ...payload,
    event: { ...payload.event, text: `${defaultAgentMention} gemini: please draft a short reply`, ts: GEMINI_MENTION_TS, event_ts: GEMINI_MENTION_TS },
  };
}

function slowMentionEvent(eventId = 'Ev_SMOKE_SLOW_1') {
  return {
    token: 'verification-token-not-a-secret',
    team_id: WORKSPACE,
    api_app_id: APP_ID,
    event_id: eventId,
    event_time: 1782771000,
    type: 'event_callback',
    event: {
      type: 'message',
      channel_type: 'channel',
      user: OWNER_USER_ID,
      text: `${defaultAgentMention} slow: take as long as you need`,
      ts: SLOW_MENTION_TS,
      channel: SLOW_CHANNEL,
      event_ts: SLOW_MENTION_TS,
    },
  };
}

export function threadReplyEvent() {
  return {
    token: 'verification-token-not-a-secret',
    team_id: WORKSPACE,
    api_app_id: APP_ID,
    event_id: 'Ev_SMOKE_REPLY_1',
    event_time: 1782770460,
    type: 'event_callback',
    event: {
      type: 'message',
      channel: CHANNEL,
      user: OWNER_USER_ID,
      text: 'smoke: continue from the prior answer',
      ts: '1782770460.000200',
      event_ts: '1782770460.000200',
      thread_ts: MENTION_TS,
      channel_type: 'channel',
    },
  };
}

export async function waitForFinalCount(backend, minFinals, timeoutMs) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    if (backend.finals().length >= minFinals) {
      return backend.finals();
    }
    await delay(150);
  }
  return backend.finals();
}

/** Onboarding completes once its reply is recorded as shown, which can trail the reply's post; the last read on timeout. */
async function waitForOnboardingComplete(baseUrl, timeoutMs = 10_000) {
  const deadline = Date.now() + timeoutMs;
  for (;;) {
    const onboarding = await adminFetch(baseUrl, '/admin/api/onboarding');
    if ((onboarding.status === 200 && onboarding.body?.stage === 'complete') || Date.now() >= deadline) return onboarding;
    await delay(250);
  }
}

async function main() {
  const args = process.argv.slice(2);
  if (args.length > 0) {
    if (args.length !== 1 || args[0] !== '--check-drain') {
      throw new Error(`unknown arguments: ${args.join(' ')}`);
    }
    await runDrainCheck({
      baseUrl: process.env.CF_SMOKE_BASE_URL,
      personalToken: process.env.CHICKPEA_PERSONAL_TOKEN,
    });
    console.log('PASS cf-smoke drain — every runtime work category is zero');
    return;
  }
  assertNodeVersion();
  const requestedProfile = resolveCloudflareDeploymentProfile();
  const buildAndVerify = (profile, options) => {
    buildCloudflareTarget(profile, options);
    console.log(`• verifying ${profile} build artifacts…`);
    verifyBuildArtifacts(profile);
    if (failures.length > 0) {
      throw new Error(`${profile} build artifacts failed verification`);
    }
  };
  if (requestedProfile === 'core') {
    // The core workerd scenario is the normal smoke target, but it cannot
    // validate the optional overlay after its own rebuild. Validate the real
    // generated Sandbox artifact first, then rebuild core for local boot.
    buildAndVerify('sandbox');
    buildAndVerify('core');
  } else {
    // An explicit Sandbox smoke retains its one-deployment-profile behavior, including
    // the documented iteration-only reuse path.
    buildAndVerify('sandbox', { reuseExisting: true });
  }
  const setup = await mintSetupCapability();
  writeSmokeWranglerConfigs(setup);

  // Fresh local DO state every run: the seeding + dedupe assertions assume a
  // first-boot Durable Object.
  applyLocalAuthMigrations();

  const { FakeSlackBackend, FAKE_PROVIDER_KEYS, STUB_REPLY_MARKER } = await loadFake();
  const { publicKey, privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });
  const publicJwk = {
    ...publicKey.export({ format: 'jwk' }),
    kid: 'cf-smoke-rs256', alg: 'RS256', use: 'sig',
  };
  // The fake provides the exact confidential bot/OIDC exchanges plus the
  // directory/channel truth checks consumed by the built Worker.
  const backend = new FakeSlackBackend({
    slack: {
      identity: {
        appId: APP_ID,
        botUserId: BOT_USER_ID,
        teamId: WORKSPACE,
        teamName: 'Smoke Workspace',
      },
      oauth: {
        appId: APP_ID,
        clientId: OAUTH_CLIENT_ID,
        clientSecret: OAUTH_CLIENT_SECRET,
        configurationToken: OAUTH_CONFIGURATION_TOKEN,
        signingSecret: SIGNING_SECRET,
        botToken: OAUTH_BOT_TOKEN,
        installerUserId: OWNER_USER_ID,
        privateKeyPem: privateKey.export({ format: 'pem', type: 'pkcs8' }),
        publicJwk,
      },
      channels: [
        { id: CHANNEL, name: 'smoke-mentions', isMember: true, teamId: WORKSPACE },
        { id: AI_CHANNEL, name: 'smoke-workers-ai', isMember: true, teamId: WORKSPACE },
        { id: SLOW_CHANNEL, name: 'smoke-slow', isMember: true, teamId: WORKSPACE },
        { id: 'C0SMOKEEXTRA', name: 'general', isMember: false, teamId: WORKSPACE },
      ],
      channelMembers: {
        [CHANNEL]: [OWNER_USER_ID, BOT_USER_ID],
        [AI_CHANNEL]: [OWNER_USER_ID, BOT_USER_ID],
        [SLOW_CHANNEL]: [OWNER_USER_ID, BOT_USER_ID],
      },
      workspaceUsers: [
        { id: OWNER_USER_ID, teamId: WORKSPACE },
        { id: BOT_USER_ID, teamId: WORKSPACE, isBot: true, isAppUser: true },
      ],
      directMessages: { [OWNER_USER_ID]: ONBOARDING_DM_CHANNEL },
      // A transient welcome-DM failure must not hold new turns behind the
      // receipt outbox's exponential-backoff alarm. Restored after that probe.
      conversationsOpenError: 'internal_error',
    },
  });
  const fakePort = await getFreePort();
  const fake = await backend.listen(fakePort);
  console.log(`• fake Slack + provider backend on ${fake.url}`);
  writeDevVars(fake.url);

  const baseUrl = `http://127.0.0.1:${PORT}`;
  const eventsUrl = `${baseUrl}${EVENTS_PATH}`;
  let wrangler = spawnWranglerDev();
  const previousWorkerOutputs = [];

  try {
    console.log('• waiting for wrangler dev (round 1)…');
    await waitForSetupReady(wrangler, baseUrl);
    const { PUBLIC_ASSET_PATHS } = await loadTsModule('src/assets/public-assets.ts');
    for (const assetPath of PUBLIC_ASSET_PATHS) {
      const response = await fetch(`${baseUrl}/${assetPath}`);
      check(response.status === 200 &&
        Buffer.from(await response.arrayBuffer()).equals(readFileSync(join(REPO_ROOT, 'assets', assetPath))),
      `Cloudflare static asset preserves ${assetPath}`);
    }
    const onboardingImage = await fetch(`${baseUrl}/admin/assets/onboarding/ready.webp`);
    check(onboardingImage.status === 200 &&
      Buffer.from(await onboardingImage.arrayBuffer()).equals(readFileSync(join(REPO_ROOT, 'assets/onboarding/ready.webp'))),
    'Worker ASSETS binding preserves the legacy onboarding image URL');
    await completeSlackNativeSetup(baseUrl, eventsUrl, setup, backend);
    const agentsResult = await adminFetch(baseUrl, '/admin/api/agents');
    if (agentsResult.status !== 200 || !Array.isArray(agentsResult.body?.agents)) {
      throw new Error(`authenticated Admin API did not become ready (HTTP ${agentsResult.status})`);
    }
    const seededAgentIds = agentsResult.body.agents.map((agent) => agent.id).sort();
    check(
      seededAgentIds.length === 0,
      'DO-backed config store seeds no user Agent on a fresh install',
      seededAgentIds.join(',') || 'none',
    );
    const workspaceDefault = await adminFetch(baseUrl, '/admin/api/workspace-model-default');
    check(
      workspaceDefault.status === 200 &&
        workspaceDefault.body?.workspaceDefault?.modelId === 'cloudflare/@cf/zai-org/glm-4.7-flash',
      'Cloudflare install bootstraps the keyless Workers AI Workspace default',
      `HTTP ${workspaceDefault.status} ${String(workspaceDefault.body?.workspaceDefault?.modelId)}`,
    );
    // The remaining cases drive one ordinary user Agent through the real
    // Admin API, standing in for the first teammate a person creates.
    const defaultCreate = await adminFetch(baseUrl, '/admin/api/agents', {
      method: 'POST',
      body: JSON.stringify({
        id: 'agent_default',
        name: 'Sprout',
        instructions: 'Answer only from the CF smoke gate fixture.',
        enabled: true,
        model: 'cloudflare/@cf/zai-org/glm-4.7-flash',
      }),
    });
    check(
      defaultCreate.status === 201 && defaultCreate.body?.agent?.id === 'agent_default',
      'smoke default Agent created through the DO-backed Admin API',
      `HTTP ${defaultCreate.status}`,
    );
    const defaultAgent = defaultCreate.body?.agent;

    const stateWrite = await measureRepresentativeStateWrite(baseUrl);
    check(
      stateWrite.p95 <= USAGE_PRE_DELIVERY_BUDGET_MS,
      'representative Worker → TagStateStore transaction stays inside the usage write budget',
      `p95=${stateWrite.p95.toFixed(2)}ms n=${stateWrite.count} budget=${USAGE_PRE_DELIVERY_BUDGET_MS}ms`,
    );
    const usageSummary = await adminFetch(
      baseUrl,
      `/admin/api/usage/summary?from=${Date.now() - 60_000}&to=${Date.now() + 60_000}`,
    );
    check(
      usageSummary.status === 200 && usageSummary.body?.totals?.operationCount === 0,
      'Usage summary queries the initialized TagStateStore ledger',
      `HTTP ${usageSummary.status} operations=${String(usageSummary.body?.totals?.operationCount)}`,
    );
    const drainStatus = await runDrainCheck({ baseUrl, sessionCookie: adminCookie });
    check(
      drainStatus.drained,
      'runtime drain endpoint reaches the initialized TagStateStore aggregate',
      JSON.stringify(drainStatus.categories),
    );

    const wireBeforeHeartbeat = backend.wireLog.length;
    const heartbeat = await fetch(`${baseUrl}/cdn-cgi/handler/scheduled?cron=*+*+*+*+*`);
    await delay(100);
    const scheduledWork = await adminFetch(baseUrl, '/admin/api/audit/scheduled_work/routines');
    check(
      heartbeat.status === 200 && backend.wireLog.length === wireBeforeHeartbeat,
      'empty permanent heartbeat performs no Slack or model work',
      `HTTP ${heartbeat.status} wireDelta=${backend.wireLog.length - wireBeforeHeartbeat}`,
    );
    check(
      scheduledWork.status === 200 &&
        scheduledWork.body?.capability?.reason === 'enabled' &&
        scheduledWork.body?.capability?.enabled === true &&
        Array.isArray(scheduledWork.body?.routines) &&
        scheduledWork.body.routines.length === 0,
      'Scheduled Work reports the Cloudflare capability as permanently enabled',
      `HTTP ${scheduledWork.status} reason=${String(scheduledWork.body?.capability?.reason)}`,
    );

    // --- Slack-native first Owner state ------------------------------------

    const team = await adminFetch(baseUrl, '/admin/api/team');
    check(
      team.status === 200 && !('soleOwnerWarning' in (team.body ?? {})) &&
        team.body?.members?.length === 1 && team.body?.members?.[0]?.slackUserId === OWNER_USER_ID,
      'first OIDC admission creates one exact Owner without obsolete enrollment state',
      `HTTP ${team.status} members=${String(team.body?.members?.length)}`,
    );
    const connectedAdmin = await renderAdminWithWorkerdState(baseUrl, '/admin/onboarding');
    check(
      connectedAdmin.html.includes('Choose your model provider') &&
        connectedAdmin.html.includes('data-action="onboarding-provider-continue"') &&
        !connectedAdmin.html.includes('Choose where Chickpea should start'),
      'fresh Slack-native onboarding resumes at provider selection without a channel picker',
    );
    check(
      connectedAdmin.html.length > 0 &&
        !/password|sign up|forgot/i.test(connectedAdmin.html),
      'authenticated onboarding exposes no password-era affordance',
    );

    // --- Settings/model-provider screen APIs --------------------------------

    // The hosted model catalog is fetched live from GitHub, so pin this
    // workerd to the bundled catalog and derive the expected merge from it.
    const catalogMode = await adminFetch(baseUrl, '/admin/api/model-catalog/mode', {
      method: 'PUT',
      body: JSON.stringify({ mode: 'bundled' }),
    });
    check(
      catalogMode.status === 200 &&
        catalogMode.body?.refresh?.status === 'bundled' &&
        catalogMode.body?.catalog?.source === 'bundled',
      'model catalog mode PUT pins workerd to the bundled catalog',
      `HTTP ${catalogMode.status} ${JSON.stringify(catalogMode.body?.catalog ?? {})}`,
    );
    const { BUNDLED_MODEL_CATALOG } = await loadTsModule('src/model-catalog/bundled.ts');
    const expectedProviderModels = (provider, lane, fakeModelIds) => {
      const catalogIds = BUNDLED_MODEL_CATALOG
        .filter((entry) => entry.lanes[lane])
        .map((entry) => entry.id.slice(`${provider}/`.length));
      return {
        catalogCount: catalogIds.length,
        overlap: fakeModelIds.filter((id) => catalogIds.includes(id)).length,
        modelCount: new Set([...fakeModelIds, ...catalogIds]).size,
      };
    };
    // Mirrors the fake /v1/models bodies in tests/parity/fake-slack.ts after
    // provider-models.ts drops OpenAI's non-chat models.
    const expectedAnthropic = expectedProviderModels(
      'anthropic',
      'anthropic_api_key',
      ['claude-sonnet-4-6', 'claude-haiku-4-5'],
    );
    const expectedOpenAi = expectedProviderModels(
      'openai',
      'openai_api_key',
      ['gpt-4.1', 'gpt-4.1-mini'],
    );
    for (const [provider, key] of Object.entries(FAKE_PROVIDER_KEYS)) {
      const savedProvider = await adminFetch(baseUrl, `/admin/api/providers/${provider}/key`, {
        method: 'POST',
        body: JSON.stringify({ key }),
      });
      check(
        savedProvider.status === 200 && savedProvider.body?.provider?.status === 'stored',
        `provider-key save validated and stored ${provider}`,
        `HTTP ${savedProvider.status} ${savedProvider.body?.provider?.status ?? ''}`,
      );
    }
    const providers = await adminFetch(baseUrl, '/admin/api/providers');
    const providerSummaries = Object.fromEntries(
      (providers.body?.providers ?? []).map((provider) => [provider.id, provider]),
    );
    check(
      expectedAnthropic.overlap === 0 &&
        providerSummaries.anthropic?.status === 'stored' &&
        providerSummaries.anthropic?.modelCount === expectedAnthropic.modelCount,
      `providers GET combines two fake Anthropic models with ${expectedAnthropic.catalogCount} bundled catalog models`,
      `${JSON.stringify(providerSummaries.anthropic)} expected=${expectedAnthropic.modelCount}`,
    );
    check(
      expectedOpenAi.overlap === 0 &&
        providerSummaries.openai?.status === 'stored' &&
        providerSummaries.openai?.modelCount === expectedOpenAi.modelCount,
      `providers GET combines two fake OpenAI models with ${expectedOpenAi.catalogCount} bundled catalog models`,
      `${JSON.stringify(providerSummaries.openai)} expected=${expectedOpenAi.modelCount}`,
    );
    check(
      providerSummaries.google?.status === 'stored' && providerSummaries.google?.modelCount === 3,
      'providers GET lists the three reviewed Gemini models after the key check',
      JSON.stringify(providerSummaries.google),
    );
    check(
      providerSummaries.openai?.subscriptionAvailable === true && providerSummaries.openai?.subscriptionProtocol === 'chatgpt-plan',
      'workerd advertises the official ChatGPT plan connection',
    );
    for (const action of ['start', 'poll', 'confirm-account']) {
      const rejected = await adminFetch(baseUrl, `/admin/api/providers/openai/subscription/${action}`, {
        method: 'POST',
        body: JSON.stringify(action === 'start' ? {} : { attemptCapability: 'synthetic-workerd-attempt-capability' }),
      });
      check(
        rejected.status === 409 && rejected.body?.error === 'unsupported_runtime',
        `workerd rejects subscription ${action}`,
        `HTTP ${rejected.status} ${rejected.body?.error ?? ''}`,
      );
    }
    const subscriptionSelection = await adminFetch(baseUrl, '/admin/api/providers/openai/auth-method', {
      method: 'PUT',
      body: JSON.stringify({ method: 'subscription' }),
    });
    check(
      subscriptionSelection.status === 409 && subscriptionSelection.body?.error === 'openai_subscription_missing',
      'workerd requires a connected ChatGPT account before subscription selection',
    );
    const imageModels = await adminFetch(baseUrl, '/admin/api/image-models');
    const imageModelIds = (imageModels.body?.models ?? []).map((model) => model.id);
    check(
      imageModels.status === 200 &&
        sameArray(imageModelIds, [
          'openai/gpt-image-2.6-flare',
          'openai/gpt-image-2.6-sunburst',
          'openai/gpt-image-2.5-flare',
          'openai/gpt-image-2.5-sunburst',
        ]),
      'workerd image catalog excludes ChatGPT Image even with an OpenAI API key configured',
      `HTTP ${imageModels.status} ${JSON.stringify(imageModelIds)}`,
    );
    const subscriptionImageSelection = await adminFetch(
      baseUrl,
      '/admin/api/workspace-model-roles/image',
      {
        method: 'PUT',
        body: JSON.stringify({ modelId: 'openai/chatgpt-image', expectedRevision: 0 }),
      },
    );
    check(
      subscriptionImageSelection.status === 400 &&
        subscriptionImageSelection.body?.error === 'invalid_request' &&
        subscriptionImageSelection.body?.message ===
          'openai/chatgpt-image is not available on this installation.',
      'workerd rejects ChatGPT Image selection even with an OpenAI API key configured',
      `HTTP ${subscriptionImageSelection.status} ${subscriptionImageSelection.body?.error ?? ''}`,
    );
    check(
      providerSummaries.openrouter?.status === 'stored' && providerSummaries.openrouter?.modelCount === 2,
      'providers GET reports OpenRouter key stored with two fake models',
      JSON.stringify(providerSummaries.openrouter),
    );

    const seededWorkersFavorites = await adminFetch(baseUrl, '/admin/api/providers/workers-ai/favorites');
    const expectedWorkersSeed = [
      '@cf/zai-org/glm-4.7-flash',
      '@cf/zai-org/glm-5.3-flash',
      '@cf/openai/gpt-oss-120b',
      '@cf/meta/llama-4-scout-17b-16e-instruct',
    ];
    check(
      seededWorkersFavorites.status === 200 &&
        sameArray(seededWorkersFavorites.body?.favorites, expectedWorkersSeed),
      'Workers AI favorites GET seeds the four default picker models',
      JSON.stringify(seededWorkersFavorites.body?.favorites),
    );
    const nextWorkersFavorites = ['@cf/zai-org/glm-5.2', '@cf/moonshotai/kimi-k2.7-code'];
    const savedWorkersFavorites = await adminFetch(baseUrl, '/admin/api/providers/workers-ai/favorites', {
      method: 'PUT',
      body: JSON.stringify({ favorites: nextWorkersFavorites }),
    });
    const roundTripWorkersFavorites = await adminFetch(baseUrl, '/admin/api/providers/workers-ai/favorites');
    check(
      savedWorkersFavorites.status === 200 &&
        sameArray(roundTripWorkersFavorites.body?.favorites, nextWorkersFavorites),
      'Workers AI favorites PUT/GET round-trips curated models',
      JSON.stringify(roundTripWorkersFavorites.body?.favorites),
    );
    const nextOpenRouterFavorites = ['anthropic/claude-sonnet-4', 'meta-llama/llama-3.3-70b-instruct'];
    const savedOpenRouterFavorites = await adminFetch(baseUrl, '/admin/api/providers/openrouter/favorites', {
      method: 'PUT',
      body: JSON.stringify({ favorites: nextOpenRouterFavorites }),
    });
    const roundTripOpenRouterFavorites = await adminFetch(baseUrl, '/admin/api/providers/openrouter/favorites');
    check(
      savedOpenRouterFavorites.status === 200 &&
        sameArray(roundTripOpenRouterFavorites.body?.favorites, nextOpenRouterFavorites),
      'OpenRouter favorites PUT/GET round-trips curated models',
      JSON.stringify(roundTripOpenRouterFavorites.body?.favorites),
    );

    const smokeConnections = [
      {
        id: 'linear-mcp',
        displayName: 'Linear smoke',
        url: 'https://mcp.example.com/linear',
        transport: 'streamable-http',
        authMode: 'bearer',
        headerNames: ['X-Linear-Key'],
        enabled: true,
        lifecycleStatus: 'ready',
        statusText: '',
        discoveredTools: [],
        allowedTools: [],
      },
      {
        id: 'github-mcp',
        displayName: 'GitHub smoke',
        url: 'https://mcp.example.com/github',
        transport: 'streamable-http',
        authMode: 'bearer',
        headerNames: ['X-GitHub-Key'],
        enabled: true,
        lifecycleStatus: 'ready',
        statusText: '',
        discoveredTools: [],
        allowedTools: [],
      },
    ];
    const smokeAgent = {
      id: 'agent_cf_smoke',
      name: 'CF Smoke Agent',
      instructions: 'Answer only from the CF smoke gate fixture.',
      enabled: true,
      model: 'anthropic/claude-sonnet-4-6',
      mcpServers: smokeConnections,
    };
    const agentCreate = await adminFetch(baseUrl, '/admin/api/agents', {
      method: 'POST',
      body: JSON.stringify(smokeAgent),
    });
    check(
      agentCreate.status === 201 &&
        agentCreate.body?.agent?.id === 'agent_cf_smoke' &&
        agentCreate.body?.agent?.model === 'anthropic/claude-sonnet-4-6',
      'Agent create endpoint saves an explicit model pin',
      `HTTP ${agentCreate.status}`,
    );
    const createdAgent = await adminFetch(baseUrl, '/admin/api/agents/agent_cf_smoke');
    check(
      createdAgent.status === 200 &&
        createdAgent.body?.agent?.model === 'anthropic/claude-sonnet-4-6',
      'Agent create round-trips through the Agent GET endpoint',
      `HTTP ${createdAgent.status}`,
    );

    // Two writes in parallel exercise the atomic settings-set merge through a
    // real Durable Object RPC. Delete + recreate then probes both sources: if
    // either merge entry were lost, its old credential would still read stored.
    const [linearSecrets, githubSecrets] = await Promise.all([
      adminFetch(baseUrl, '/admin/api/agents/agent_cf_smoke/mcp/secrets/linear-mcp', {
        method: 'PUT',
        body: JSON.stringify({
          expectedRevision: createdAgent.body?.agent?.revision,
          expectedCredentialBinding: createdAgent.body?.agent?.mcpServers?.find(
            (connection) => connection.id === 'linear-mcp',
          )?.credentialBinding,
          bearerToken: 'linear-smoke-token',
          headers: { 'X-Linear-Key': 'linear-smoke-key' },
          headerNames: ['X-Linear-Key'],
        }),
      }),
      adminFetch(baseUrl, '/admin/api/agents/agent_cf_smoke/mcp/secrets/github-mcp', {
        method: 'PUT',
        body: JSON.stringify({
          expectedRevision: createdAgent.body?.agent?.revision,
          expectedCredentialBinding: createdAgent.body?.agent?.mcpServers?.find(
            (connection) => connection.id === 'github-mcp',
          )?.credentialBinding,
          bearerToken: 'github-smoke-token',
          headers: { 'X-GitHub-Key': 'github-smoke-key' },
          headerNames: ['X-GitHub-Key'],
        }),
      }),
    ]);
    check(
      linearSecrets.status === 200 && githubSecrets.status === 200,
      'parallel MCP secret writes complete through the DO settings RPC',
      `HTTP ${linearSecrets.status}/${githubSecrets.status}`,
    );
    const deleteSmokeAgent = await adminFetch(
      baseUrl,
      '/admin/api/agents/agent_cf_smoke',
      {
        method: 'DELETE',
        body: JSON.stringify({
          expectedRevision: createdAgent.body?.agent?.revision,
          credentialConfigurationBinding:
            createdAgent.body?.agent?.credentialConfigurationBinding,
        }),
      },
    );
    check(
      deleteSmokeAgent.status === 204,
      'Agent deletion consumes the durable MCP secret inventory',
      `HTTP ${deleteSmokeAgent.status}`,
    );
    const recreateSmokeAgent = await adminFetch(baseUrl, '/admin/api/agents', {
      method: 'POST',
      body: JSON.stringify(smokeAgent),
    });
    const [linearSources, githubSources] = await Promise.all([
      adminFetch(baseUrl, '/admin/api/agents/agent_cf_smoke/mcp/secrets/linear-mcp', {
        method: 'PUT',
        body: JSON.stringify({
          expectedRevision: recreateSmokeAgent.body?.agent?.revision,
          expectedCredentialBinding: recreateSmokeAgent.body?.agent?.mcpServers?.find(
            (connection) => connection.id === 'linear-mcp',
          )?.credentialBinding,
          headerNames: ['X-Linear-Key'],
        }),
      }),
      adminFetch(baseUrl, '/admin/api/agents/agent_cf_smoke/mcp/secrets/github-mcp', {
        method: 'PUT',
        body: JSON.stringify({
          expectedRevision: recreateSmokeAgent.body?.agent?.revision,
          expectedCredentialBinding: recreateSmokeAgent.body?.agent?.mcpServers?.find(
            (connection) => connection.id === 'github-mcp',
          )?.credentialBinding,
          headerNames: ['X-GitHub-Key'],
        }),
      }),
    ]);
    check(
      recreateSmokeAgent.status === 201 &&
        linearSources.body?.bearer === 'missing' &&
        linearSources.body?.headers?.['X-Linear-Key'] === 'missing' &&
        githubSources.body?.bearer === 'missing' &&
        githubSources.body?.headers?.['X-GitHub-Key'] === 'missing',
      'Agent deletion cleared both parallel MCP credential scopes',
      `HTTP ${recreateSmokeAgent.status}/${linearSources.status}/${githubSources.status}`,
    );
    const cleanupSmokeAgent = await adminFetch(
      baseUrl,
      '/admin/api/agents/agent_cf_smoke',
      {
        method: 'DELETE',
        body: JSON.stringify({
          expectedRevision: recreateSmokeAgent.body?.agent?.revision,
          credentialConfigurationBinding:
            recreateSmokeAgent.body?.agent?.credentialConfigurationBinding,
        }),
      },
    );
    check(
      cleanupSmokeAgent.status === 204,
      'recreated MCP smoke Agent cleans up',
      `HTTP ${cleanupSmokeAgent.status}`,
    );

    // --- Add-channel proxy: server-side conversations.list through workerd ---
    const channels = await adminFetch(baseUrl, '/admin/api/slack-channels');
    check(channels.status === 200, 'slack-channels proxy served', `HTTP ${channels.status}`);
    const channelIds = (channels.body?.channels ?? []).map((channel) => channel.id);
    check(
      channelIds.includes(CHANNEL) && channelIds.includes(SLOW_CHANNEL),
      'slack-channels proxy returns the fake fixture channels',
      channelIds.join(','),
    );
    check(
      channels.body?.teamId === WORKSPACE,
      'slack-channels proxy reports the connected team id',
      String(channels.body?.teamId),
    );

    // --- Turn flow, verifying against the STORED signing secret ------------

    // A channel whose workspace does NOT match the connected team is rejected
    // at the API — the exact miss that let a wrong-workspace channel through.
    const mismatch = await adminFetch(baseUrl, '/admin/api/agents/agent_default/channels', {
      method: 'POST',
      body: JSON.stringify({
        workspaceId: 'T0WRONG',
        channelId: CHANNEL,
      }),
    });
    check(
      mismatch.status === 403 && mismatch.body?.error === 'forbidden',
      'mismatched-workspace Agent publication is forbidden',
      `HTTP ${mismatch.status} ${mismatch.body?.error ?? ''}`,
    );

    const put = await adminFetch(baseUrl, '/admin/api/agents/agent_default/channels', {
      method: 'POST',
      body: JSON.stringify({
        workspaceId: WORKSPACE,
        channelId: CHANNEL,
      }),
    });
    check(
      put.status === 201 && put.body?.grant?.status === 'active',
      'Agent publication created the active Channel grant and Slack handle',
      `HTTP ${put.status}`,
    );
    const userGroupId = put.body?.agent?.slackPresence?.userGroupId;
    if (typeof userGroupId !== 'string' || !/^S[A-Z0-9]+$/.test(userGroupId)) {
      throw new Error('Published Default Agent has no valid Slack handle.');
    }
    defaultAgentMention = `<!subteam^${userGroupId}>`;
    const onboardingBeforeProvider = await adminFetch(baseUrl, '/admin/api/onboarding');
    check(
      onboardingBeforeProvider.status === 200 && onboardingBeforeProvider.body?.stage === 'choose_provider',
      'onboarding resumes at provider selection after Slack connects',
      `HTTP ${onboardingBeforeProvider.status} stage=${String(onboardingBeforeProvider.body?.stage)}`,
    );
    const onboardingBeforeTry = await adminFetch(baseUrl, '/admin/api/onboarding/provider', {
      method: 'POST',
      body: JSON.stringify({
        expectedRevision: onboardingBeforeProvider.body?.revision,
        providerId: 'cloudflare',
      }),
    });
    check(
      onboardingBeforeTry.status === 200 && onboardingBeforeTry.body?.stage === 'choose_model',
      'provider selection advances onboarding to model selection',
      `HTTP ${onboardingBeforeTry.status} stage=${String(onboardingBeforeTry.body?.stage)}`,
    );
    const onboardingWorkspaceDefault = await adminFetch(baseUrl, '/admin/api/workspace-model-default');
    const onboardingTry = await adminFetch(baseUrl, '/admin/api/onboarding/try', {
      method: 'POST',
      body: JSON.stringify({
        expectedRevision: onboardingBeforeTry.body?.revision,
        modelId: 'cloudflare/@cf/zai-org/glm-4.7-flash',
        expectedDefaultRevision: onboardingWorkspaceDefault.body?.workspaceDefault?.revision,
      }),
    });
    check(
      onboardingTry.status === 200 &&
        onboardingTry.body?.stage === 'try' &&
        onboardingTry.body?.agentId === 'agent_chickpea' &&
        onboardingTry.body?.slackAppId === APP_ID,
      'model selection activates Chickpea and advances onboarding to its Slack DM',
      `HTTP ${onboardingTry.status} stage=${String(onboardingTry.body?.stage)}`,
    );
    const onboardingDmAdmission = await postSignedEvent(eventsUrl, onboardingDmEvent());
    check(
      onboardingDmAdmission.status === 200 || onboardingDmAdmission.status === 202,
      'plain installer DM admitted without an @Chickpea mention',
      `HTTP ${onboardingDmAdmission.status}`,
    );
    const onboardingFinals = await waitForFinalCount(backend, 1, 90_000);
    check(
      onboardingFinals.some((final) => final.channel === ONBOARDING_DM_CHANNEL),
      'Chickpea delivered the onboarding reply in the installer DM',
    );
    const completedOnboarding = await waitForOnboardingComplete(baseUrl);
    check(
      completedOnboarding.status === 200 && completedOnboarding.body?.stage === 'complete',
      'a delivered installer DM completes onboarding',
      `HTTP ${completedOnboarding.status} stage=${String(completedOnboarding.body?.stage)}`,
    );
    backend.reset();

    // Signature is enforced from the WIZARD-STORED secret: tampered → rejected.
    const tampered = await postSignedEvent(eventsUrl, mentionEvent('Ev_SMOKE_TAMPERED'), {
      tamper: true,
    });
    check(
      tampered.status === 401 || tampered.status === 400 || tampered.status === 403,
      'tampered signature is rejected (stored secret enforced)',
      `HTTP ${tampered.status}`,
    );

    // Before the local-stub repin, exercise the seeded model through the real
    // built entry and its ambient env.AI registration. The smoke-only binding
    // rejects any non-undefined `gateway` option, so a removed or overwritten
    // `gateway:false` registration produces a provider-failure final instead.
    const aiPut = await adminFetch(baseUrl, '/admin/api/agents/agent_default/channels', {
      method: 'POST',
      body: JSON.stringify({
        workspaceId: WORKSPACE,
        channelId: AI_CHANNEL,
      }),
    });
    check(
      aiPut.status === 201 && aiPut.body?.grant?.status === 'active',
      'Agent publication granted the Workers AI smoke Channel',
      `HTTP ${aiPut.status}`,
    );
    const aiAdmission = await postSignedEvent(eventsUrl, aiMentionEvent());
    check(
      aiAdmission.status === 200 || aiAdmission.status === 202,
      'seeded Workers AI mention admitted',
      `HTTP ${aiAdmission.status}`,
    );
    const aiFinals = await waitForFinalCount(backend, 1, 90_000);
    const aiFinal = aiFinals.find((final) => final.channel === AI_CHANNEL);
    const aiBindingProofPassed = Boolean(aiFinal?.text.includes(AI_SMOKE_REPLY));
    check(
      aiBindingProofPassed,
      'built Cloudflare entry resolves env.AI without a default gateway',
      aiFinal?.text ?? 'no Workers AI final',
    );
    const canarySessions = await adminFetch(baseUrl, '/admin/api/sessions?limit=10');
    const canaryRunId = canarySessions.body?.items?.find(
      (item) => item.adapterKind === 'slack' && item.status === 'settled',
    )?.runId;
    const canaryDetail = canaryRunId
      ? await adminFetch(baseUrl, `/admin/api/sessions/${encodeURIComponent(canaryRunId)}`)
      : { status: 0, body: undefined };
    check(
      canarySessions.status === 200 &&
        canaryDetail.status === 200 &&
        canaryDetail.body?.session?.executionAuthority === 'ledger' &&
        canaryDetail.body?.session?.deliveryStatus === 'delivered' &&
        canaryDetail.body?.executions?.length === 1,
      'exact-channel workerd canary executes and settles through ledger authority',
      `list=${canarySessions.status} detail=${canaryDetail.status} authority=${String(canaryDetail.body?.session?.executionAuthority)}`,
    );
    const diagnosticDetail = canaryRunId
      ? await adminFetch(baseUrl, `/admin/api/sessions/${encodeURIComponent(canaryRunId)}?diagnostics=1`)
      : { status: 0, body: undefined };
    const submissionRef = diagnosticDetail.body?.executions?.[0]?.flueSubmissionRef;
    check(
      diagnosticDetail.status === 200 &&
        diagnosticDetail.body?.schemaVersion === 'chickpea-request-diagnostics/v1' &&
        !Object.hasOwn(diagnosticDetail.body, 'content') &&
        /^fluesubmission_[a-f0-9]{40}$/.test(submissionRef ?? '') &&
        new RegExp(`run\\.correlation[\\s\\S]{0,500}${submissionRef}`).test(wrangler.getOutput()),
      'built workerd emits the same opaque submission reference exposed by Sessions diagnostics',
      `diagnostics=${diagnosticDetail.status}`,
    );
    if (!aiBindingProofPassed) {
      throw new Error('Workers AI binding privacy proof failed');
    }
    backend.reset();

    // The remaining durability cases stay on the HTTP fake provider. This
    // model edit still goes through the real admin API and DO-backed store.
    const patch = await adminFetch(baseUrl, '/admin/api/agents/agent_default', {
      method: 'PATCH',
      body: JSON.stringify({
        expectedRevision: aiPut.body?.agent?.revision ?? defaultAgent.revision,
        model: 'local-stub/smoke-model',
      }),
    });
    check(patch.status === 200, 'admin PATCH pinned the agent model', `HTTP ${patch.status}`);

    // Observe a fresh third-or-later failed receipt delivery. Its next retry
    // is at least 20 seconds away, longer than the new-turn budget below.
    const retryLogOffset = wrangler.getOutput().length;
    const retryDeadline = Date.now() + 90_000;
    let sawDeferredReceipt = false;
    while (Date.now() < retryDeadline) {
      const attempts = [...wrangler.getOutput().slice(retryLogOffset).matchAll(
        /receipt delivery failed[^\n]*"attempt":(\d+)[^\n]*"terminal":false[^\n]*"failureCode":"internal_error"/g,
      )];
      sawDeferredReceipt = attempts.some((match) => Number(match[1]) >= 3);
      if (sawDeferredReceipt) break;
      await delay(100);
    }
    check(sawDeferredReceipt, 'transient welcome failure armed a later receipt retry');
    if (!sawDeferredReceipt) throw new Error('could not establish the receipt retry regression precondition');
    await backend.quiesce(250, 2000);

    // Address the published Default Agent, not the base app. After onboarding,
    // a base-app mention targets Chickpea management, which has its own model
    // and intentionally does not expose a user Agent's memory.
    const turnStartedAt = Date.now();
    const admission = await postSignedEvent(eventsUrl, mentionEvent());
    check(
      admission.status === 200 || admission.status === 202,
      'signed Default Agent mention admitted',
      `HTTP ${admission.status}`,
    );
    const finals = await waitForFinalCount(backend, 1, 10_000);
    const turnWallTimeMs = Date.now() - turnStartedAt;
    check(finals.length === 1 && turnWallTimeMs < 10_000,
      'new turn does not wait behind the welcome receipt retry', `${turnWallTimeMs}ms`);
    backend.configure({ slack: { conversationsOpenError: null } });
    check(finals.length === 1, 'turn delivered exactly one final', `${finals.length} finals`);
    check(
      Boolean(finals[0]?.text.includes(STUB_REPLY_MARKER)),
      'final carries the stub provider reply',
      finals[0]?.text ?? 'no final',
    );
    check(finals[0]?.channel === CHANNEL, 'final landed in the mention channel');
    console.log(`• measured turn wall-time: ${turnWallTimeMs}ms (signed POST → final on the wire)`);

    // Dedupe: the identical event (same event_id, same channel:ts) must not
    // produce a second final. quiesce() lets any wrongly-admitted turn surface.
    const redelivery = await postSignedEvent(eventsUrl, mentionEvent());
    check(
      redelivery.status === 200 || redelivery.status === 202,
      'identical redelivery acked',
      `HTTP ${redelivery.status}`,
    );
    await backend.quiesce(1500, 15_000);
    check(
      backend.finals().length === 1,
      'identical redelivery deduped by the DO claim store',
      `${backend.finals().length} finals`,
    );

    const memoryAdmission = await postSignedEvent(eventsUrl, memoryRememberEvent());
    check(
      memoryAdmission.status === 200 || memoryAdmission.status === 202,
      'explicit Memory command admitted on workerd',
      `HTTP ${memoryAdmission.status}`,
    );
    const memoryFinals = await waitForFinalCount(backend, 2, 90_000);
    check(
      memoryFinals.length === 2 && Boolean(memoryFinals[1]?.text.includes('Saved Agent memory (revision 1).')),
      'explicit Memory command persisted to the Agent memory and returned a receipt',
      memoryFinals[1]?.text ?? 'no memory receipt',
    );
    const memoryPath = '/admin/api/agents/agent_default/memory';
    const agentMemory = await adminFetch(baseUrl, memoryPath);
    check(
      agentMemory.status === 200 && agentMemory.body?.memory?.agentId === 'agent_default' &&
        agentMemory.body?.memory?.revision === 1 &&
        String(agentMemory.body?.memory?.body ?? '').includes('Use the release checklist.'),
      'workerd Admin Memory API exposes the one Agent-owned body',
      `memory=${agentMemory.status} revision=${String(agentMemory.body?.memory?.revision)}`,
    );
    const memoryEditBody = JSON.stringify({
      expectedRevision: 1,
      body: 'Run focused tests and the workerd smoke before release.',
    });
    const memoryEdit = await adminFetch(
      baseUrl,
      memoryPath,
      {
        method: 'PUT',
        body: memoryEditBody,
      },
    );
    const memoryConflict = await adminFetch(
      baseUrl,
      memoryPath,
      {
        method: 'PUT',
        body: memoryEditBody,
      },
    );
    check(
      memoryEdit.status === 200 && memoryEdit.body?.memory?.revision === 2 &&
        memoryConflict.status === 409 && memoryConflict.body?.currentVersion === 2,
      'workerd Memory edit is optimistic and conflict-safe',
      `edit=${memoryEdit.status} conflict=${memoryConflict.status}`,
    );

    // Restart workerd on the SAME persist dir: claims, the thread registry,
    // and the config all live in the state DO's SQLite and must survive.
    console.log('• restarting wrangler dev (persistence round)…');
    await stopWrangler(wrangler);
    previousWorkerOutputs.push(wrangler.getOutput());
    wrangler = spawnWranglerDev();
    await waitForAdminReady(wrangler, baseUrl);

    const persistedSession = await adminFetch(baseUrl, '/admin/api/team');
    check(
      persistedSession.status === 200 && persistedSession.body?.members?.[0]?.slackUserId === OWNER_USER_ID,
      'the original Slack-established session and exact Owner survived the workerd restart',
      `HTTP ${persistedSession.status}`,
    );
    adminCookie = await completeSlackLogin(baseUrl);
    const freshSession = await adminFetch(baseUrl, '/admin/api/team');
    check(
      freshSession.status === 200 && freshSession.body?.viewer?.role === 'owner',
      'a fresh post-restart Slack OIDC session resolves the same live Owner authority',
      `HTTP ${freshSession.status} role=${String(freshSession.body?.viewer?.role)}`,
    );
    const restartMemory = await adminFetch(baseUrl, memoryPath);
    check(
      restartMemory.status === 200 && restartMemory.body?.memory?.revision === 2 &&
        restartMemory.body?.memory?.body === 'Run focused tests and the workerd smoke before release.',
      'Agent memory and revision survived the workerd restart',
      `HTTP ${restartMemory.status} revision=${String(restartMemory.body?.memory?.revision)}`,
    );

    const postRestartRedelivery = await postSignedEvent(eventsUrl, mentionEvent());
    check(
      postRestartRedelivery.status === 200 || postRestartRedelivery.status === 202,
      'post-restart redelivery acked',
      `HTTP ${postRestartRedelivery.status}`,
    );
    await backend.quiesce(1500, 15_000);
    check(
      backend.finals().length === 2,
      'post-restart redelivery still deduped (claims persisted)',
      `${backend.finals().length} finals`,
    );

    const replyStartedAt = Date.now();
    const reply = await postSignedEvent(eventsUrl, threadReplyEvent());
    check(
      reply.status === 200 || reply.status === 202,
      'implicit thread reply admitted post-restart',
      `HTTP ${reply.status}`,
    );
    const replyFinals = await waitForFinalCount(backend, 3, 90_000);
    check(
      replyFinals.length === 3,
      'thread registry persisted across restart (reply turn delivered)',
      `${replyFinals.length} finals in ${Date.now() - replyStartedAt}ms`,
    );

    // --- Slow-turn case: DO alarm relay past the old ~30s waitUntil horizon ---
    //
    // The provider holds its SSE response open for SLOW_TURN_DELAY_MS. A real
    // deploy's events-invocation waitUntil dies at ~29.5s (tail-log-confirmed);
    // under the relay the events handler only enqueues (fast ack) and the state
    // DO's alarm() runs the turn with the platform's 15-minute budget. Local
    // workerd does not enforce the 30s cap, so this proves the relay PATH: the
    // ack returns before the held turn, and the final lands after it. The
    // cancellation it replaces is doc/tail-log-backed.
    console.log(`• slow-turn case: provider will hold ${SLOW_TURN_DELAY_MS}ms before replying…`);
    backend.configure({ provider: { delayMs: SLOW_TURN_DELAY_MS } });
    const slowGrant = await adminFetch(baseUrl, '/admin/api/agents/agent_default/channels', {
      method: 'POST',
      body: JSON.stringify({
        workspaceId: WORKSPACE,
        channelId: SLOW_CHANNEL,
      }),
    });
    check(
      slowGrant.status === 201 && slowGrant.body?.grant?.status === 'active',
      'Agent publication granted the slow-turn Channel',
      `HTTP ${slowGrant.status}`,
    );

    const finalsBeforeSlow = backend.finals().length;
    const slowStartedAt = Date.now();
    const slowAdmission = await postSignedEvent(eventsUrl, slowMentionEvent());
    const slowAckMs = Date.now() - slowStartedAt;
    check(
      slowAdmission.status === 200 || slowAdmission.status === 202,
      'slow-turn mention admitted',
      `HTTP ${slowAdmission.status}`,
    );
    // The events ack must return FAST: the turn runs in the alarm, not inline.
    // A ~SLOW_TURN_DELAY_MS ack here would mean the handler blocked on the turn.
    check(
      slowAckMs < 10_000,
      'events ack returned before the turn ran (enqueued, not inline)',
      `${slowAckMs}ms`,
    );

    const slowFinals = await waitForFinalCount(backend, finalsBeforeSlow + 1, 120_000);
    const slowDeliveryMs = Date.now() - slowStartedAt;
    check(
      slowFinals.length === finalsBeforeSlow + 1,
      'slow turn delivered its final via the DO alarm relay',
      `${slowFinals.length - finalsBeforeSlow} new final(s) in ${slowDeliveryMs}ms`,
    );
    const slowFinal = slowFinals[slowFinals.length - 1];
    check(
      Boolean(slowFinal?.text.includes(STUB_REPLY_MARKER)),
      'slow-turn final carries the stub provider reply (not the failure text)',
    );
    check(slowFinal?.channel === SLOW_CHANNEL, 'slow-turn final landed in the slow channel');
    console.log(
      `• measured slow-turn delivery: ${slowDeliveryMs}ms (fast ack ${slowAckMs}ms; provider held ${SLOW_TURN_DELAY_MS}ms)`,
    );

    // Claims settle: the completed slow turn keeps its claim, so an identical
    // redelivery is deduped. Reset the provider delay first so a wrongly-
    // admitted redelivery would deliver fast (and be caught) instead of hanging.
    backend.configure({ provider: { delayMs: 0 } });
    const slowRedelivery = await postSignedEvent(eventsUrl, slowMentionEvent());
    check(
      slowRedelivery.status === 200 || slowRedelivery.status === 202,
      'slow-turn redelivery acked',
      `HTTP ${slowRedelivery.status}`,
    );
    await backend.quiesce(1500, 15_000);
    check(
      backend.finals().length === finalsBeforeSlow + 1,
      'slow-turn redelivery deduped (claims settled after the alarm ran)',
      `${backend.finals().length - finalsBeforeSlow} new final(s)`,
    );

    {
      const output = [...previousWorkerOutputs, wrangler.getOutput()].join('\n');
      const runnerRan = /thread_runner_alarm[\s\S]{0,300}?ran['"]?:\s*[1-9]/.test(output);
      const runnerLatency = /turn_latency[\s\S]{0,400}?executor['"]?:\s*['"]runner['"]/.test(output);
      const alarmLatency = /turn_latency[\s\S]{0,400}?executor['"]?:\s*['"]alarm['"]/.test(output);
      const dispatched = /relay_alarm[\s\S]{0,600}?jobsDispatched['"]?:\s*[1-9]/.test(output);
      if (SMOKE_TURN_EXECUTOR === 'runner') {
        // The admission hands a new turn to its runner itself; the relay alarm
        // dispatches only what that hand-off missed, so its count proves nothing
        // on a quiet run. The runner's own alarm running jobs, and no turn
        // executed by the relay alarm, is the hand-off's evidence.
        check(
          runnerRan && runnerLatency && !alarmLatency,
          'default executor (variable unset): turns were handed to and run by thread runners',
        );
      } else {
        check(
          alarmLatency && !runnerLatency && !runnerRan && !dispatched,
          'SLACK_TAG_TURN_EXECUTOR=alarm: the state store alarm ran every turn and handed none to runners',
        );
      }
    }

    // Pi's Google adapter and its SDK's web build answer a turn inside workerd.
    const agentBeforeGemini = await adminFetch(baseUrl, '/admin/api/agents/agent_default');
    const geminiPin = await adminFetch(baseUrl, '/admin/api/agents/agent_default', {
      method: 'PATCH',
      body: JSON.stringify({ expectedRevision: agentBeforeGemini.body?.agent?.revision, model: 'google/gemini-3.8-flash' }),
    });
    check(geminiPin.status === 200, 'admin PATCH pinned the agent to a Gemini model', `HTTP ${geminiPin.status}`);
    const finalsBeforeGemini = backend.finals().length;
    const geminiWireStart = backend.wireLog.length;
    const geminiAdmission = await postSignedEvent(eventsUrl, geminiMentionEvent());
    check(
      geminiAdmission.status === 200 || geminiAdmission.status === 202,
      'Gemini mention admitted',
      `HTTP ${geminiAdmission.status}`,
    );
    const geminiFinals = await waitForFinalCount(backend, finalsBeforeGemini + 1, 90_000);
    const geminiStreams = backend.wireLog.slice(geminiWireStart)
      .filter((entry) => entry.method === 'streamGenerateContent').map((entry) => entry.url.split('?')[0]);
    check(
      geminiStreams.includes('/gemini/v1beta/models/gemini-3.8-flash:streamGenerateContent') &&
        Boolean(geminiFinals.at(-1)?.text.includes(STUB_REPLY_MARKER)),
      'a Gemini turn streams from GEMINI_BASE_URL with the saved key and delivers its reply',
      `${geminiStreams.join(',') || 'no Gemini request'}; ${geminiFinals.at(-1)?.text ?? 'no final'}`,
    );

    await exerciseSlackRecovery(baseUrl, backend, eventsUrl);

    if (failures.length > 0) {
      throw new Error(`assertions failed: ${failures.join('; ')}`);
    }
    console.log(
      `\nPASS cf-smoke — turn wall-time ${turnWallTimeMs}ms; slow-turn delivery ${slowDeliveryMs}ms`,
    );
  } catch (err) {
    console.error(`\nFAIL cf-smoke: ${err instanceof Error ? err.message : String(err)}`);
    const output = [...previousWorkerOutputs, wrangler.getOutput()].join('\n');
    const chickpeaDiagnostics = output
      .split('\n')
      .filter((line) => line.includes('[chickpea]') || line.includes('[work]'));
    if (chickpeaDiagnostics.length > 0) {
      console.error('\n--- Chickpea diagnostics ---');
      console.error(chickpeaDiagnostics.join('\n'));
    }
    console.error('\n--- wrangler dev output (tail) ---');
    console.error(output.split('\n').slice(-60).join('\n'));
    console.error('\n--- fake Slack wire log (methods) ---');
    console.error(backend.wireLog.map((entry) => `${entry.kind}:${entry.method}`).join('\n'));
    process.exitCode = 1;
  } finally {
    await stopWrangler(wrangler);
    await fake.close();
    await backend.close();
  }
}

export { SIGNING_SECRET };

const invokedAsScript = process.argv[1] !== undefined &&
  realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url));
if (invokedAsScript) {
  main().catch((err) => {
    console.error(err);
    process.exitCode = 1;
  }).finally(() => {
    rmSync(PERSIST_DIR, { recursive: true, force: true });
  });
}