Files
PaperClipAI/packages/paperclip-runner/scripts/aws-agentcore-provisioning.test.mjs
Dotta af8439a70b feat(runner): restore direct live eval campaigns and reports (#12909)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Runner executes agents through native and managed provider
drivers.
> - The direct live eval layer had drifted from the current Runner
contracts.
> - The old local workflow did not provide a complete parallel campaign
or durable report history.
> - The Runner also needed current native OpenCode and OpenRouter
qualification.
> - This pull request restores the direct campaign, corrects the runtime
gaps that the campaign found, and adds safe hosted Evalbook history.
> - The benefit is repeatable model comparison against an immutable
Runner and eval source revision.

## Linked Issues or Issue Description

Refs #11297
Refs #11634

**What existing behavior does this improve?**

This improves the direct live `paperclip-runner` eval workflow, provider
execution contract, and static Evalbook reporting path.

**Current behavior**

The direct evals do not have one maintained full campaign on current
`master`. OpenCode has no qualified multi-model OpenRouter roster.
Parallel provider bursts can compact committed events before the
transport observes them. Local reports do not have a separate safe S3
history index.

**Proposed behavior**

Run one immutable roster-plus-case matrix. Use the shared paid AWS
runner fleet. Keep raw artifacts access-controlled. Publish a sanitized
canonical Evalbook report under the separate `runner-protocol-evals` S3
prefix. Keep immutable campaign directories plus root history, latest,
and latest-green pointers.

**Reason and benefit**

Maintainers can compare native Codex, native OpenCode, ACPX, Claude
Managed, and AWS AgentCore behavior over time. They can inspect failures
without mixing this direct protocol layer with browser full-stack E2E.

**Breaking changes**

None. The new workflow and S3 prefix are additive. The existing Runner
full-stack E2E workflow and report remain separate.

## What Changed

- Added a trusted two-shard direct live workflow for up to 393
roster-plus-case cells.
- Reused the numeric actor allowlist, protected paid environment, and
RunsOn fleet controls from Runner full-stack E2E.
- Added immutable Runner and eval revision resolution, exact credential
boundaries, bounded retries, and cost ceilings.
- Added a public report projection that removes sessions, transcripts,
tool payloads, state, traces, raw failures, remote profile identities,
and credential-shaped values.
- Added additive S3 history under `runner-protocol-evals`, with
immutable campaigns and mutable root index pointers.
- Added native OpenCode model injection and current OpenRouter pricing
contracts.
- Fixed direct eval completion, workflow execution, semantic discovery,
warm-attach state reset, executable binding, and event-burst handling.
- Kept Runner browser full-stack E2E behavior and publication separate.
- Documented local and hosted direct eval operation.

## Verification

- `pnpm --filter @paperclipai/paperclip-runner
test:runner-protocol-eval-publish` — 15 passed.
- `pnpm --filter @paperclipai/paperclip-runner build:typescript` —
passed.
- `actionlint .github/workflows/runner-protocol-live-evals.yml
.github/workflows/runner-full-stack-e2e.yml` — passed.
- Local current matrix at the revision in
[paperclip-evals#17](https://github.com/paperclipai/paperclip-evals/pull/17)
— 323 cells across 10 enabled configurations completed.
- Final local current matrix — 269 passed, 11 behavior failures, and 43
expected macOS-only ACPX platform failures.
- Targeted Runner checks — 13/13 eval-session tests, 15/15
publisher/security tests, and package typecheck passed; complete PR CI
is green, including all browser E2E shards.

## Risks

- Paid live campaigns can consume provider budget. Actor authorization,
exact per-cell ceilings, protected environments, and explicit schedule
enablement bound this risk.
- Public reports can leak provider data. The workflow publishes only a
separately projected report and validates every file before upload.
- The new workflow cannot publish until it is present on the default
branch. This pull request does not change the existing
`runner-full-stack-e2e` publication path.
- The campaign is large. It uses two GitHub matrices and caps combined
concurrency at the shared fleet limit.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex on GPT-5. The exact deployment ID and context-window size
are not exposed. The model used reasoning, code editing, browser
inspection, repository tools, and live provider execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-09-05 20:18:11 -05:00

266 lines
17 KiB
JavaScript

import assert from "node:assert/strict";
import { execFileSync, spawnSync } from "node:child_process";
import { chmod, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import test from "node:test";
const templateUrl = new URL("../infra/aws-agentcore-paperclip.yaml", import.meta.url);
const wrapperUrl = new URL("./aws-agentcore.sh", import.meta.url);
const labServerUrl = new URL("./capability-issue-thread-server.mjs", import.meta.url);
const liveSessionUrl = new URL("../src/live/live-session.ts", import.meta.url);
function parameterAllowedPattern(source, parameterName) {
const marker = ` ${parameterName}:\n`;
const start = source.indexOf(marker);
assert.notEqual(start, -1, `missing ${parameterName} parameter`);
const remaining = source.slice(start + marker.length);
const nextMatch = /\n \S/.exec(remaining);
const nextParameter = nextMatch ? start + marker.length + nextMatch.index : -1;
const block = source.slice(start, nextParameter === -1 ? undefined : nextParameter);
const match = block.match(/AllowedPattern: "([^"]+)"/);
assert.ok(match, `missing ${parameterName} AllowedPattern`);
return new RegExp(match[1]);
}
test("AgentCore template has closed development/private resources and explicit command denial", async () => {
const source = await readFile(templateUrl, "utf8");
for (const resource of [
"AWS::BedrockAgentCore::Harness",
"AWS::BedrockAgentCore::Memory",
"AWS::S3::Bucket",
"AWS::KMS::Key",
"AWS::EC2::VPC",
"com.amazonaws.${AWS::Region}.ecr.api",
"com.amazonaws.${AWS::Region}.ecr.dkr",
"com.amazonaws.${AWS::Region}.s3",
"com.amazonaws.${AWS::Region}.bedrock-runtime",
]) assert.match(source, new RegExp(resource.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")));
assert.match(source, /AllowedValues: \[development, private\]/);
assert.match(source, /Effect: Deny\s+Action: bedrock-agentcore:InvokeAgentRuntimeCommand/g);
assert.doesNotMatch(source, /Effect: Allow\s+Action: bedrock-agentcore:InvokeAgentRuntimeCommand/);
assert.doesNotMatch(source, /AWS::EC2::NatGateway|AWS::EC2::InternetGateway/);
assert.match(source, /EventExpiryDuration: 90/);
assert.match(source, /MaxIterations: 8/);
assert.match(source, /MaxTokens: 4096/);
assert.match(source, /TimeoutSeconds: 300/);
assert.match(source, /AllowedTools:\s+- "@\*\/pc_\*"/);
assert.match(source, /Tools: \[\]/);
assert.match(source, /Skills: \[\]/);
assert.doesNotMatch(source, /BedrockModelResourceArn:\s+[\s\S]{0,100}Default: "\*"/);
assert.match(source, /BedrockModelId:[\s\S]*AllowedPattern: "\^\[A-Za-z0-9\]\[A-Za-z0-9\._:-\]\{0,255\}\$"/);
assert.match(source, /BedrockModelResourceArn:[\s\S]*AllowedPattern:[^\n]+inference-profile[^\n]+\[A-Za-z0-9\]\[A-Za-z0-9\._:-\]\{0,255\}/);
assert.match(source, /BedrockFoundationModelResourceArn:[\s\S]*AllowedPattern:[^\n]+foundation-model\/\[A-Za-z0-9\]\[A-Za-z0-9\._:-\]\{0,255\}/);
const modelIdPattern = parameterAllowedPattern(source, "BedrockModelId");
assert.match("global.anthropic.claude-sonnet-4-6", modelIdPattern);
assert.match("anthropic.claude-3-5-sonnet-20241022-v2:0", modelIdPattern);
for (const unsafeModelId of ["custom/model", "custom*", "custom?", "arn:aws:bedrock:us-east-1::foundation-model/custom"]) {
assert.doesNotMatch(unsafeModelId, modelIdPattern);
}
const inferenceProfilePattern = parameterAllowedPattern(source, "BedrockModelResourceArn");
assert.match("arn:aws:bedrock:us-east-1:123456789012:inference-profile/global.anthropic.claude-sonnet-4-6", inferenceProfilePattern);
assert.doesNotMatch("arn:aws:bedrock:us-east-1:123456789012:inference-profile/*", inferenceProfilePattern);
assert.doesNotMatch("arn:aws:bedrock:us-east-1:123456789012:inference-profile/custom/model", inferenceProfilePattern);
const foundationModelPattern = parameterAllowedPattern(source, "BedrockFoundationModelResourceArn");
assert.match("arn:aws:bedrock:*::foundation-model/anthropic.claude-sonnet-4-6", foundationModelPattern);
assert.doesNotMatch("arn:aws:bedrock:*::foundation-model/*", foundationModelPattern);
assert.doesNotMatch("arn:aws:bedrock:*::foundation-model/custom/model", foundationModelPattern);
assert.match(source, /BedrockFoundationModelResourceArn/);
assert.match(source, /HarnessEndpointName/);
assert.match(source, /ContextPrefix/);
assert.match(source, /BucketOwnerEnforced/);
assert.match(source, /SSEAlgorithm: aws:kms/);
assert.match(source, /EnableKeyRotation: true/);
assert.match(source, /Sid: DenyInsecureTransport/);
assert.match(source, /Sid: DenyUnencryptedContextUploads/);
assert.match(source, /Sid: DenyContextUploadsWithAnotherKey/);
assert.match(source, /Sid: WriteAndVerifyPinnedRuntimeContext[\s\S]*s3:GetObject[\s\S]*s3:PutObject[\s\S]*s3:DeleteObject[\s\S]*Resource: !Sub \$\{ContextBucket\.Arn\}\/\$\{ContextPrefix\}\/assets\/\*/);
assert.match(source, /Sid: EncryptPinnedRuntimeContext[\s\S]*kms:Encrypt[\s\S]*kms:GenerateDataKey[\s\S]*Resource: !GetAtt ContextEncryptionKey\.Arn/);
assert.match(source, /Sid: ReadPinnedRuntimeContext[\s\S]*Action: s3:GetObject[\s\S]*Resource: !Sub \$\{ContextBucket\.Arn\}\/\$\{ContextPrefix\}\/assets\/\*/);
assert.match(source, /Sid: EnumeratePinnedRuntimeContext[\s\S]*Action: s3:ListBucket[\s\S]*Resource: !GetAtt ContextBucket\.Arn[\s\S]*s3:prefix: !Sub \$\{ContextPrefix\}\/assets\/\*/);
assert.match(source, /Sid: EnumeratePinnedRuntimeContextForTeardown[\s\S]*Action: s3:ListBucket[\s\S]*Resource: !GetAtt ContextBucket\.Arn[\s\S]*s3:prefix: !Sub \$\{ContextPrefix\}\/assets\/\*/);
assert.match(source, /Sid: DecryptPinnedRuntimeContext[\s\S]*Action: kms:Decrypt[\s\S]*Resource: !GetAtt ContextEncryptionKey\.Arn/);
const invocationRole = source.slice(source.indexOf("RunnerInvocationRole:"), source.indexOf("PrivateVpc:"));
assert.doesNotMatch(invocationRole, /Action:\s+(?:-\s+)?(?:s3|kms):\*/);
assert.match(invocationRole, /Action: sts:AssumeRoleWithWebIdentity/);
assert.match(invocationRole, /token\.actions\.githubusercontent\.com:aud["']?: sts\.amazonaws\.com/);
assert.match(invocationRole, /token\.actions\.githubusercontent\.com:sub["']?: !Sub repo:\$\{GitHubRepository\}:environment:\$\{GitHubEnvironment\}/);
assert.doesNotMatch(invocationRole, /repo:\*|environment:\*/);
assert.match(source, /\$\{AgentHarness\.Arn\}\/harness-endpoint\/\$\{HarnessEndpointName\}/);
assert.match(source, /\$\{AgentHarness\.Arn\}\/runtime-endpoint\/\$\{HarnessEndpointName\}/);
assert.match(source, /BedrockMarketplaceProductId/);
assert.match(source, /Sid: ViewMarketplaceSubscriptionsForModelAccess[\s\S]*Action: aws-marketplace:ViewSubscriptions[\s\S]*Sid: SubscribePinnedMarketplaceModel[\s\S]*Action: aws-marketplace:Subscribe[\s\S]*aws-marketplace:ProductId: !Ref BedrockMarketplaceProductId/);
assert.doesNotMatch(source, /aws-marketplace:Unsubscribe/);
});
test("AgentCore wrapper is valid shell and writes only nonsecret profile metadata", async () => {
execFileSync("bash", ["-n", wrapperUrl.pathname]);
const source = await readFile(wrapperUrl, "utf8");
const generatedBlock = source.slice(source.lastIndexOf('"AWS_PROFILE=$AWS_PROFILE_NAME"'), source.lastIndexOf('>"$tmp"'));
const teardownBlock = source.slice(source.indexOf("write_teardown_metadata()"), source.indexOf("assume_runner_role()"));
assert.ok(generatedBlock.length > 0);
assert.ok(teardownBlock.length > 0);
assert.doesNotMatch(generatedBlock, /AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|AWS_SESSION_TOKEN|Authorization|X-Amz-Signature/);
assert.doesNotMatch(teardownBlock, /AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|AWS_SESSION_TOKEN|Authorization|X-Amz-Signature/);
assert.match(teardownBlock, /PAPERCLIP_AWS_AGENTCORE_STACK_NAME=\$STACK_NAME/);
assert.match(teardownBlock, /chmod 600 "\$tmp"/);
assert.match(source, /chmod 600 "\$tmp"/);
assert.match(source, /printf '%q\\n'/);
assert.match(source, /printf 'AWS_CONFIG_FILE=%q\\n'/);
assert.match(source, /AWS_PROFILE_EXPLICIT=true/);
assert.match(source, /AWS_REGION_EXPLICIT=true/);
assert.match(source, /STACK_NAME_EXPLICIT=true/);
assert.equal((source.match(/local requested_profile=/g) ?? []).length, 1);
assert.equal((source.match(/requested_region=/g) ?? []).length, 1);
assert.equal((source.match(/requested_stack=/g) ?? []).length, 1);
const destroyBlock = source.slice(source.indexOf("destroy()"), source.indexOf('case "$ACTION"'));
assert.ok(destroyBlock.indexOf("load_local_env") < destroyBlock.indexOf("stack_output HarnessId"));
assert.match(source, /cloudformation deploy/);
const provisionBlock = source.slice(source.indexOf("provision()"), source.indexOf("lab()"));
assert.ok(provisionBlock.indexOf("cloudformation deploy") < provisionBlock.indexOf("write_teardown_metadata"));
assert.ok(provisionBlock.indexOf("write_teardown_metadata") < provisionBlock.indexOf("stack_output HarnessId"));
assert.ok(provisionBlock.indexOf("write_teardown_metadata") < provisionBlock.indexOf("wait_for_harness_status"));
assert.match(source, /CAPABILITY_NAMED_IAM/);
assert.match(source, /--\) shift ;;/);
assert.match(source, /iam get-role --role-name "\$role_name"/);
assert.doesNotMatch(source, /printf 'arn:%s:iam::%s:role\/%s/);
assert.match(source, /existing_status.*ROLLBACK_COMPLETE/s);
assert.match(source, /--replace-failed-stack/);
assert.match(provisionBlock, /existing_description.*STACK_DESCRIPTION/s);
assert.match(provisionBlock, /existing_owned.*paperclip:owned/s);
assert.match(provisionBlock, /existing_environment.*paperclip:environment/s);
assert.match(provisionBlock, /existing_cost_center.*paperclip:cost-center/s);
assert.ok(provisionBlock.indexOf("ownership tags or template provenance") < provisionBlock.indexOf("cloudformation delete-stack"));
assert.ok(provisionBlock.indexOf("REPLACE_FAILED_STACK") < provisionBlock.indexOf("cloudformation delete-stack"));
assert.match(provisionBlock, /Unable to verify whether stack .* exists and is owned by Paperclip/);
assert.match(source, /cloudformation wait stack-delete-complete/);
assert.match(source, /--query harness\.status/);
assert.match(source, /AgentCore tool allowlist drift/);
assert.match(source, /--query memory\.status/);
assert.match(source, /--query endpoint\.status/);
assert.match(source, /o\.endpoint\?\.arn/);
assert.match(source, /--marketplace-product-id/);
assert.match(source, /--github-oidc-provider-arn/);
assert.match(source, /GitHubOidcProviderArn=\$GITHUB_OIDC_PROVIDER_ARN/);
assert.match(source, /BedrockMarketplaceProductId=\$MARKETPLACE_PRODUCT_ID/);
assert.match(generatedBlock, /PAPERCLIP_AWS_AGENTCORE_CONTEXT_BUCKET=\$context_bucket/);
assert.match(generatedBlock, /PAPERCLIP_AWS_AGENTCORE_CONTEXT_PREFIX=\$context_prefix/);
assert.match(generatedBlock, /PAPERCLIP_AWS_AGENTCORE_CONTEXT_KMS_KEY_ARN=\$context_kms_key_arn/);
assert.match(generatedBlock, /PAPERCLIP_AWS_AGENTCORE_EXECUTION_ROLE_ARN=\$role_arn/);
assert.match(source, /ContextPrefix=\$CONTEXT_PREFIX/);
assert.match(source, /s3 rm "s3:\/\/\$context_bucket\/\$context_prefix\/assets\/" --recursive/);
assert.ok(source.indexOf("delete-harness-endpoint") < source.lastIndexOf("cloudformation delete-stack"));
});
test("AgentCore wrapper rejects unsafe model IDs before AWS access", () => {
const result = spawnSync("bash", [
wrapperUrl.pathname,
"provision",
"--model",
"custom/model/*",
"--marketplace-product-id",
"prod-safe123",
], { encoding: "utf8" });
assert.equal(result.status, 2);
assert.match(result.stderr, /must not contain ARN, path, glob, or wildcard syntax/);
});
test("AgentCore wrapper never implicitly deletes a colliding failed stack", async () => {
const temp = await mkdtemp(join(tmpdir(), "paperclip-agentcore-test-"));
const fakeAws = join(temp, "aws");
const commandLog = join(temp, "aws.log");
await writeFile(fakeAws, `#!/usr/bin/env bash
set -eu
printf '%s\\n' "$*" >>"$MOCK_AWS_LOG"
if [[ " $* " == *" --version "* || "$1" == "--version" ]]; then
printf 'aws-cli/2.31.0 Python/3.13.0\\n'
elif [[ " $* " == *" sts get-caller-identity "* ]]; then
printf '{"Account":"123456789012","Arn":"arn:aws:iam::123456789012:role/paperclip-test"}\\n'
elif [[ " $* " == *" cloudformation describe-stacks "* ]]; then
printf '{"Stacks":[{"StackStatus":"ROLLBACK_COMPLETE","Description":"%s","Tags":[{"Key":"paperclip:owned","Value":"%s"},{"Key":"paperclip:environment","Value":"development"},{"Key":"paperclip:cost-center","Value":"runner-lab"}]}]}\\n' "\${MOCK_STACK_DESCRIPTION}" "\${MOCK_STACK_OWNED}"
elif [[ " $* " == *" cloudformation deploy "* ]]; then
exit 42
fi
`, { mode: 0o700 });
await chmod(fakeAws, 0o700);
const baseEnv = {
...process.env,
PATH: `${temp}:${process.env.PATH}`,
MOCK_AWS_LOG: commandLog,
MOCK_STACK_DESCRIPTION: "Paperclip proof-of-concept Amazon Bedrock AgentCore Harness and least-privilege invocation roles.",
MOCK_STACK_OWNED: "true",
};
try {
const implicit = spawnSync("bash", [wrapperUrl.pathname, "provision"], { encoding: "utf8", env: baseEnv });
assert.equal(implicit.status, 1);
assert.match(implicit.stderr, /--replace-failed-stack/);
assert.doesNotMatch(await readFile(commandLog, "utf8"), /cloudformation delete-stack/);
await writeFile(commandLog, "");
const foreign = spawnSync("bash", [wrapperUrl.pathname, "provision", "--replace-failed-stack", "--yes"], {
encoding: "utf8",
env: { ...baseEnv, MOCK_STACK_OWNED: "false" },
});
assert.equal(foreign.status, 1);
assert.match(foreign.stderr, /ownership tags or template provenance do not match/);
assert.doesNotMatch(await readFile(commandLog, "utf8"), /cloudformation delete-stack/);
await writeFile(commandLog, "");
const explicit = spawnSync("bash", [wrapperUrl.pathname, "provision", "--replace-failed-stack", "--yes"], {
encoding: "utf8",
env: baseEnv,
});
assert.equal(explicit.status, 42);
const explicitLog = await readFile(commandLog, "utf8");
assert.match(explicitLog, /cloudformation delete-stack/);
assert.ok(explicitLog.indexOf("cloudformation delete-stack") < explicitLog.indexOf("cloudformation deploy"));
} finally {
await rm(temp, { recursive: true, force: true });
}
});
test("Runner Lab accepts and resolves the complete qualified AgentCore profile", async () => {
const source = await readFile(labServerUrl, "utf8");
assert.match(source, /provider !== "aws_agentcore"/);
assert.match(source, /AWS AgentCore requires exact model global\.anthropic\.claude-sonnet-4-6/);
assert.match(source, /function resolveAgentCoreProfile\(configuration\)/);
for (const field of [
"PAPERCLIP_AWS_AGENTCORE_CONTEXT_BUCKET",
"PAPERCLIP_AWS_AGENTCORE_CONTEXT_PREFIX",
"PAPERCLIP_AWS_AGENTCORE_CONTEXT_KMS_KEY_ARN",
]) assert.match(source, new RegExp(field));
assert.match(source, /agentCoreProfile: resolveAgentCoreProfile\(configuration\)/);
assert.match(source, /agentCoreProfileId: snapshot\.config\.agentCoreProfile\.profileId/);
assert.match(source, /configuration\.provider === "aws_agentcore" \? "remote_service"/);
});
test("Runner Lab qualifies Claude Managed and exposes remote governance for both remote providers", async () => {
const source = await readFile(labServerUrl, "utf8");
const liveSessionSource = await readFile(liveSessionUrl, "utf8");
assert.match(source, /provider !== "claude_managed"/);
assert.match(source, /Claude Managed requires exact model claude-sonnet-5/);
assert.match(source, /function resolveManagedProfile\(configuration\)/);
for (const field of [
"PAPERCLIP_CLAUDE_MANAGED_PROFILE_ID",
"ANTHROPIC_API_KEY",
"ANTHROPIC_MANAGED_AGENT_ID",
"ANTHROPIC_MANAGED_AGENT_VERSION",
"ANTHROPIC_MANAGED_ENVIRONMENT_ID",
]) assert.match(source, new RegExp(field));
assert.match(source, /\^\[1-9\]\[0-9\]\*\$/);
assert.match(source, /BigInt\(agentVersion\) <= 2_147_483_647n/);
assert.match(source, /managedProfile: resolveManagedProfile\(configuration\)/);
assert.match(source, /managedProfileId: snapshot\.config\.managedProfile\.profileId/);
assert.match(source, /route === "managed-budget"/);
assert.match(source, /entry\.session\.increaseManagedSessionBudget\(nextCap\)/);
assert.match(source, /entry\.configuration\?\.provider === "claude_managed"/);
assert.match(source, /entry\.configuration\?\.provider === "aws_agentcore"/);
assert.match(source, /route === "managed-session-delete"/);
assert.match(source, /body\.confirm !== true/);
assert.match(source, /entry\.session\.deleteManagedRemoteSession\(\)/);
assert.match(liveSessionSource, /async increaseManagedSessionBudget\(/);
assert.match(liveSessionSource, /this\.#transport\.request\("session\/budget\/increase"/);
assert.match(liveSessionSource, /async deleteManagedRemoteSession\(\)/);
assert.match(liveSessionSource, /this\.#transport\.request\("session\/destroy"/);
});