diff --git a/.claude/plans/aws-service-coverage-100.plan.md b/.claude/plans/aws-service-coverage-100.plan.md new file mode 100644 index 00000000..d520d632 --- /dev/null +++ b/.claude/plans/aws-service-coverage-100.plan.md @@ -0,0 +1,192 @@ +# Plan: Repeatable AWS Service Onboarding + +**Source PRD**: `.claude/prds/aws-service-coverage-100.prd.md` +**Selected Milestone**: 1 — Onboarding cost is known +**Complexity**: Medium (small diffs; the measurement, not the code, is the deliverable) + +## Summary + +The service-onboarding pipeline already exists end to end — per-service model +download, a codegen scaffolder that writes a self-registering provider and +refuses to clobber a hand-written one, config that auto-enables every registered +service, and a main loop that needs no edit per service. Milestone 1 is therefore +a **repair-and-measure** job, not a build-a-tool job. + +Two defects make the existing pipeline unusable and one makes its output dishonest: +the import generator gates on a file no service has, so it empties `imports.go`; +the scaffolded provider declines in a way that never reaches the CRUD engine, so +a new service serves zero operations; and the fidelity manifest would publish +those zero-op services as `auto-crud` anyway. Fixing all three is under 30 lines. +The remaining work is removing the one genuinely repetitive step (a hand-written +boto3 fixture per service — there are already 104) and then running the whole +path on one real service with a stopwatch. + +## Findings That Shape the Plan + +| Finding | Evidence | Consequence | +|---|---|---| +| **`generate-imports.sh` skips every service dir.** It requires `register.go`; zero of 103 services have one — they register from an `init()` inside `provider.go`. | `scripts/generate-imports.sh:19`; `ls internal/services/*/register.go` → no matches; 103 dirs vs 103 entries in the committed `cmd/devcloud/imports.go` | Running the script today writes an **empty import block**. The weekly sync workflow runs it (`.github/workflows/smithy-sync.yml:37`) before its test step, so that job has been failing every week rather than opening sync PRs. No new service can be reached until this is fixed. | +| **The scaffold declines the wrong way.** It returns `generated.ErrNotImplemented`; the CRUD fallback is reached only on `plugin.ErrUnhandledOp`. | `internal/codegen/templates/scaffold_provider.go.tmpl:31` vs `internal/gateway/router.go:61` | A freshly scaffolded service serves **zero** operations and cannot meet the PRD's quality floor as generated. One-line fix. | +| **The fidelity manifest does not check engine wiring.** An op is labelled `auto-crud` from the model-derived CRUD registry alone. | `internal/codegen/gen_fidelity.go:95-104` (`tierFor` consults only the `hand` and `crud` maps) | A scaffolded service would be published as `auto-crud` while returning an error at runtime — the manifest overstating coverage is the PRD's top-ranked risk, and this is the mechanism. | +| Services are auto-enabled and auto-started; no per-service config or `main.go` edit. | `internal/config/config.go:122` (no `services` block ⇒ all enabled); `cmd/devcloud/main.go:102` iterates `registry.RegisteredServices()` | `docs/contributing.md` step 7 ("Update main.go") is dead. Two of its ten documented steps do not apply. | +| **104 near-identical boto3 fixtures are hand-written**, each a one-line wrapper over a shared helper. | `tests/compatibility/conftest.py:126` (`_make_client`), 104 `*_client(devcloud_server)` definitions | This is the single largest per-service cost and the only step that genuinely scales with 330 services. One parameterized fixture removes it. | +| The scaffolder already refuses to overwrite a hand-written provider. | `internal/codegen/generator.go:65` (`os.Stat` guard, comment states the intent) | Re-running codegen over the whole tree is safe; no quarantine mechanism needs inventing. | +| **338 upstream models are missing locally** (431 upstream vs 93 in-tree). | `comm` over the `aws-sdk-go-v2/aws-models` listing vs `smithy-models/` | Confirms the PRD's ~330 figure. Upstream filenames are hyphenated (`api-gateway`, `app-mesh`) while package names are not — the download script takes the **upstream filename**, and the package name comes from the model's service id. They differ. | + +## Patterns to Mirror + +| Category | Source | Pattern | +|---|---|---| +| Generated file | `cmd/devcloud/imports.go:1` | `// Code generated by