Guided AgentCore Hub setup. Asks the user which modules they want, generates .env.local, and runs only the deploy scripts those modules need — with a verification gate between phases.
Install
npx skillscat add tycenjmccann/agentcore-hub/setup Install via the SkillsCat registry.
/agentcore-hub:setup — AgentCore Hub guided installer
You are running this skill from the root of an agentcore-hub clone. Your job is to install AgentCore Hub for the user by:
- Asking 4–6 questions to figure out what they want (use
AskUserQuestion, not free-text). - Detecting their AWS account/region from their existing credentials.
- Writing a
.env.localfrom their answers (never overwrite an existing one — back up to.env.local.bakfirst). - Running the deploy scripts for the modules they picked, in the right order.
- Pausing after each phase to verify it worked. If a verification fails, surface the actual error and ask the user how to proceed.
Authoritative references — read these before doing anything else, they describe the system you're installing:
docs/MODULES.md— module boundaries + per-module file listsREADME.mdStages 1–6 — the manual setup this skill automates.env.example— every env var that may need a value
You are a runner over scripts that already exist in the repo. Never invent new infra or new scripts. If something the user wants isn't covered by an existing script in deploy/, scripts/, or alongside Lambda source under lambda/<name>/deploy.sh, tell them and link to the README section instead.
Pre-flight (run silently before Q1)
Run these in parallel and use the results in the questions below:
pwd # confirm we're in an agentcore-hub clone
test -f package.json && cat package.json | head -5
aws sts get-caller-identity 2>&1 # detect account; capture failures to report in Q3
aws configure get region 2>&1 # detect region
test -f .env.local && echo "EXISTING_ENV_LOCAL"If pwd doesn't look like an agentcore-hub repo (no package.json with agentcore-hub in it, or no docs/MODULES.md), stop and tell the user to cd into the repo first.
If .env.local already exists, tell the user up-front: "Found existing .env.local — I'll back it up to .env.local.bak before writing." Don't ask permission for the backup; just do it when you write the new file.
Q1 — Brand name
- question: "Would you like to replace the AgentCore Hub branding with your own brand or company name? This changes the name shown in the header, sidebar, and page titles. AWS resources keep the canonical
agentcore-hub-*prefix so the app keeps working." - header: "Brand"
- options:
- Keep "AgentCore Hub" — no change to the UI branding.
- Use a custom name — I'll type the brand or company name to display.
If the user picks "Custom", do a free-text follow-up. Save as brand_name in the answers blob. This becomes NEXT_PUBLIC_BRAND_NAME in .env.local.
The user has confirmed this is the contract: the brand var only affects display text. AWS resource names (DynamoDB tables, Lambdas, IAM roles, S3 bucket prefix, AgentCore runtimes) are part of the application contract and are always created with the canonical
agentcore-hub-*prefix. Do not offer to rename them. If a user asks, point them at the design-lock section in.claude-plugin/README.md.
Q2 — Modules
Before asking, print a short module overview so the user can answer with eyes open. Read counts/lambdas from docs/MODULES.md and src/config/agents.json; do not hard-code them in the skill output if they've drifted. Format:
This install can deploy four modules. You'll always get Core; the rest are optional.
Core — always installed. Dashboard, Agents browser, Invoke console.
No new AWS resources beyond credentials.
Builder — adds /build (chat-driven agent creation). Deploys 1 AgentCore
harness runtime (agentcore_hub_builder) + 1 Lambda
(builder-tools). ~3–5 min.
Workflow — adds the multi-agent pipeline (intake → requirements → design
→ development → QA). Deploys 14 AgentCore Runtime agents
(1 Requirements + 8 Design + 3 Development + 1 QA + 1 Review),
3 DynamoDB tables, 1 S3 bucket, 4 Lambdas (orchestrator,
tickets, jira, workflow-output), and an ECR image. ~10–15 min.
Depends on: Core. Optionally uses Jira Cloud for tickets.
Evaluations — adds the self-improvement loop. Deploys 3 Lambdas
(eval-packager, token-aggregator, prd-submitter), 1 DynamoDB
table (agentcore-hub-eval-config), and CloudWatch
subscription filters. ~5 min.
Depends on: Workflow (it watches Workflow agents' eval logs).
Cloud Code — adds /cloud-code: Claude Code + Codex running server-side on a
dedicated AgentCore Runtime ("safe to close your laptop").
Deploys 1 runtime (image), a VPC + EFS workspace, 1 DynamoDB
table (agentcore-hub-cloud-code-sessions). ~10-15 min
(NAT gateway + EFS). Depends on: Core only — independent of
Workflow/Evaluations. Needs Docker (Colima) for the image build.Then ask via AskUserQuestion:
- question: "This application is modular — you can deploy as many or as few modules as you'd like depending on your use case and the time you have for install. You can deploy additional modules later by re-running /agentcore-hub:setup. Which modules would you like to install?"
- header: "Modules"
- options (single-select; offer "Other" for a custom combination):
- Core only — Explore agents already deployed in your account. No new AWS resources are created. Fastest path to a working UI.
- Core + Builder — Adds chat-driven agent creation (
/build). Deploys 1 AgentCore harness runtime + 1 Lambda. ~3–5 min. - Core + Builder + Workflow (Recommended) — Adds the full multi-agent pipeline. Deploys ~15 AgentCore runtimes, 5 Lambdas, 3 DynamoDB tables, and an S3 bucket. ~15–20 min.
- Everything — #3 + the self-improvement evaluation loop + Cloud Code (the cloud coding agent). ~30–40 min total.
Map the answer to a MODULES set in the canonical order core → builder → workflow → evaluations → cloud-code. Enforce dependency order: if the user picks Evaluations they must also have Workflow; if they pick Workflow they must also have Core. Cloud Code depends only on Core — it can be added to any selection (or installed alone: core + cloud-code), since it's independent of the Workflow/Evaluations chain. If the user wants Cloud Code without the full pipeline, accept that via "Other".
Hard rule: never reorder the modules within the dependency chain.
run-module.shruns them in the order you give it, and downstream modules read state written by earlier ones (e.g., Evaluations subscribes to log groups created by Workflow's runtime fleet). Cloud Code has no such ordering dependency — run it any time after Core.
Q3 — Ticket store (skip if Workflow not in MODULES)
- question: "The Workflow module uses tickets to orchestrate and assign work between agents. Will you use Jira Cloud, or our built-in DynamoDB system?"
- header: "Ticket store"
- options:
- Built-in DynamoDB (Recommended for first run) — We create the
agentcore-hub-ticketstable for you. No external accounts, no extra credentials. Tickets are visible in the app's Tickets tab. - Jira Cloud — Tickets are created and updated as Jira issues in your existing project. You'll need your site URL, email, API token, and project key. Best fit if your team already lives in Jira.
- Built-in DynamoDB (Recommended for first run) — We create the
If they pick Jira, do a follow-up AskUserQuestion (or accept free text via "Other") for JIRA_SITE_URL, JIRA_EMAIL, JIRA_API_TOKEN, JIRA_PROJECT_KEY. Treat these as secrets — do not echo them back, do not write them anywhere except .env.local.
Q4 — Workflow runtime topology (skip if Workflow not in MODULES)
Before asking, print this framing so the user understands what's happening and where it can go:
The Workflow module ships 14 personas across four pipeline phases:
• requirements (1) – analyst that scopes the work and creates tickets
• design (8) – iOS, Android, frontend, backend, security, legal,
localization, analytics
• development (3) – frontend, backend, API
• verification + review (2) – QA, CI
How those personas map to AgentCore runtimes is up to you. We default to ONE
runtime that hosts all 14 personas: per-persona prompts live in S3 and the
runtime loads the right one per invocation, caching it for the life of the
microVM. Edit a prompt in S3 and the next session picks it up — no redeploy.
The setup is designed to grow. When a team is ready to own their agent —
different model, separate scaling, isolated logs and metrics — re-run
/agentcore-hub:setup and split that persona out. The end-state most teams reach is one runtime per
team-owned agent. You don't have to start there.Then ask via AskUserQuestion:
- question: "Workflows are executed by agents. You can use one agent with 14 personas, 4 agents with assigned personas per phase, or 14 individual agents. We recommend starting with 1 agent / 14 personas to limit overhead and expand as the need for different tools and customizations grow. Which would you like?"
- header: "Runtimes"
- options:
- 1 agent, 14 personas (Recommended) — One AgentCore runtime hosts every persona. Per-persona prompts live in S3 and load per invocation. Cheapest to run, fastest to deploy (~3 min), and easiest to evolve: edit a prompt in S3 and the next session picks it up — no redeploy. You can split agents out later as needs grow.
- 4 agents, one per pipeline phase — Separate runtimes for requirements, design, development, and QA+CI. Each phase can scale, log, and (eventually) run a different model independently. ~6 min to deploy.
- 14 agents, one per persona — Full isolation. Per-agent model/config, separate log groups, separate scaling. Best when teams already own individual agents and need full customization. ~10–15 min to deploy.
Save the answer as workflow_runtimes (1, 4, or 14) in the answers blob. apply-env.sh writes it to .env.local as WORKFLOW_RUNTIME_COUNT. run-module.sh workflow invokes deploy/runtime-agent/deploy-topology.sh, which branches on this value:
1→ deployagentcore_hub_requirements_analystas the shared runtime; write its ARN into all 14runtimeArnfields insrc/config/agents.json.4→ deployrequirements_analyst,backend_designer,backend_dev, andqa_verifieras anchors; map each persona to its phase's anchor (verification + review both go to the QA anchor).14→ delegate to the existingdeploy-fleet.sh(one runtime per persona).
In every mode deploy-topology.sh syncs all 14 prompts to s3://$ARTIFACT_BUCKET/prompts/ and uploads the rewritten agents.json to s3://$ARTIFACT_BUCKET/config/agents.json — that's how the runtime resolves per-persona prompts and how the orchestrator/Jira Lambdas (DL-023) discover the right runtimeArn at cold start.
No application code changes are required across these three modes — the orchestrator resolves per-agent via
agents.jsonruntimeArn, and the runtime resolves per-persona prompts viaprompts/{agentId}.txt. Topology is purely a deploy + mapping concern.
Q4b — Deploy mode (skip if Workflow not in MODULES)
Before asking, print this framing so the user understands what each mode contains and the tradeoff:
Workflow agents need a Linux container to run in. Two modes are available:
Lightweight (default) — Stock python:3.10 container provided by AgentCore.
On cold start each agent downloads Node.js and the
Claude Code CLI into /tmp (3–10s tax). No Playwright
browser, no curated skills/plugins. ~3 min to deploy.
Best for first-time setup, demos, and any persona
that doesn't need browser automation or pre-loaded
domain expertise.
Robust — Custom container baked from this repo's Dockerfile.
Pre-installs Node.js, Claude Code CLI, Playwright +
Chromium (~150MB), and ~262 curated SKILL.md files
across 10 personas (frontend, iOS, Android, backend,
API, analytics, QA, etc.). Faster cold starts, full
browser automation, persona-matched skills auto-load
on description match. Adds a one-time ~6 min Docker
build + ECR push before the agent loop runs.
You can switch modes later by re-running /agentcore-hub:setup — it's just an
env var (DEPLOY_MODE=lightweight|robust) read by deploy-fleet.sh.Then ask via AskUserQuestion:
- question: "Which deploy mode do you want for the Workflow agents? Lightweight is the smallest install and works for most personas; Robust gives every agent Playwright Chromium and curated skill packs but adds a Docker build step."
- header: "Deploy mode"
- options:
- Lightweight (Recommended) — Stock container, fast deploy, no extra tooling baked in. Cold-start tax of 3–10s as Node + claude-code self-install on first invocation per microVM.
- Robust — Custom Docker image with Playwright Chromium + 262 curated skills baked in. Adds ~6 min for the one-time Docker build & ECR push. Requires Docker running locally (Colima or Docker Desktop).
Save as deploy_mode (lightweight or robust) in the answers blob. apply-env.sh writes it to .env.local as DEPLOY_MODE. deploy-fleet.sh reads DEPLOY_MODE; in robust mode it builds the Dockerfile (deploy/runtime-agent/Dockerfile + install-skills.sh), pushes to ECR (repo runtime-agent), and points CreateAgentRuntime/UpdateAgentRuntime at the resulting containerUri directly.
If the user picks Robust, do a quick pre-flight check:
docker info >/dev/null 2>&1 || echo "DOCKER_NOT_RUNNING"If Docker isn't running, surface this immediately and ask the user to start Docker Desktop or Colima before continuing — the build step will fail otherwise.
AWS MCP server tip: if the user has Claude Code's AWS MCP server installed (the
aws-coreplugin in theagent-toolkit-for-awsmarketplace), most of the AWS troubleshooting here is one tool call away (aws___call_aws,search_documentation, etc.). It's not required, but it's the smoothest path. If they haven't installed it, point them atagentcoreplugin install instructions in the README and continue without it.
Q5 — AWS target
Use the pre-flight detection result:
If
aws sts get-caller-identitysucceeded, default the option label toUse detected: <account>/<region>.If it failed, the only option is "Configure credentials and re-run" — abort the skill with a pointer to the README's prerequisites section.
question: "This installer creates real AWS resources in the account your credentials point to. We detected
<account>in<region>. Use this account, or switch to a different AWS profile?"header: "AWS target"
options:
- Use detected:
<account>in<region>(Recommended) — Continues with the credentials already in your environment. - Use a different AWS profile — I'll name a profile from
~/.aws/credentialsand we'll switch to it. - Cancel — Stop without creating anything.
- Use detected:
Set AWS_PROFILE and AWS_REGION for every subsequent shell call.
Q6 — Deploy target
Before asking, print this framing so the user understands the trade-offs:
The AWS infrastructure (Lambdas, agents, DynamoDB tables, S3) deploys the
same either way. The only question is where the Next.js front-end runs.
Locally (npm run dev)
Fastest to iterate. App reads .env.local on your laptop.
⚠ If you chose Jira Cloud for tickets: Jira sends webhooks over the
public internet, so localhost is unreachable. You'll need an
ngrok / Cloudflare Tunnel / similar to expose port 3000, or your
ticket transitions won't trigger workflows. (DynamoDB tickets work
either way — they trigger via DynamoDB Streams inside AWS, not
webhooks.)
⚠ If your org blocks outbound tunneling tools, App Runner is simpler.
AWS App Runner
Public HTTPS URL, auto-scales, your team can reach it. Builds a
container from this repo, pushes to ECR, deploys behind an HTTPS
endpoint. Adds ~5 min and ongoing cost (App Runner + ECR storage).
Jira webhooks "just work" because the URL is publicly reachable.
Bring-your-own container
You already have a deploy target (ECS, EKS, Fargate, your own
container host). Skip the App Runner build, and we'll record a
placeholder DEPLOYMENT_URL you can update yourself in .env.local
once your service is live.
Skip
Only create AWS infra; don't touch the Next.js app at all.- question: "Where would you like to deploy the Next.js app? The AWS infra deploys the same in every option — this is just where the front-end runs."
- header: "App host"
- options:
- Locally (Recommended for first run) — Run
npm run devafter setup. Fastest to iterate. ⚠ With Jira tickets, you'll need to exposelocalhost:3000via ngrok/Cloudflare Tunnel for webhooks to reach you. - AWS App Runner — Public HTTPS URL, auto-scaling, no tunneling needed for Jira. Adds ~5 min and ongoing cost.
- Bring your own container — Skip the build; you deploy the container yourself (ECS/EKS/Fargate/etc.). We'll set a placeholder
DEPLOYMENT_URLyou'll update later. - Skip the app — Only create AWS infra. You'll run the app yourself later.
- Locally (Recommended for first run) — Run
Q7 — GitHub integration (skip if Workflow not in MODULES)
- question: "The Workflow agents push branches and open pull requests as part of the pipeline. How should they authenticate to GitHub?"
- header: "GitHub"
- options:
- Personal Access Token (Recommended) — Paste a GitHub PAT with
repo+workflowscope. Simplest path; the agents push and open PRs as you. Stored in.env.localonly. - Custom MCP server — Point us at a GitHub MCP server JSON config (e.g., your org runs one with SSO). Use this if a raw PAT isn't allowed by policy.
- Skip — The workflow still runs, but stops at "ready for PR" without pushing. Use this to do a dry run before committing real GitHub credentials.
- Personal Access Token (Recommended) — Paste a GitHub PAT with
Q7b — GitHub workspace repo (skip if Workflow not in MODULES or Q7 was Skip)
- question: "Which GitHub repo should AgentCore use as its workspace? This is where agents push branches and open PRs during the workflow pipeline."
- header: "GitHub repo"
- options:
- Type
owner/repo— I'll enter the GitHub owner and repository name (e.g.,myorg/my-project). - Skip for now — Use the default test repo (
octocat/Hello-World). You can updateGITHUB_OWNERandGITHUB_REPOin.env.locallater.
- Type
If the user provides owner/repo, split on / and save as github.owner and github.repo in the answers blob. apply-env.sh writes them to .env.local as GITHUB_OWNER and GITHUB_REPO. These are read by deploy/config.sh to build FLEET_REPO_URL and by deploy/runtime-agent/verify-fleet-invoke.py for GitHub MCP tool tests.
Q8 — Confirm
Print a recap of every choice plus the exact list of scripts that will run, then ask:
- question: "Ready to start the install? This creates real AWS resources in
<account>(<region>). The full pipeline takes about 15–20 minutes; smaller selections are faster. We'll pause and verify after each phase before moving on." - header: "Confirm"
- options:
- Yes, run it — Begin the install. We'll show progress per phase.
- Show me the exact script list first — Print every script that will run, then come back to this question.
- Cancel — Stop without creating anything.
After confirmation: write .env.local
Build a JSON answers blob and pipe it to bin/apply-env.sh:
cat > /tmp/agentcore-hub-answers.json <<'EOF'
{
"brand_name": "Bob's AI Hub",
"modules": ["core", "workflow"],
"ticket_provider": "dynamodb",
"workflow_runtimes": 1,
"aws_account": "...",
"aws_region": "us-east-1",
"aws_profile": "default",
"deploy_target": "local",
"github": { "mode": "pat", "pat": "...", "owner": "myorg", "repo": "my-project" },
"jira": null
}
EOF
.claude-plugin/bin/apply-env.sh /tmp/agentcore-hub-answers.json
rm /tmp/agentcore-hub-answers.jsonapply-env.sh is the one place that writes .env.local. The skill does not write env vars by hand.
Run modules in order
Evaluations is deferred until after the deploy-target step because itsprd-submitter Lambda needs DEPLOYMENT_URL (the App Runner URL) to know where
to POST workflow-start requests. Run modules in this order:
core→builder→workflow(skip whichever the user didn't pick)- Deploy target step (Local / App Runner / Bring-your-own / Skip)
evaluations(if selected)
For each module run:
.claude-plugin/bin/run-module.sh <module>
.claude-plugin/bin/verify-module.sh <module>If verify-module.sh exits non-zero, stop. Show the user the verification output and ask via AskUserQuestion:
- question: "Verification of
<module>failed. What do you want to do?" - options: Retry, Skip this module and continue, Abort the whole setup
Long-running deploys (build-and-push.sh, deploy-fleet.sh, App Runner deploy) should be delegated to the deploy-runner subagent so their multi-MB output doesn't dominate this conversation. Pass the subagent the exact script path and the env vars it needs.
Deploy target step (between workflow and evaluations)
After Core/Builder/Workflow verify clean and before running Evaluations:
- Local (
local): print "Runnpm run devto start the app at http://localhost:3000." SetDEPLOYMENT_URL=http://localhost:3000in.env.local. If the user picked Jira tickets, also remind them: "Jira webhooks can't reachlocalhost— expose port 3000 with ngrok / Cloudflare Tunnel, then updateDEPLOYMENT_URLto the public URL or your ticket transitions won't trigger workflows." - App Runner (
apprunner): run./deploy/apprunner/deploy.sh. This script idempotently creates the ECR repository, theAppRunnerECRAccessRoleandagentcore-hub-apprunner-instanceIAM roles, builds and pushes the Docker image, and creates (or updates) the App Runner service. It setsHOSTNAME=0.0.0.0andPORT=8080as runtime env vars to prevent the health-check bind issue (see Dockerfile comment). Once the service is RUNNING, the script captures the App Runner URL and persists it asDEPLOYMENT_URLin.env.local(same sed-or-append pattern asBUILDER_AGENT_ID). Requires Docker running locally. - Bring-your-own (
byo): don't build or push anything. WriteDEPLOYMENT_URL=https://placeholder.exampleto.env.localand tell the user: "UpdateDEPLOYMENT_URLin.env.localonce your service is live so prd-submitter and Jira webhooks know where to reach the app." If Evaluations was selected, surface this warning prominently — prd-submitter is being deployed with a placeholder URL. - Skip (
skip): skip both the deploy and theDEPLOYMENT_URLwrite. If Evaluations was selected, warn the user that prd-submitter will be deployed with a placeholder URL and they must update it manually.
Jira webhook setup (after deploy-target, if TICKET_PROVIDER=jira and deploy_target is NOT local)
When the ticket provider is Jira and the app is deployed to a publicly reachable URL (App Runner or BYO), automate the Jira webhook by running:
./deploy/apprunner/setup-jira-webhook.shThis script uses the Jira legacy admin endpoint (/rest/webhooks/1.0/webhook) which accepts PAT-based basic auth. It idempotently deletes any stale agentcore-hub-workflow webhooks and creates a new one pointing at DEPLOYMENT_URL/api/jira/webhook filtered to JIRA_PROJECT_KEY. All credentials are read from .env.local.
For deploy_target=local, skip the automated webhook and remind the user: "Jira webhooks need a public URL. Once you expose localhost via ngrok/Cloudflare Tunnel, update DEPLOYMENT_URL in .env.local and run ./deploy/apprunner/setup-jira-webhook.sh."
After this step, run Evaluations (if selected) so it picks up the freshly written DEPLOYMENT_URL.
Final gate: end-to-end test suite
After every selected module verifies clean and the deploy-target step is done, run the full Playwright test suite. This is the only signal that the install is actually working — existence checks and HTTP 200s are not proof of function.
The repo exposes npm run test:full, which runs ./tests/run-all.sh --full:
- Tab tests (
tests/tab-*.spec.ts) - API smoke (
tests/e2e-api-routes.spec.ts) - Real end-to-end workflow (
tests/e2e-workflow-full.spec.ts)
Branch on deploy_target:
local: before running the suite, ensure the dev server is up. Ifnpm run devis not already running on port 3000, start it in the background and wait untilhttp://localhost:3000returns 200. SetDEPLOYMENT_URL=http://localhost:3000in the test env. Then delegatenpm run test:fullto thedeploy-runnersubagent (the multi-MB Playwright output would otherwise dominate the conversation).apprunner: confirmDEPLOYMENT_URLis the App Runner URL (was just persisted by the deploy-target step). Pass it asDEPLOYMENT_URLenv var tonpm run test:full. Delegate todeploy-runner.byoorskip: the test suite needs the app running and there is no app to point at. Tell the user honestly:"I can't run the end-to-end test suite — your container isn't deployed yet (or you chose Skip). Once your service is live and
DEPLOYMENT_URLin.env.localpoints at it, run this from the repo root to validate the install:DEPLOYMENT_URL=<your-url> npm run test:full. Until that passes, treat the install as unverified."Print a yellow warning and proceed to the success summary, but mark the install as "deployed but not validated".
On test failure: surface the failing test name and the failure message from the Playwright output. Do not try to fix the failure yourself — ask the user via AskUserQuestion:
- question: "End-to-end test
<test name>failed:<short error>. What do you want to do?" - options: Retry the suite, Skip and finish anyway (the install is unverified), Abort
On test pass: this is when you declare the install complete. Move any "install complete" copy here. Before this point, the install is "deployed but unvalidated."
Re-runs
The user may run /agentcore-hub:setup more than once. Before any module runs, run-module.sh should detect what already exists and skip steps that are already done (the underlying scripts are idempotent — they exit 0 if the resource exists). Never wipe .env.local. Never delete AWS resources.
Hard rules
- AWS_PROFILE / AWS_REGION: every
awscall must pass them through. Never assumedefault. - Secrets: Jira tokens / GitHub PATs go from the prompt straight into
.env.local. Do not log them, do not echo them, do not write them to a temp file that lingers. - No new infra: if a user request would require a script that doesn't exist in
deploy/,scripts/, orlambda/<name>/deploy.sh, refuse and link toREADME.md/docs/MODULES.md. - Real errors only: if a script fails, show the user the actual stderr and the script that produced it. No "something went wrong, check logs."
- No README duplication: "next steps" output should link to
README.mdanddocs/MODULES.mdrather than restating them. - No in-session script authoring: when
verify-module.shreports a missing resource, you may NOT write a new deploy script, IAM policy, or aws CLI patch to fix it in this session. Stop, surface the gap to the user, and offer Retry / Skip-this-module / Abort. Real fixes belong in a PR to the repo so the next install benefits — not in the install session that found the gap. - Do not declare success early: the install is not complete until
npm run test:fullpasses. Existence checks and HTTP 200s are not proof of function. If the test suite was skipped (deploy_target wasbyoorskip), the install is "deployed but unvalidated" — say that, don't say "complete".