Skip to content

feat(vercel-to-aws): post-Estimate what-if workshop checkpoint - #153

Merged
icarthick merged 34 commits into
awslabs:mainfrom
herosjourney:feat/vercel-what-if-workshop
Jul 20, 2026
Merged

feat(vercel-to-aws): post-Estimate what-if workshop checkpoint#153
icarthick merged 34 commits into
awslabs:mainfrom
herosjourney:feat/vercel-what-if-workshop

Conversation

@herosjourney

@herosjourney herosjourney commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds an optional what-if workshop checkpoint after Estimate for vercel-to-aws: freeze discovery, edit traffic/outcome/region/Multi-AZ/arch knobs, refresh Recommend (or record an explicit fired_rule: workshop_override) + Estimate, snapshot up to 5 scenarios, compare side-by-side.
  • Transcript-safe Clarify edits (workshop_note preserves the founder's original answer; recommend reasons prefix knob-sourced signals with "workshop assumption:").
  • Outcome C override gated on separable and requires a backend-shape pick, so Generate is never handed an undispatchable recommendation.
  • Renames the report to migration-report.html (cross-skill consistency) and renders the scenario table in it; per-scenario shareable calculator.aws links (best-effort, never blocks).

Motivation: same as #152 — Transform-style what-if for a live SA workshop, without re-running discovery. Vercel's twist is that the traffic knob legitimately changes the recommendation (A vs B), so the refresh re-runs the precedence engine, not just the cost engine.

Relationship to other PRs

Test plan

  • Fixtures: fixtures/vercel-workshop/ (seed → outcome-B/x86 reprice after-state); python3 check_expected_workshop.py after-outcome-b-x86 → PASS
  • fixtures:check green on the branch (seeds carry the full declared phase set)
  • mise run build green (branch previously failed fmt:check/markdownlint/shared:check — fixed here, including moving the arm64 rates + workshop schema additions from vendored copies into canonical skills/shared)
  • Full workshop-loop fresh-agent replay (enter → override outcome → apply → compare → exit) — demo script in the fixture README

Made with Cursor

Logan Kleier and others added 26 commits July 14, 2026 17:20
…w migration-to-aws skill: an honest Vercel-to-AWS assessment for Next.js apps (not a full migration plan). Built on the phase DSL (same architecture as heroku-to-aws), 5 backbone phases + 1 optional scaffold checkpoint: - PreScan -> Discover -> Clarify -> Recommend -> Report, with an optional Scaffold checkpoint - Discover computes a Coupling Score and 10 named Pre-Flight Checks unconditionally, before Recommend has run - Recommend is a fixed-precedence, three-outcome engine (OpenNext/SST, ECS Fargate, or a Vercel+AWS Hybrid) - every recommendation traces to exactly one rule, never a judgment call - Report renders a validated HTML assessment (new scripts/validate-assessment-report.py + pytest suite + reference/stub fixtures), with outcome-filtered findings, a reader-vocabulary rule, and a cost-labeling rule enforced by the validator - Scaffold (optional) emits a thin IaC skeleton matching the recommended outcome - SST/Terraform for OpenNext, Terraform-only for Fargate or the Hybrid path - and defaults compute to Graviton (ARM64) where SST/Terraform expose the option - assessment-state.json: a skill-owned resumability ledger (independent of the vendored .phase-status.json) supporting incremental, effort-for-confidence input collection across multiple sessions Registers the skill in the plugin's README, the top-level migrate README, and the Claude/Codex/Cursor plugin manifests. Verified: frontmatter validator (0 problems), pytest (39/39), dprint check and markdownlint-cli2 clean, reference fixture passes the validator (REPORT_OK), stub fixture fails with actionable errors (REPORT_FAIL).
…hipped) Per the precedent set in 033669c (removed heroku-eks-support, heroku-to-aws-migration, and migration-telemetry-sharing spec dirs from a prior PR), .kiro/specs/ is local Kiro working material, not project documentation this repo ships - no .kiro/specs/ directory exists anywhere on main today. The requirements/design/tasks docs used to drive this skill's build don't belong in the PR.
…nerate phase Add a mandatory estimate phase (three-tier AWS cost projection vs. Vercel spend) and promote the optional scaffold checkpoint into a mandatory generate phase producing production-ready Terraform, including: - baseline.tf (GuardDuty, CloudTrail, IMDSv2, EBS encryption, budget alerts, Access Analyzer, remote-state backend, compliance-conditional Config/SecurityHub) - Full VPC with public/private subnets, NAT gateway, route tables - Outcome-specific compute: SST/OpenNext (A), Fargate+ALB+CloudFront (B), API Gateway+Lambda (C-A), Fargate backend (C-B) - Peripheral Terraform: RDS (Postgres), ElastiCache (KV), S3 (Blob), EventBridge (Cron) - Numbered migration scripts (01-06) with dry-run defaults - MIGRATION_GUIDE.md with phased timeline, verification, rollback, Go/No-Go gates - generation-warnings.json for unpriced/unmapped services Backbone changes: prescan -> discover -> clarify -> recommend -> estimate -> generate -> report -> complete (was: prescan -> discover -> clarify -> recommend -> report -> complete + scaffold checkpoint) Clarify extended with Q6 (Vercel spend), Q7 (database size), Q8 (compliance) to feed the estimate and generate phases. Vendored shared files: aws-infra-pricing.json, estimation-infra.schema.json, complexity-tiers.json — registered in sync-vendored-shared.ts auto-discovery. Breaking change: existing .phase-status.json files from the old backbone are not compatible; re-run from prescan.
…port, validator, READMEs, scaffold deletion)
…nerate-phase

