feat: register the 218 scaffolded services and stop their routes fabricating successes - #162
Merged
Merged
Conversation
…icating successes 218 services had generated routers and no provider package, so every SDK call to one left the machine for a billed AWS account. Each now gets a provider from the codegen scaffold template, wired by a new -scaffold-output flag on `make codegen`. The scaffold implements nothing by hand and returns plugin.ErrUnhandledOp, which is what hands the request to the generic CRUD engine — so a service serves its CRUD-shaped operations from the moment it is generated, and the engine declines the rest with an honest AWS error. GenerateAll writes the scaffold only when none exists, so regenerating never clobbers a hand-written provider. Registering them exposed a fabricated success that predates this change. The CRUD registry held only operations the engine can classify, and httproute.Match answers with the most specific route it *holds* — so an unclassifiable operation whose path a classified sibling also claims was answered by the sibling. chime's AssociatePhoneNumberWithUser returned UpdateUser's 200; apigateway's ImportRestApi returned CreateRestApi's. classifyOps now records every REST-bound operation, the unclassifiable ones with an empty Verb, so the specific route exists to outrank the broader one and crud.Handle declines it on the Verb check it already makes. Those entries are routes and not capability: BuildFidelityData skips them so the manifest cannot count them as served, and RegisteredOps filters them so a caller asking what a service holds is told what it will answer. A service that classifies nothing still registers nothing — rds-data is unchanged. Neither fixed case was reachable by the compatibility suite: _unserved_probe picks one operation per service and prefers Describe/List/Get, and "Import" is excluded as mutating. Both are now pinned by Go tests instead — one on classifyOps, one end-to-end against the registry the binary ships, with the opposite direction asserted so declining cannot become the cheap way to pass. test_no_fabricated_success.py skipped whenever botocore put nothing on the wire, which is unbounded: a change that broke request building would shrink the suite with no assertion moving. The condition now fails unless the probe is named in _coverage.UNSENDABLE_PROBES, matching how test_service_smoke.py already treats it. Pinning the two that were skipping showed both to be this suite's own stub builder rather than a botocore policy — an unfilled PredictEndpoint and a nested minimum the padding does not descend into — and the entries say so. Three services are excluded from the compatibility-tested figure because botocore, not DevCloud, stops the request: codecatalyst signs with a bearer token, cloudfront-keyvaluestore resolves its endpoint from a KVS ARN, and partnercentral-revenue-measurement decodes every answer as CBOR. The set is pinned, so a fourth lowers the published figure deliberately. docs/coverage.md said the target is "205 services, not 431" on the same page that now reports 431 registered. The 2026-09-05 decision refused the cost of hand-building 283 services on an untested assumption; the scaffold removed that cost, so breadth was taken because it became nearly free and the target stayed at 205, because it was never a count of registrations — it is where depth is promised. The page now states those as two claims rather than one. Registered services 213 -> 431, serving 209 -> 426, compatibility-tested 211 -> 426, auto-crud operations 5,193 -> 10,871. The compatibility suite goes from 1,156 tests to 1,530.
This was referenced Sep 12, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Registers the 218 services that had generated routers but no provider package, so their SDK calls are answered locally instead of reaching a billed AWS account — and fixes the fabricated success that registering them exposed, where an operation the CRUD engine cannot classify was answered by a classified sibling that shares its path.
Related Issue
None. This repository records the PR number in the Changie fragment's
Issuefield —Issue: "162"here, matching #160 and #161 — so there is no separate issue to close.Changes
make codegentakes a new-scaffold-outputflag; each service gets a provider from the codegen template that returnsplugin.ErrUnhandledOp, handing the request to the generic CRUD engine.GenerateAllwrites a scaffold only when none exists, so regeneration never clobbers a hand-written provider.classifyOpsnow records every REST-bound operation, the unclassifiable ones with an emptyVerb, so the specific route exists to outrank a broader sibling's andcrud.Handledeclines on theVerbcheck it already makes. chime'sAssociatePhoneNumberWithUserwas returningUpdateUser's 200; apigateway'sImportRestApiwas returningCreateRestApi's.BuildFidelityDataskips them so the manifest cannot count them as served;RegisteredOpsfilters them so a caller asking what a service holds is told what it will answer. A service that classifies nothing still registers nothing —rds-datais unchanged.test_no_fabricated_success.pyskipped whenever botocore put nothing on the wire, which is unbounded. It now fails unless the probe is named in_coverage.UNSENDABLE_PROBES, matching howtest_service_smoke.pyalready treats the same condition.docs/coverage.md. The page said the target is "205 services, not 431" while reporting 431 registered. Restated as two claims: 431 answer locally, 205 are where depth is promised.Test Plan
Reviewing this diff: 218 of the 239 files are the identical 53-line scaffold. The code worth reading is 13 files — `internal/codegen/gen_crud_meta.go`, `gen_fidelity.go`, `internal/shared/crud/crud.go`, the two new tests, and the compatibility-suite changes.
Known gaps, recorded rather than hidden: both pinned probes are this suite's own stub builder (an unfilled `PredictEndpoint`, a nested minimum the padding does not descend into) and are fixable; `docs/coverage.md`'s "The target" table is still not asserted by any test.
Checklist