Skip to content

migration-to-aws: flat-steering port with scripts shipped directly - #2

Open
ayn-builds wants to merge 2 commits into
mainfrom
ayn/migration-to-aws-flat-scripts
Open

migration-to-aws: flat-steering port with scripts shipped directly#2
ayn-builds wants to merge 2 commits into
mainfrom
ayn/migration-to-aws-flat-scripts

Conversation

@ayn-builds

Copy link
Copy Markdown
Owner

Summary

Ports the Kiro migration-to-aws power to parity with the upstream awslabs/startups/migrate/plugins/migration-to-aws plugin (Apache-2.0), using a flat-steering/ design that ships the plugin's deterministic scripts directly as uv run-able files.

Fork-only PR for review — nothing merged to kirodotdev/powers upstream.

Design

The plugin is a nested Claude/Cursor/Codex plugin; a Kiro power is flat. The bundled tooling/flatten_plugin_to_power.py projects the plugin into a flat steering/ deterministically, so a sync is a re-run rather than a manual merge. Verified byte-identical to a fresh projection of upstream HEAD 927def0.

What ships

  • 214 flat steering files — 178 .md, 24 .json, 11 .py, 1 .template. No servers/ MCP dir.
  • All 4 engines (gcp-to-aws, heroku-to-aws, llm-to-bedrock, agent-advisor) + shared tf-best-practices.
  • Deterministic engines ship as scripts, not prose or an MCP server: agent-advisor scoring/build-diagram, the llm validators, and the tf policy checker are PEP 723 files run via uv run steering/<name>.py (only llm-validate-result.py needs a third-party dep — jsonschema — declared inline, so uv run resolves it with no setup).
  • POWER.md defines $STEERING/$SCRIPTS/$HELPERS/<scriptsDir>/$GCP_BASE to resolve to the one flat directory, so the plugin's injected "Scripts directory" line is no longer load-bearing.
  • INTERPRETER.md _exec dispatches to Kiro's generic general-task-execution sub-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

  • Re-projection from upstream HEAD → byte-identical to shipped steering/.
  • validate_power.py → clean (0/0/0/0).
  • Ran agent-advisor-scoring.py and llm-validate-result.py under the flat uv run invocations — both produce correct output and contract tokens.

Not done here / caveats

  • Upstream's script test suites are not re-run in this PR (logic is byte-identical to upstream CI).
  • The three MCP servers in 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.
  • _exec assumes general-task-execution is the registered generic sub-agent in the target Kiro runtime — worth a one-time confirmation.

Ayushi Nair added 2 commits July 31, 2026 13:38
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.
Comment on lines +167 to +171
| `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) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reference here still points to awslabs/startups

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +234 to +313
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
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The directory structure here has changed.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +114 to +162
```
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)
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The directory structure has changed and needs to be updated.

@ayn-builds ayn-builds Aug 4, 2026

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

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