# Conflicts:
#	.claude-plugin/marketplace.json
#	migrate/README.md
#	migrate/plugins/migration-to-aws/.claude-plugin/plugin.json
#	migrate/plugins/migration-to-aws/.codex-plugin/plugin.json
#	migrate/plugins/migration-to-aws/.cursor-plugin/plugin.json
#	migrate/plugins/migration-to-aws/README.md
…gration-skill

# Conflicts:
#	.claude-plugin/marketplace.json
#	migrate/README.md
#	migrate/plugins/migration-to-aws/.claude-plugin/plugin.json
#	migrate/plugins/migration-to-aws/.codex-plugin/plugin.json
#	migrate/plugins/migration-to-aws/.cursor-plugin/plugin.json
#	migrate/plugins/migration-to-aws/README.md
… the worker contract Three architecture contradictions made the skill unexecutable as written: prescan declared _interactive:false + _exec:rw while its collect fragment converses with the founder (token request), runs next build, and calls the Vercel API; four of discover's dispatched fragments needed shell or network the rw worker (Read/Grep/Glob/Write/Edit) does not have; and the token, collected interactively and never persisted, could not reach a dispatched worker at all. Retrofit (the pattern proven on heroku/gcp live discovery, awslabs#148/awslabs#149): - prescan runs INLINE (_interactive: true, _exec removed) — its work is conversational + shell + network by nature; scope boundary corrected (the Tier 1 build-health attempt belongs to prescan-collect per Requirements 1.1-1.2) - NEW discover-capture.md: main-window pre-work owning ALL shell/network — adapter/manifest build capture, a GET-only 8-endpoint API whitelist (Vercel tokens cannot be scoped read-only, so the whitelist IS the read-only guarantee), env keys projected to names before touching disk, headers-only probe capture, manifest.json index; VERCEL_TOKEN lives in an env var in the main window only - discover-adapter/manifests/api/probe become parse-only fragments reading capture/; triggers keyed to the capture manifest; new postconditions (no env values/token material anywhere; coupling items carry confidence) - prescan-collect token request rewritten per Vercel's token docs: read-only tokens do not exist — ask for project-scoped + shortest expiration, state the GET-whitelist enforcement honestly, give the revoke command - Vercel MCP positioned as optional read-only enrichment (runtime logs, access links) with the purchase-tool caution — not the discovery backbone Validated: fixtures/vercel-capture/ replay set (manifest-fallback path, ISR cross-check, unclassified Route Handlers, skipped crons/usage, names-only env keys) + fresh-agent Discover replay: HANDOFF_OK, zero network/build/token, check_expected_discovery.py PASS. Also: shared:sync refreshed the stale vendored INTERPRETER.md this branch carried.
…docs - Domains endpoint corrected to the documented /v9 (was /v5) - Env row note strengthened: the documented response schema carries value/ vsmValue/legacyValue fields even with decrypt=false — the key-name pipeline projection is the REAL protection, not the query param - Crons and storage rows reworded honestly: neither path is in the public REST reference; discover the GET endpoints via 'vercel api list' (the CLI's beta OpenAPI-backed api command), else record skipped — vercel.json and env-name/ dependency signals remain the fallbacks - Transport note added: prefer 'vercel api' (session/token auth, --paginate for the 100-per-page list endpoints, OpenAPI endpoint discovery), raw curl with manual pagination.next handling as fallback - Rate limits documented as a non-issue (200-1000 reads/min per endpoint vs this capture's small volume) - Fixture manifest endpoint strings synced
…fied whitelist The prior commit's message claimed this sync but the edit had failed on formatting drift — domains now /v9, crons/stores rows use the OpenAPI-discovered wording.
…-aws-generate-phase

