migration-to-aws: flat-steering port with scripts shipped directly - #2
migration-to-aws: flat-steering port with scripts shipped directly#2ayn-builds wants to merge 2 commits into
Conversation
Replaces the MCP-server design with a flat-`steering/` power that ships the upstream plugin's deterministic scripts as `uv run`-able files. Byte- identical to a fresh projection of awslabs/startups migrate plugin (HEAD 927def0) via the bundled tooling/flatten_plugin_to_power.py. - 214 flat steering files (178 .md, 24 .json, 11 .py, 1 .template); no servers/ dir. - All 4 engines + tf-best-practices; agent-advisor scoring/build-diagram and the llm/tf validators ship as PEP 723 scripts run via `uv run`. - POWER.md defines $STEERING/$SCRIPTS/$HELPERS/<scriptsDir>/$GCP_BASE to the one flat dir; INTERPRETER.md _exec dispatches to Kiro's generic general-task-execution sub-agent with inline fallback. - Parity sync tooling: flatten_plugin_to_power.py, validate_power.py (scans fenced blocks for plugin-layout tokens), compare_to_published.py.
Review feedback: the reference files are all flat in steering/, but the "Files in This Skill" ASCII trees in gcp-orchestrator.md and heroku-orchestrator.md still drew the upstream plugin's nested layout, so they read as though the port resolves references/phases/discover/discover.md. Nothing loaded through those paths — both files address every target by bare filename — but the tree is the most prominent structural statement in each file, and a prose disclaimer above the fence did not travel with the block when quoted, skimmed, or grepped. - flatten_layout_tree() rewrites the tree body into the flat layout: directory rows dropped, leaves re-anchored under steering/, comments re-aligned, upstream order kept so the phase grouping stays legible. Runs after the reference pass, so leaves are already shipped flat names. Rows naming a file the projection does not ship are dropped, which removes heroku's dangling shared/README.md row and its heroku-to-aws/ tree root. - heroku-clarify-assemble.md:101 pointed at the directory `references/phases/workshop/` in live prose. The generic pass rewrites every workshop reference carrying a filename, but a bare directory has no filename to match, so this one survived as a dead path an agent could act on. Now names heroku-workshop.md. - validate_power.py missed both: LAYOUT_TOKENS held `references/` as a backtick-wrapped literal, so it matched neither the un-backticked tree rows nor the deeper `references/phases/workshop/` form. Replaced with the LAYOUT_DIRS regex, markup-independent, with a trailing boundary so prose like "≥2 phases/rows" does not trip it. Verified: re-projection from upstream 927def0 byte-identical to shipped steering/; validate_power.py 0/0/0/0 with the strengthened check; inventory unchanged at 214 (178 md / 24 json / 11 py / 1 template); scoring and build-diagram still run. Three steering files changed, no others drifted.
| | `awslabs/startups:migrate/plugins/migration-to-aws/skills/agent-advisor/scripts/test_temporal_decision_refs.py` | Content lock for the Temporal decision reference | | ||
| | `awslabs/startups:migrate/plugins/migration-to-aws/skills/agent-advisor/scripts/test_poc_shapes.py` | Content lock for the POC deploy shapes | | ||
| | `awslabs/startups:migrate/plugins/migration-to-aws/skills/agent-advisor/scripts/test_workload_classes.py` | Content lock for agent-advisor-workload-classes.md (verdicts table) | | ||
| | `awslabs/startups:migrate/plugins/migration-to-aws/skills/agent-advisor/scripts/test_unit_grouping.py` | Unit grouping + pattern matching (workload-class assignment) | | ||
| | `awslabs/startups:migrate/plugins/migration-to-aws/skills/agent-advisor/scripts/test_collapse_invariant.py` | Collapse-invariant ordering enforcement (A→B implies [B] ⊆ [A] outputs) | |
There was a problem hiding this comment.
The reference here still points to awslabs/startups
There was a problem hiding this comment.
Deliberate - test_*.py isn't shipped. Those tests assert on the plugin's nested layout (references/phases//.md, and one case walking up four parents to CONTRIBUTING.md), so they can't pass against a flat power and can't be mechanically repaired. Rather than leave five dangling basenames that validate_power.py would flag, they're repo-qualified upstream so the pointer stays resolvable. That said, they sit under a bare ## Files heading which reads as local-only — happy to move them under a "content locks — not shipped with this power" sub-heading, or collapse the five rows into one.
| steering/ | ||
| ├── gcp-orchestrator.md ← You are here (orchestrator + state machine) | ||
| │ | ||
| ├── references/ | ||
| │ ├── phases/ | ||
| │ │ ├── discover/ | ||
| │ │ │ ├── discover.md # Phase 1: Discover orchestrator | ||
| │ │ │ ├── discover-iac.md # Terraform/IaC discovery | ||
| │ │ │ ├── discover-live.md # Live gcloud CLI discovery (read-only, consent-gated) | ||
| │ │ │ ├── discover-app-code.md # App code discovery | ||
| │ │ │ └── discover-billing.md # Billing data discovery | ||
| │ │ ├── clarify/ | ||
| │ │ │ ├── clarify.md # Phase 2: Clarify orchestrator | ||
| │ │ │ ├── clarify-global.md # Category A: Global/Strategic (Q1-Q7) | ||
| │ │ │ ├── clarify-compute.md # Categories B+C: Config Gaps + Compute (Q8-Q11) | ||
| │ │ │ ├── clarify-database.md # Category D: Database (Q12–Q13b) | ||
| │ │ │ ├── clarify-ai.md # Categories F/G/H: AI/Bedrock, Agentic, Programs (Q14-Q27) | ||
| │ │ │ └── clarify-ai-only.md # Standalone AI-only migration flow | ||
| │ │ ├── design/ | ||
| │ │ │ ├── design.md # Phase 3: Design orchestrator | ||
| │ │ │ ├── design-infra.md # Infrastructure design (IaC-based) | ||
| │ │ │ ├── design-ai.md # AI workload design (Bedrock) | ||
| │ │ │ └── design-billing.md # Billing-only design (fallback) | ||
| │ │ ├── estimate/ | ||
| │ │ │ ├── estimate.md # Phase 4: Estimate orchestrator | ||
| │ │ │ ├── estimate-infra.md # Infrastructure cost analysis | ||
| │ │ │ ├── estimate-ai.md # AI workload cost analysis | ||
| │ │ │ └── estimate-billing.md # Billing-only cost analysis | ||
| │ │ ├── workshop/ | ||
| │ │ │ ├── workshop.md # Sidebar: optional post-Estimate what-if | ||
| │ │ │ ├── workshop-sheet.md # Assumption sheet knobs | ||
| │ │ │ ├── workshop-refresh.md # Patch prefs → Design → Estimate → snapshot | ||
| │ │ │ ├── workshop-compare.md # Side-by-side scenarios | ||
| │ │ │ └── workshop-assemble.md # Resolve sidebar → return to Generate | ||
| │ │ ├── generate/ | ||
| │ │ │ ├── generate.md # Phase 5: Generate orchestrator | ||
| │ │ │ ├── generate-infra.md # Infrastructure migration plan | ||
| │ │ │ ├── generate-ai.md # AI migration plan | ||
| │ │ │ ├── generate-billing.md # Billing-only migration plan | ||
| │ │ │ ├── generate-artifacts-infra.md # Terraform configurations | ||
| │ │ │ ├── generate-artifacts-scripts.md # Migration scripts | ||
| │ │ │ ├── generate-artifacts-ai.md # Provider adapter + test harness | ||
| │ │ │ ├── generate-artifacts-billing.md # Skeleton Terraform | ||
| │ │ │ └── generate-artifacts-docs.md # MIGRATION_GUIDE.md + README.md | ||
| │ │ └── feedback/ | ||
| │ │ ├── feedback.md # Phase 6: Feedback orchestrator | ||
| │ │ └── feedback-trace.md # Anonymized trace builder | ||
| │ │ | ||
| │ ├── design-refs/ | ||
| │ │ ├── design-ref-index.md # Lookup table: GCP type → design-ref file | ||
| │ │ ├── design-ref-fast-path.md # Deterministic 1:1 mappings (Pass 1) | ||
| │ │ ├── design-ref-compute.md # Compute mappings (Cloud Run, GCE, GKE, etc.) | ||
| │ │ ├── design-ref-database.md # Database mappings (Cloud SQL, Spanner, etc.) | ||
| │ │ ├── design-ref-storage.md # Storage mappings (GCS, Filestore, etc.) | ||
| │ │ ├── design-ref-networking.md # Networking mappings (VPC, LB, DNS, etc.) | ||
| │ │ ├── design-ref-messaging.md # Messaging mappings (Pub/Sub, etc.) | ||
| │ │ └── design-ref-ai.md # AI mappings (Vertex AI → Bedrock) | ||
| │ │ | ||
| │ ├── clustering/terraform/ | ||
| │ │ ├── clustering-classification-rules.md # Primary/secondary classification | ||
| │ │ ├── clustering-algorithm.md # Cluster formation rules | ||
| │ │ ├── depth-calculation.md # Topological depth calculation | ||
| │ │ └── typed-edges-strategy.md # Edge type assignment | ||
| │ │ | ||
| │ └── shared/ | ||
| │ ├── schema-phase-status.md # .phase-status.json schema (canonical reference) | ||
| │ ├── schema-workshop-scenarios.md # scenarios/ + preferences.workshop contract | ||
| │ ├── schema-discover-iac.md # gcp-resource-inventory + clusters schemas (loaded by discover-iac.md) | ||
| │ ├── schema-discover-ai.md # ai-workload-profile schema (loaded by discover-app-code.md and discover-iac.md Step 7d) | ||
| │ ├── schema-discover-billing.md # billing-profile schema (loaded by discover-billing.md) | ||
| │ ├── schema-estimate-infra.md # estimation-infra.json schema (loaded by estimate-infra.md at write time) | ||
| │ ├── handoff-gates.md # Fail-closed phase handoff protocol (GATE_FAIL / HANDOFF_OK) | ||
| │ ├── validate-artifacts.md # Pre-report validation (Generate Step 0; read-only) | ||
| │ ├── validate-migration-report.md # Post-write HTML completeness (Generate Step 4) | ||
| │ ├── migration-complexity.md # Complexity tier definitions (small/medium/large) for timeline scaling | ||
| │ ├── cached-prices.md # Cached AWS + source provider pricing (±5-25%, primary source) | ||
| │ ├── graviton.md # Graviton/ARM64 tiers, mapping, per-phase rules (conditional load) | ||
| │ ├── schema-graviton.md # graviton_profile + cpu_architecture + architecture_comparison schemas | ||
| │ └── bedrock-quotas.md # Bedrock TPM/RPM quota awareness, burndown rates, capacity planning | ||
| ``` |
There was a problem hiding this comment.
The directory structure here has changed.
There was a problem hiding this comment.
Already fixed in 8395103 — that landed ~30 min before your review, so the hunk you're seeing is from 645c663. The tree is now single-level under steering/, done in the projection via flatten_layout_tree() rather than by hand: directory rows dropped, leaves re-anchored, comments realigned, upstream ordering kept so the phase grouping stays readable.
| ``` | ||
| heroku-to-aws/ | ||
| ├── heroku-orchestrator.md ← You are here (skill entry point) | ||
| │ | ||
| ├── references/ | ||
| │ ├── phases/ | ||
| │ │ ├── discover/ | ||
| │ │ │ ├── heroku-discover.md # Phase 1: Discover orchestrator | ||
| │ │ │ ├── heroku-discover-terraform.md # Terraform discovery | ||
| │ │ │ ├── heroku-discover-live-capture.md # Live CLI capture (main-window pre-work, consent-gated) | ||
| │ │ │ ├── heroku-discover-live.md # Live discovery fragment (parses live-capture/) | ||
| │ │ │ └── heroku-discover-billing.md # Billing data parsing | ||
| │ │ ├── clarify/ | ||
| │ │ │ └── heroku-clarify.md # Phase 2: Adaptive questions (12–15, batched ≤5) | ||
| │ │ ├── design/ | ||
| │ │ │ └── heroku-design.md # Phase 3: Design orchestrator (flat single-pass mapping) | ||
| │ │ ├── estimate/ | ||
| │ │ │ └── heroku-estimate.md # Phase 4: Cost projection | ||
| │ │ ├── workshop/ | ||
| │ │ │ ├── heroku-workshop.md # Sidebar: optional post-Estimate what-if | ||
| │ │ │ ├── heroku-workshop-sheet.md # Assumption sheet knobs | ||
| │ │ │ ├── heroku-workshop-refresh.md # Patch prefs → Design → Estimate → snapshot | ||
| │ │ │ ├── heroku-workshop-compare.md # Side-by-side scenarios | ||
| │ │ │ └── heroku-workshop-assemble.md # Resolve sidebar → return to Generate | ||
| │ │ ├── generate/ | ||
| │ │ │ ├── heroku-generate.md # Phase 5: Generate orchestrator | ||
| │ │ │ ├── heroku-generate-terraform.md # Terraform configurations | ||
| │ │ │ ├── heroku-generate-docs.md # MIGRATION_GUIDE.md + README.md | ||
| │ │ │ ├── heroku-generate-report.md # migration-report.html (stakeholder + scenarios) | ||
| │ │ │ └── heroku-generate-eks.md # EKS manifests when design has EKS | ||
| │ │ └── feedback/ | ||
| │ │ └── heroku-feedback.md # Phase 6: Feedback collection (reuses shared) | ||
| │ │ | ||
| │ └── shared/ # heroku-to-aws's own shared references | ||
| │ ├── README.md # what lives here + pointers to plugin-neutral shared data | ||
| │ ├── heroku-pricing-cache.md # Heroku plan pricing (source-side baseline) | ||
| │ ├── heroku-schema-discover-heroku.md # heroku-resource-inventory.json schema | ||
| │ └── heroku-schema-workshop-scenarios.md # scenarios/ + preferences.workshop contract | ||
| │ | ||
| ├── knowledge/design/ # design lookup DATA (pure data, referenced by | ||
| │ │ # heroku-design.md _knowledge, gated per _when) | ||
| │ ├── heroku-dyno-eb-sizing.json # Dyno type → Elastic Beanstalk EC2 instance type | ||
| │ ├── heroku-dyno-fargate-sizing.json # Dyno type → Fargate CPU/memory | ||
| │ ├── heroku-eks-pod-sizing.json # Dyno type → EKS pod sizing + node selection | ||
| │ ├── heroku-postgres-rds-sizing.json # Postgres plan → RDS/Aurora sizing | ||
| │ ├── heroku-redis-elasticache-sizing.json # Redis plan → ElastiCache sizing | ||
| │ ├── heroku-kafka-msk-sizing.json # Kafka plan → MSK sizing | ||
| │ └── heroku-fast-path-addons.json # Add-on → AWS deterministic mappings (13+ entries) | ||
| ``` |
There was a problem hiding this comment.
The directory structure has changed and needs to be updated.
There was a problem hiding this comment.
Same commit as the gcp one. Heroku also had two extras the rewrite cleaned up: a dangling
README.md row and the heroku-to-aws/ tree root, both gone since rows naming an unshipped file get dropped. validate_power.py missed both trees originally — LAYOUT_TOKENS held references/ as a backtick-wrapped literal, so it matched neither the un-backticked tree rows nor the deeper references/phases/workshop/ form. That's now a markup-independent LAYOUT_DIRS regex.
| @@ -0,0 +1,531 @@ | |||
| --- | |||
| name: llm-to-bedrock | |||
There was a problem hiding this comment.
In the original Claude Code plugin, we defined some subagents, but in Kiro Power these have all been converted to flat reference files. The original purpose of the subagent design was context isolation, but that benefit is lost once they're turned into reference files.
I'd suggest checking whether Kiro Power supports subagents. If it doesn't, we should run through the tests to confirm there are no context issues.
There was a problem hiding this comment.
Kiro does have sub-agents and the port uses them — isolation is preserved. What's missing is a power-level agent registry: a power bundles steering + MCP, so it can't register migration-to-aws:llm2bedrock-code-analyzer as an addressable type. So the two jobs got split — the agent file ships as a steering file and serves as the contract, and the isolation comes from dispatching Kiro's generic general-task-execution sub-agent with that file handed over (INTERPRETER.md L294-311, POWER.md L192-203; llm Phase C does the same with the five llm-*.md files). Artifacts pass as file paths, never inlined. The tier becomes advisory, which INTERPRETER.md's platform-asymmetry note already permits.
Summary
Ports the Kiro
migration-to-awspower to parity with the upstreamawslabs/startups/migrate/plugins/migration-to-awsplugin (Apache-2.0), using a flat-steering/design that ships the plugin's deterministic scripts directly asuv run-able files.Fork-only PR for review — nothing merged to
kirodotdev/powersupstream.Design
The plugin is a nested Claude/Cursor/Codex plugin; a Kiro power is flat. The bundled
tooling/flatten_plugin_to_power.pyprojects the plugin into a flatsteering/deterministically, so a sync is a re-run rather than a manual merge. Verified byte-identical to a fresh projection of upstream HEAD927def0.What ships
.md, 24.json, 11.py, 1.template. Noservers/MCP dir.uv run steering/<name>.py(onlyllm-validate-result.pyneeds a third-party dep —jsonschema— declared inline, souv runresolves it with no setup).$STEERING/$SCRIPTS/$HELPERS/<scriptsDir>/$GCP_BASEto resolve to the one flat directory, so the plugin's injected "Scripts directory" line is no longer load-bearing._execdispatches to Kiro's genericgeneral-task-executionsub-agent (with an inline fallback when no sub-agent tool exists), rather than the plugin-only worker-agent name.Parity tooling (maintainers only, not loaded at runtime)
flatten_plugin_to_power.py— projects plugin → flat steering, rewrites cross-references.validate_power.py— 0 unflattened paths / 0 dangling names / 0 plugin-layout tokens (scans fenced code blocks) / 0 broken POWER.md pointers.compare_to_published.py— drift vs the published Kiro power.Verification
steering/.validate_power.py→ clean (0/0/0/0).agent-advisor-scoring.pyandllm-validate-result.pyunder the flatuv runinvocations — both produce correct output and contract tokens.Not done here / caveats
mcp.json(awsknowledge, awspricing, temporal-docs) are declared identically to upstream and are not live-tested; POWER.md has a cached-pricing fallback for awspricing._execassumesgeneral-task-executionis the registered generic sub-agent in the target Kiro runtime — worth a one-time confirmation.