# Conflicts:
#	.claude-plugin/marketplace.json
#	migrate/README.md
#	migrate/plugins/migration-to-aws/.codex-plugin/plugin.json
#	migrate/plugins/migration-to-aws/.cursor-plugin/plugin.json
#	migrate/plugins/migration-to-aws/README.md
…ical The merge from main brought the July 2026 canonical pricing update; the vercel skill's vendored copy was stale and failing shared:check.
…iew follow-up: rows 6-7 (crons/stores) stay unpinned because Vercel does not document those paths -- pinning guesses would be fake precision that breaks silently. But the discovery step was looser than the pinned rows. New constraints: the resolved operation must be GET in the spec, its path must contain the row's subject segment (crons / stores|storage), the exact resolved path is recorded verbatim in the manifest entry with discovered_via: 'vercel api list' (audit trail), and no match means skipped -- never a close-enough substitute. Fixture manifest updated to model the audit fields.
…-aws-generate-phase (rows 6-7 discovery constraints)
…ssembler Review follow-up + parity fix: heroku (generate-terraform.md Step 12) and gcp (validation-report degraded-offline convention) both validate their generated Terraform; vercel's generate had static postconditions only. New assembler Step 6: static HCL checks (syntax, reference integrity, variable completeness, output references), then terraform init -backend=false && terraform validate when the binary is available. Failures and skipped runs land in generation-warnings.json with a founder-facing action line -- never a generation halt, matching the degraded-offline convention of the other two skills.
…s The capture manifest's build.files names three .next build manifests (routes/prerender/app-path-routes) that were never committed -- the validated replay ran against scratch copies. Reconstructed exactly per expected-discovery.json and discover-manifests.md: /blog/[slug] in dynamicRoutes with two prerendered entries at initialRevalidateSeconds 3600 (genuinely ISR), / static, /dashboard absent from prerender-manifest (dynamic), /api/checkout only in app-path-routes-manifest (Route Handler, unclassified by page manifests -> LOW-confidence dynamic). Preview keys are labeled fixture placeholders, not secrets.
… repo-root .gitignore's global build/ rule silently dropped the three canned .next manifests from the previous commit. Scoped negation inside the fixture directory re-includes them — they are committed test data mirroring the real capture layout, not build output.
…endering Fresh-agent replay against the restored build-manifest fixtures surfaced the ambiguity: staticRoutes/dynamicRoutes distinguish fixed paths from [param] segments -- a fixed-path page that renders per-request still sits in staticRoutes, and the replay classified /dashboard as static because of it. The rendering disposition comes from prerender-manifest membership: numeric initialRevalidateSeconds = isr, false = static, absent = dynamic. Spelled out the resolution table and extended the never-infer rule to cover static-from-staticRoutes as well as isr-from-revalidate-exports.
…ebreak paths Review follow-up: Discover had replay fixtures and an asserter; Estimate and Generate were spec-only. Now the whole pipeline is machine-checkable. Spec gap found while seeding: estimate had no handling for the unresolved [A,B] tiebreak that recommend legitimately produces and generate explicitly asks the founder about. Estimate is non-interactive, so it now prices BOTH candidate outcomes: projected_costs (and everything downstream) = Outcome A, a tiebreak_alternative section = Outcome B with its own Property-16 check, and mandatory tiebreak honesty in financial_summary/path_label (both balanced totals + how it gets resolved). The A-vs-B cost delta is itself a resolving input. Fixtures: seed-estimate/ and seed-generate/ are harvested from a validated fresh-agent chain replay (discover->clarify->recommend under documented-default answers, Q6 spend $200-1000, genuine [A,B] tiebreak; discover asserter PASS). expected-estimate.json pins the $600 midpoint baseline, both-path pricing, and comparison arithmetic; expected-generate.json pins the artifact set, OpenNext/Fargate mutual exclusion, provider pin, no-placeholder scan, compliance-none baseline, estimated-service coverage, and the Step 6 validate contract (pass = no warning; fail/skip = exactly one entry with a founder action). Both asserters PASS against fresh-agent replays of their phases (the generate replay's terraform init -backend=false + validate genuinely passed via a local provider cache). seed/.phase-status.json gains the estimate/generate phases this branch declares.
…ase Caught by the new fixtures-check tool: the skill declares 6 phases (incl. scaffold) but the replay seed's .phase-status.json listed 5 -- phase-status.schema.json requires one entry per declared phase. (On the stacked generate-phase branch the seed already tracks that branch's estimate/generate phase set.)
…; seed keeps this branch's estimate/generate phase set
…g; docs/spec cleanups Review-observation batch, replay-validated: - Q7 confirm-first: when discovery captured the postgres store's sizeBytes, Clarify derives the band (decimal GB) and presents it for founder confirmation instead of asking cold -- one less question per run, and the founder's correction wins when given. The phase postcondition now states the rule precisely: no COLD question whose answer discovery determined; confirmations are the sanctioned form. Validated by a fresh-agent discover->clarify replay (Q7 presented as a confirmation of band B from the ~3 GB store; HANDOFF_OK both phases). - Case fix folded back from that replay: five files matched peripherals[] against 'Postgres' while the discover schema emits lowercase 'postgres' -- a literal match would wrongly skip Q7, the DB migration script, and the has_databases complexity input. All now lowercase + case-insensitive. - Pricing hierarchy row 4 'estimated' (mirrors the heroku change on awslabs#150): the documented home of the services_by_source.estimated bucket; Lambda's formula constants are the canonical example. - generate-docs: guide step numbers count existing scripts (the file set is conditional, so numbering gaps are normal and must be called out), and a Provision Infrastructure slot between scripts 01 and 02 (terraform apply + sst deploy) -- both folded back from the generate replay. - SKILL.md: estimate/generate are read-only consumers of assessment-state.json (no phase file specifies a write; none should be improvised). - clarify.md: repaired the malformed declined-answer error-table row.
Freeze discovery/coupling/preflight and reprice traffic/outcome/region/arch
via Recommend+Estimate inner runs with scenario snapshots. Outcome overrides
use fired_rule workshop_override (declared contract) with transcript
workshop_note provenance. Stacked on the generate-phase skill (awslabs#144).

Co-authored-by: Cursor <cursoragent@cursor.com>
Port INTERPRETER deferred-advance checkpoint resume and vercel SKILL workshop
resume rule so warm starts never re-run Estimate while workshop is unresolved.

Co-authored-by: Cursor <cursoragent@cursor.com>
@herosjourney

Copy link
Copy Markdown
Contributor Author

Fresh-agent replay + resume fix

Resume rule (bfb1a56)

  • Shared INTERPRETER.md deferred-advance checkpoint resume (vendored into vercel)
  • vercel-to-aws/SKILL.mdWorkshop resume (mandatory) + warm-start exception

Fresh-agent replay (house bar)

Agent from seed/ only (no after-outcome-b-x86 peek) → enter workshop → spiky + outcome B + x86_64 Apply & reprice → scenario-002.

python3 check_expected_workshop.py /tmp/replay-vercel-fresh seed
→ PASS — expected-workshop.json assertions hold
  • Discovery bytes frozen
  • fired_rule: workshop_override (no rule_id); Q1 workshop_note keeps original sustained
  • Balanced reprice; current_phase: estimate, workshop in_progress
  • Transcript agent: Vercel replay

Logan Kleier and others added 2 commits July 19, 2026 18:07
Add conditional what-if-scenarios section (workshop compare table) and enforce
it in validate-assessment-report.py when scenarios/index.json has ≥2 entries.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@herosjourney

Copy link
Copy Markdown
Contributor Author

Stakeholder deliverable: what-if section in assessment report

  • report-render.md: conditional what-if-scenarios after cost comparison
  • validate-assessment-report.py: requires the section when ≥2 scenarios exist (--migration-dir)

Commit: bc8b923

….html

Unify the stakeholder HTML filename with GCP and Heroku. Validator script
name unchanged (validate-assessment-report.py) to avoid colliding with GCP's
validate-migration-report.py.

Co-authored-by: Cursor <cursoragent@cursor.com>
@herosjourney

Copy link
Copy Markdown
Contributor Author

Filename unify

Vercel Report now writes migration-report.html (was assessment-report.html) — same path as GCP/Heroku.

Validator remains scripts/validate-assessment-report.py (Vercel-specific gate; avoids colliding with GCP validate-migration-report.py).

…ting CI failures on this branch, all fixed: (1) eight files committed with dprint drift (fmt:check); (2) markdownlint MD025/MD029/ MD031 — the fixtures README second H1, report-render's scenario table breaking an ordered list, workshop-assemble's fenced block splitting a list, workshop-refresh's unspaced fences; (3) shared:check — the workshop schema additions (estimation-infra workshop metadata) and the Fargate/EC2 arm64 rates were edited in the VENDORED copies instead of the canonical skills/shared files. Ported vendored -> canonical and ran shared:sync (heroku's vendored copies pick up the same additive changes). mise run build now exits 0.
@herosjourney

Copy link
Copy Markdown
Contributor Author

Verified + fixed on this branch (64176ca): fixtures-check and the workshop asserter pass, and the scenario render spec correctly sources display columns from per-scenario copies. Branch now passes mise run build — pre-existing failures fixed: eight files with dprint drift; markdownlint MD025/MD029/MD031; and shared:check — the workshop schema additions and the Fargate/EC2 arm64 rates had been edited in the VENDORED copies instead of canonical skills/shared (the exact drift mode that produced the cached_stale bug). Ported vendored → canonical and synced; heroku's vendored copies pick up the same additive changes. Note for merge ordering: this branch predates #150's cached_stale enum addition to the same schema file — whichever merges second has a small, obvious conflict.

…rio workshop-refresh 6b: after each snapshot, best-effort build_estimate via the aws-pricing-calculator MCP -> shareable calculator.aws URL stored as estimation_summary.calculator_url (PRIMARY outcome's Balanced services; tiebreak_alternative skipped; null + one chat note on failure; never blocks). Compare table and report scenario section render the link. AWS computes regional prices server-side when opened -- the honest region answer. Server registration (.mcp.json) rides the heroku workshop branch; degradation here is silent-null when unconfigured.
@herosjourney

Copy link
Copy Markdown
Contributor Author

Pushed 6d7e7d2 — shareable calculator.aws link per workshop scenario (refresh step 6b: best-effort build_estimate on the PRIMARY outcome's Balanced services, tiebreak_alternative skipped; calculator_url in the manifest; compare table + report render it; never blocks). Server registration in .mcp.json rides the heroku workshop branch (#152) — here the behavior degrades to silent-null when unconfigured. Build green.

Resolves README conflicts by UNIONING both sides: kept main's newer content
(agent-advisor sections from awslabs#147, the awslabs#148 live-Heroku-discovery corrections,
tf-best-practices) AND re-applied vercel-to-aws's unique additions (intro block,
assessment triggers, Vercel to AWS mapping tables, trigger-table row, requirement,
and the DSL-architecture resumability-ledger note). dprint-formatted.

Also fixes two pre-existing CI failures on the branch:
- workshop fragment _ids (workshop-sheet/-refresh/-compare) now match workshop.md's
  declared _ids (sheet/refresh/compare) per the house convention (frontmatter validator).
- shared:sync'd vercel's vendored estimate schema + pricing to canonical (picks up
  awslabs#150's cached_stale enum + arm64 rates that landed on main).
awslabs#159 changed canonical INTERPRETER.md (_check_phase_completed honors
skill-declared resolved statuses); shared:sync propagated it to all vendored
copies. shared:check + both DSL validators + full build green.
@icarthick
icarthick merged commit 46d2472 into awslabs:main Jul 20, 2026
8 checks passed
icarthick added a commit to herosjourney/startups that referenced this pull request Jul 20, 2026
Union-resolve fixtures/README.md registry: keep both gcp-workshop (this branch)
and vercel-workshop (awslabs#153, now on main) entries. Full build green.
icarthick added a commit to herosjourney/startups that referenced this pull request Jul 20, 2026
Brings the branch up to current main (through awslabs#153/awslabs#154/awslabs#159). Resolutions:
- fixtures/README.md: union — keep heroku-workshop + vercel-workshop registry lines.
- estimation-infra.schema.json (canonical + vendored): took main's generic workshop-
  metadata description (the 'heroku-to-aws pilot' note is stale now that vercel/gcp
  share the field); shared:sync keeps copies byte-identical.
Full build green.
icarthick pushed a commit to herosjourney/startups that referenced this pull request Jul 20, 2026
…ode, vendored Merge-last PR: built from awslabs#152 + awslabs#153 + awslabs#154 (plus awslabs#148 via awslabs#152's lineage). After those merge, three near-identical copies of the workshop contract and the estimate Step 0 pricing-mode block would exist -- the exact drift pattern that produced the cached_stale enum bug and the vendored-edited-instead-of-canonical arm64 rates. - skills/shared/workshop/workshop-invariants.md (canonical): frozen discovery + fingerprint, checkpoint state semantics incl. the warm-start rule, the inner-runs allowed/forbidden contract, scenario store rules (max-5 warn-and-name eviction, working-tree==active, estimation_summary core fields), region honesty, and the calculator link procedure. Vendored into all three skills; gcp gains a references/vendored tree (now 4 skills under shared:check). - skills/shared/estimate/pricing-mode.md (canonical Step 0): cache staleness, MCP retry ladder, display modes, and the 5-rung pricing hierarchy incl. the estimated rung. heroku + vercel cost engines now execute the vendored copy as Step 0 instead of restating it; vercel keeps its skill-specific Step 0a-workshop knobs section. - Skill workshop files keep knobs/artifact names/engine refreshes and defer to the invariants file for every invariant (workshop.md hard rules note the canonical wins on disagreement; refresh inner-runs and 6b calculator sections are pointers with skill-specific lines only). - READMEs unioned across the three branches; canonical estimation-infra schema takes the workshop-metadata side + shared:sync. Validated: shared:check green across 4 vendored trees, fixtures-check green (123 json / 8 asserters / 10 seeds), all three workshop asserters PASS on the merged tree, frontmatter validation green, full mise build green.
icarthick pushed a commit that referenced this pull request Jul 20, 2026
…ode, vendored Merge-last PR: built from #152 + #153 + #154 (plus #148 via #152's lineage). After those merge, three near-identical copies of the workshop contract and the estimate Step 0 pricing-mode block would exist -- the exact drift pattern that produced the cached_stale enum bug and the vendored-edited-instead-of-canonical arm64 rates. - skills/shared/workshop/workshop-invariants.md (canonical): frozen discovery + fingerprint, checkpoint state semantics incl. the warm-start rule, the inner-runs allowed/forbidden contract, scenario store rules (max-5 warn-and-name eviction, working-tree==active, estimation_summary core fields), region honesty, and the calculator link procedure. Vendored into all three skills; gcp gains a references/vendored tree (now 4 skills under shared:check). - skills/shared/estimate/pricing-mode.md (canonical Step 0): cache staleness, MCP retry ladder, display modes, and the 5-rung pricing hierarchy incl. the estimated rung. heroku + vercel cost engines now execute the vendored copy as Step 0 instead of restating it; vercel keeps its skill-specific Step 0a-workshop knobs section. - Skill workshop files keep knobs/artifact names/engine refreshes and defer to the invariants file for every invariant (workshop.md hard rules note the canonical wins on disagreement; refresh inner-runs and 6b calculator sections are pointers with skill-specific lines only). - READMEs unioned across the three branches; canonical estimation-infra schema takes the workshop-metadata side + shared:sync. Validated: shared:check green across 4 vendored trees, fixtures-check green (123 json / 8 asserters / 10 seeds), all three workshop asserters PASS on the merged tree, frontmatter validation green, full mise build green. (#157)

Co-authored-by: Logan Kleier <lkleier@amazon.com>
icarthick added a commit that referenced this pull request Jul 23, 2026
Per product decision, remove the vercel-to-aws migration skill entirely. This is a
forward-removal (not a git-revert): vercel landed via shared/cross-skill commits
(#153/#157/#162/#155/#152/#176) that also carried heroku/gcp/sidebar work, so
reverting those merge commits was not viable.

Removed:
- skills/vercel-to-aws/ (full skill, 57 files incl. its references/vendored/ copies)
- fixtures/vercel-capture/ + fixtures/vercel-workshop/ (replay fixture sets)
- Orphaned vercel report validator + its test + golden fixtures (lived at plugin
  level, not under the skill dir): scripts/validate-assessment-report.py,
  tests/test_validate_assessment_report.py, fixtures/assessment-report-{reference,stub}.html,
  fixtures/tier1-signals-reference.json (vercel prescan fixture, no consumers)
- Deregistered from all 3 plugin manifests (.claude/.codex/.cursor-plugin): dropped
  vercel/next-js/nextjs/opennext keywords, the 'Vercel' mentions in descriptions, and
  the codex 'Assess my Vercel migration' example prompt
- Stripped vercel from both READMEs (intro bullets, triggers, Vercel→AWS mapping table,
  trigger-table row, requirement bullet, DSL-architecture section: 'five skills'→'four',
  removed the resumability-ledger note) + fixtures/README registry line
- Dropped vercel asserter entries from tools/run-asserters.py (10→6 asserters)
- Stripped stale vercel cross-refs: heroku SKILL.md workshop-arch note, gcp
  schema-workshop-scenarios arch-defaults line, canonical workshop-invariants
  {SKILL_LABEL}/{INVENTORY} placeholders (shared:sync propagated to vendored copies)

PRESERVED (heroku + gcp depend on these — #157's shared architecture): canonical
skills/shared/workshop/workshop-invariants.md + skills/shared/estimate/pricing-mode.md
and their heroku/gcp vendored copies. shared:check drops 4→3 trees cleanly (the sync
tool auto-discovers consumers). Left legit non-skill refs: gcp's vercel.json detection
signal, 'Vercel AI SDK' framework name, historical PR-context notes.

Verified: shared:check OK (3 trees byte-identical), fixtures:assert 6/6, all validators
green (heroku/gcp/agent-advisor), dprint + markdownlint clean, full mise run build green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants