Chore/parity upgrade - #2414
Conversation
|
Important Review skippedToo many files! This PR contains 2152 files, which is 2052 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. Usage-priced reviews support at most 300 files. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (5)
📒 Files selected for processing (2152)
You can disable this status message by setting the |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
📊 Code Coverage Report
Tip This project maintains a minimum coverage threshold of 85%. Maintain or improve coverage on new code to ensure long-term stability. Last updated: Sun, 09 Aug 2026 02:21:45 GMT |
Tests that do real Docker or loopback network I/O cannot run inside a synctest bubble, because real I/O is not durably blocking and the bubble would hang rather than advance. Those were left sleeping when the synctest sweep went through. They are now polled instead. 45 sleeps across test/integration, test/e2e, test/terraform and services/lambda become require.Eventually against the condition each was actually waiting for -- a resource reaching ACTIVE, a message arriving, a log line appearing -- with generous timeouts and short ticks, so a slow or loaded machine still passes where a fixed sleep would not. Two remain, both because the wait is not a condition: services/lambda/handler_runtime_test.go sleeps for tt.responseDelay, where the delay itself is the thing under test -- it simulates a slow runtime response, so polling it away would delete the test's subject. test/integration/autopurge_test.go waits 22 seconds for a TTL window to elapse before creating fresh resources. Nothing exposes "has N seconds passed", so a poll would be a sleep wearing a disguise. The integration suite was run for real against Docker (91.9s, passing), not skipped. Also continues the comment sweep through ec2, mgn, s3, ecs and dynamodb. Repo-wide, blocks of 8+ consecutive comment lines are down from 2139 to 1947. Verified comments-only: no behaviour, identifier or control-flow change in that half of the diff. Refs gopherstack-5biv Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…to A test/integration/directconnect_test.go drives the real aws-sdk-go-v2 client against a running container: connection/LAG lifecycle, private/public/transit VIFs with BGP peers, DirectConnectGateway associations/proposals against real EC2 VpnGateway/TransitGateway resources (proving the existing EC2 cross-service validation end-to-end), and tagging including the global dx-gateway ARN. Re-judged all 12 PARITY.md gaps: moved 7 genuinely unbuildable items (physical cross-connect, real LOA-CFA content, AWS's proprietary location/ router catalogs, real legal agreements, MACsec hardware, real BGP sessions, partner billing, Cloud WAN) to structural_gaps. Left 2 gaps open (CloudFormation resource types belong to services/cloudformation; secretsmanager- backed MACsec keys deferred to avoid stacking cli.go edits onto a concurrent agent's in-flight work). bd: gopherstack-6y3m Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…na and networkmanager to A
Three services claimed the same REST prefix and only MatchPriority decided
who won.
services/bedrockagent's RouteMatcher checked the SigV4 service scope and
then fell through to an unguarded path-prefix match on /tags/, /agents,
/flows, /prompts and /resourcepolicy, so it answered any other service's
request on those paths. services/cleanrooms had the same unguarded /tags/
match. grafana and networkmanager also serve /tags/.
A previous pass had "fixed" networkmanager by raising its MatchPriority to
88 so it outranked bedrockagent. That masked the defect system-wide rather
than fixing it, and when the escalation was reverted -- correctly -- it
un-masked cleanrooms, which registers before grafana at the same priority
and was returning 404 for everyone else's tag ARNs. Re-escalating would not
have helped: cleanrooms beat grafana regardless of networkmanager.
The fix is httputils.MatchesTaggedResourceARN, which disambiguates on the
ARN already present in the path -- arn:{partition}:{service}: -- rather than
on priority or on the signing scope. The ARN names its true owner
unambiguously, so every service serving /tags/ can now match only its own
requests: cleanrooms, grafana, mgn, networkmanager, outposts and
resiliencehub all use it. bedrockagent keeps its prefix fallback but no
longer takes it when the signing scope names a different service.
managedblockchain already guarded its own match, and the remaining bare
prefix checks in omics and bedrock are internal dispatch that runs after
matching, so they cannot steal anything.
test/integration/tag_routing_test.go tags resources across several services
in ONE binary run, which is the only way this class is visible -- each
service passes its own suite in isolation while silently answering another's
traffic.
Riding along, two services reach A.
grafana gains an SDK-driven integration suite and real cross-service
validation: WorkspaceRoleArn against IAM, VPC subnets and security groups
against EC2, organizational units against Organizations, and SSO grants
against ssoadmin and identitystore. Its FAILED and DEGRADED workspace
states are now reachable through chaos injection instead of every
transition resolving to ACTIVE. ListVersions moves to structural_gaps: the
supported-version catalog is operational data with no SDK encoding, so no
implementation can derive it.
networkmanager gains its own integration suite and replaces two
placeholders with real behaviour: StartRouteAnalysis now walks EC2's
modelled transit gateway route tables with longest-prefix match and returns
genuine CONNECTED, BLACKHOLE, INACTIVE or ROUTE_NOT_FOUND verdicts, and
GetCoreNetworkChangeSet diffs the stored policy JSON for real. Telemetry
and BGP routes move to structural_gaps -- no BGP session or device
telemetry exists anywhere in this repo to derive them from. Its stale
"gap" grade, left from when the manifest was a pre-implementation spec,
becomes A.
Gates: 66687 tests pass, golangci-lint 0 issues, govulncheck clean, and the
grafana, networkmanager and tag-routing integration suites pass against
Docker.
Closes gopherstack-sokq, gopherstack-4spv, gopherstack-xhi2
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… A- to A mgn had 95 operations and roughly 12k lines of implementation behind only 960 lines of test, and no SDK-driven integration coverage at all. It now has a suite driving the real aws-sdk-go-v2 client through source servers, replication and launch templates, jobs, applications and waves. That suite immediately earned its place by catching a bug no unit test could see: UpdateSourceServer parsed FqdnForActionFramework and UserProvidedID off the wire and then never applied them, and silently wiped ConnectorAction on every update. Four more gaps closed with real behaviour. StartImport's CSV schema was invented. It now uses AWS's documented mgn:server:* parameters -- an invented schema is precisely the fabrication this campaign exists to remove, and it was worse than an empty response because it looked plausible. ModifiedCount was hardcoded to zero and now counts real modifications, keyed on mgn:server:user-provided-id the way AWS's own documentation describes. StartTest and StartCutover minted a synthetic instance ID that referred to nothing. They now launch a genuine EC2 instance through services/ec2 via a new cross_service.go, following the pattern grafana established, and the integration test confirms the instance with a real DescribeInstances call. A migration service whose launched instances do not exist is the kind of shape-correct-but-hollow behaviour that makes an emulator untrustworthy. ListManagedAccounts previously returned only the caller's own account and now resolves real Organizations member accounts. Moved to structural_gaps with individual justification: the absence of CreateSourceServer and CreateVcenterClient, NetworkMigrationExecutionID creation, and network-migration analysis, codegen and deployment content. Left in gaps as a deliberate scope call: the mgn:app:, mgn:wave: and mgn:launch:* CSV columns, which are a materially larger feature rather than an unbuildable one. Gates: build and vet clean, go test -race passes, golangci-lint 0 issues, and the Docker-backed integration suite passes. Closes gopherstack-xd34 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ldable gaps, held at B
outposts had 43 operations, 10 open gaps and no SDK-driven integration
coverage. It now has a table-driven suite exercising outposts, sites,
orders, catalog items, capacity tasks and tagging through the real
aws-sdk-go-v2 client.
The grade stays at B, deliberately.
The gap that matters most -- wiring RunInstances into the Outposts
capacity ledger, so capacity depletes as instances launch the way real
Outposts does -- cannot be built from this side. services/ec2 has no
Outpost-placement fields at all, so there is nothing for outposts to read;
even the read-only cross-service pattern grafana established has no source
to read from. That needs an ec2-side change first, filed as
gopherstack-9ij1. Raising the grade with that unbuilt would be exactly the
kind of claim this campaign exists to stop making.
Three gaps were reclassified as structural with individual justification,
covering physical hardware state and real AWS catalog inventory, and one
stale CloudFormation entry was dropped as a non-gap.
The suite also surfaced a second instance of the routing bug class fixed
earlier this branch: services/iotdataplane's matcher claims
/connections/{id} at a higher priority than outposts and was shadowing
real GetConnection calls. Fixed on the outposts side with a SigV4-gated
matcher rather than by raising MatchPriority -- priority escalation is
what produced the original bug. The iotdataplane-side fix is filed as
gopherstack-vpoh, and the two affected cases are skipped with that issue
cited rather than quietly dropped.
Gates: build and vet clean, golangci-lint 0 issues, the full -race suite
passes, and the Docker-backed integration suite passes with the one
documented skip. The pre-existing tag-routing isolation test was rerun to
confirm the matcher change broke nothing.
Refs gopherstack-b9mg
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
cmd/gendocs output had drifted from the manifests. The badge now reports 157 A and 2 B, matching live frontmatter, after mgn moved from A- to A. Also refreshes the directconnect and mgn service READMEs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…cement resiliencehub goes from B to A. It gains an SDK-driven integration suite over apps, app versions, resiliency policies, assessments, recommendations and tagging, plus real cross-service resolution: ResolveAppVersionResources now resolves an app version against the actual EC2, RDS and DynamoDB backends instead of echoing whatever it was handed, using the pattern grafana established and mgn reused. Its remaining gaps are genuinely structural and now say so. Bedrock-backed assessments and AWS's proprietary resiliency scoring have no derivable data source in an emulator -- the deliberate scorePlaceholder of 0.0 was already an honest admission of that, and it stays honest rather than being filled with an invented number. services/ec2 gains Outpost placement: RunInstances accepts Placement with an OutpostArn, instances carry it, and it surfaces wherever the SDK says it does. services/outposts consumes that, so launching onto an Outpost now depletes real capacity and terminating returns it, verified end to end through the real SDK client rather than asserted. outposts stays at B, and that is the right call. The capacity coupling was its last cross-service blocker, but two pre-existing buildable gaps remain: Order and CapacityTask lifecycles jump straight to their terminal state instead of passing through IN_PROGRESS, DELIVERED and WAITING_FOR_EVACUATION, and buildOrderingRequirements evaluates 2 of the 17 real check types. Both are buildable, so under the template's own rule they belong in gaps and gaps block A. Two stale historical notes in that manifest are marked superseded. Gates: build and vet clean, -race tests pass across all three packages, golangci-lint 0 issues, and the Docker-backed integration suites pass. Closes gopherstack-lxs2, gopherstack-9ij1 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| // ec2.Instance at all -- matches real RunInstances failing atomically. | ||
| var instanceIDs []string | ||
| if outpostArn != "" { | ||
| instanceIDs = make([]string, count) |
Foundation for showing resources from every region at once. The dashboard fans out concurrent per-region calls from the client; there is no backend wildcard region and no response annotation, because the UI already knows which region it called. ALL_REGIONS is a "__all__" sentinel rather than a real region name, since regions here can be arbitrary and any real-looking value could collide. currentRegion() resolves the sentinel down to DEFAULT_REGION, so the 149 pages not yet converted keep working exactly as before instead of receiving a region string they cannot use. Fresh users now default to All. Two region lists, kept deliberately separate. The full catalog comes from EC2 DescribeRegions and feeds the picker's autocomplete. The much smaller set of regions that actually hold data comes from /dashboard/api/system/regions and is what the fan-out iterates -- issuing a request per region in the full catalog on every page load would be unacceptable. A 404 from that endpoint is treated as empty and falls back to the default region, so the UI does not depend on the endpoint landing first. The hardcoded eleven-region array in +layout.svelte is gone; it was a second source of truth and had already drifted. multiRegionList takes a closure that performs the send itself rather than a client factory plus a command. That is not a style preference: passing a command through an extra layer of structural typing loses the SDK's per-call generic inference and widens every response to the client's broadest union. It also builds a new client per region, never reusing one, because @aws-sdk/core freezes a client's SigV4 signing region on its first request -- a reused client would sign the second region's request as if it were still the first. In single-region mode the helper collapses to exactly one call, and a rejection propagates to the caller's own try/catch with the original error intact rather than being swallowed into the errors list, which is only correct once more than one region is in flight. RegionChip renders on every resource including global services, since it is a filter affordance rather than a claim about storage, and global resources must not vanish when a region is selected. WriteRegionHint shows "using <region>" beside create actions only while All is selected. dax and dynamodb are converted as pilots. The remaining pages follow once this pattern has been reviewed, because it gets copied a further 190 times. Gates: svelte-check 0 errors across 19847 files, oxlint clean, formatting clean, 1911 tests across 174 files, production build succeeds. Refs gopherstack-eez5, gopherstack-iisp Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ns hold data Two region sources the dashboard's Region All mode needs. They are deliberately different lists and must not be conflated. DescribeRegions was returning stubRegions, a hardcoded ten entries with a comment admitting they were stubs. Real AWS has far more, so a wire-accurate operation was returning inaccurate data -- the same class of dishonesty this campaign has been closing elsewhere, and worth fixing on its own merits rather than as UI scaffolding. It now returns 34 regions read from the pinned aws-sdk-go-v2/service/ec2 v1.319.1 module's own endpoints data for the "aws" partition, so it tracks the SDK rather than a hand-maintained list. cn, us-gov and iso regions are excluded as separate partitions a commercial account does not see. The wire shape is untouched; only the data changed. GetSpotPlacementScores, the only other caller, follows the rename. Separately, the UI must fan out only to regions that actually hold something -- a request per region on every page load would be unacceptable. pkgs/service/regions.go tracks that with one middleware rather than a new interface method: ChaosRegions already exists on the service interface with 141 implementations that all just return the default region, so extending that path would have meant 161 edits for something the request path gives for free. The middleware hangs off registry.Use, the same chokepoint chaos.Middleware uses, and reads the region through the extraction that already happens there. The set is guarded by a lockmetrics.RWMutex with an RLock-first check so the common case, a region already known, never takes the write lock. Results are exposed at GET /dashboard/api/system/regions beside the existing system/state and system/health. The tracker persists its own recorded set through the existing snapshot manager. That detail matters: the first attempt seeded the set by scanning other services' persisted snapshots for region-code substrings, which produced false positives -- services/account bakes a static eight-region catalog into its default state as reference data, and a substring scan cannot tell that apart from a real resource, so a completely fresh server advertised eight regions with nothing in them. Persisting the tracker directly removes the guesswork. Seeding on restore is the requirement that makes this correct rather than merely working. Without it, regions holding restored data are unknown until something happens to touch them, and their resources are silently invisible in All mode -- a wrong answer that only appears after a restart with existing data. Verified end to end: a fresh server reports only us-east-1, writes to us-east-1, ap-south-1 and eu-west-2 make all three appear, and after a full restart all three are still reported before any new request, with the underlying resources intact. Gates: build and vet clean, -race tests pass, golangci-lint 0 issues across the whole repo, and DescribeRegions returns 34 regions live. Closes gopherstack-nh6m Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…est storm
CI reported four e2e failures after Region All landed. The cause was not
Region All, and there were eleven broken tests, not four.
Seven of them pointed at /dashboard/dynamodb/table/{name}, a route deleted
in e88712a when the orphaned detail page was folded into the main page's
?table= scheme. That commit checked that nothing in the UI linked to the
route and that its Go endpoints survived, but never checked test/e2e --
which navigated to it by path and had been getting a 404 ever since.
Folding those two pages together also silently dropped element ids the
tests depend on: the {id}-tab buttons, the PartiQL textarea, execute
button and output, and ttl-status-card. Those are restored on the merged
page. PartiQL's results now render through the shared table view that
Query and Scan use rather than a raw JSON block, so that assertion was
updated to the better rendering rather than the rendering reverted.
The rest navigate to the bare list page and exercise search, pagination,
purge and per-table ids -- none of which exist in the All-regions merged
list, which is deliberately read-and-open only. They now select a region
first, which is the correct behaviour for those tests rather than a
workaround.
The genuinely serious find is a request storm in the stream-events poller.
Its effect calls loadStreamEvents() synchronously, and that function's
first line reads streamEventsHtml -- a read inside the effect's tracking
scope, so the effect takes a dependency on it. The effect also writes
streamEventsHtml = '', and the async fetch writes real content back, so
every completed fetch retriggered the effect, which reset the value and
immediately refetched. Confirmed live in a browser: thousands of requests
per second, with no response ever surviving long enough to render. Wrapping
the initial loads in untrack() breaks the cycle -- the same hazard already
documented in region-effect.svelte.ts.
Region All remains the default; nothing was reverted to make tests pass.
Gates: full e2e suite passes in 256s, svelte-check 0 errors across 19847
files, oxlint clean, 1911 unit tests pass, go build clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Third instance of one bug class on this branch. iotdataplane's RouteMatcher
claimed the real AWS wire path /connections/{id} by bare path and method,
at priority 88 against Outposts' 85, so a correctly signed Outposts
GetConnection was silently answered by iotdataplane. Two integration cases
in outposts_test.go were skipped citing it.
The previous two instances were bedrockagent and cleanrooms both matching
/tags/ unguarded, fixed with httputils.MatchesTaggedResourceARN, which
disambiguates on the ARN's own service segment. /connections/{id} carries
no ARN, so that helper does not apply here.
pkgs/httputils gains ScopedPrefixMatch: prefix match plus SigV4 scope guard
in one call, matching when the request is unsigned or signed for the named
service and declining when signed for a different known service. Only the
ambiguous real-wire-path branch of iotdataplane's matcher is gated; its
topics, shadows, admin connections and retained-message routes are
untouched.
Default-allow-when-unsigned is deliberate. Roughly fifteen existing call
sites across the repo use strict `svc == serviceName` equality, which
forces every unit test to grow an Authorization header. That friction is
part of why this class recurred three times, so the shared helper is
built to drop in without it.
The audit that came with this found no other live collision. /tags/ is
universally guarded across all twelve services serving it. The /policies,
/v2/apis, /applications and /resourcepolicy overlaps are each protected by
one side being scope-gated with the ungated side sitting at lower
priority. One is worth knowing about: apigatewayv2 and appsync both claim
/v2/apis at equal priority, and only cli.go's registration order breaks
the tie today -- correct now, but it would fail silently if that order
changed.
One audit claim did not survive checking. It reported services/iot's
unguarded /things/ and /api/things/shadow/ prefixes as a live, larger
swallow of iotdataplane's whole Thing Shadow API. Exercised against a
running server through the real SDK, the entire family works:
UpdateThingShadow, GetThingShadow, named shadows,
ListNamedShadowsForThing and DeleteThingShadow all round-trip correctly.
The matcher does read as unguarded, so it is worth revisiting, but there
is no live defect and no bug was filed for one.
test/integration/tag_routing_test.go gains a connections isolation test
that registers a real iotdataplane connection and a real Outposts
connection, then calls both services' GetConnection through the shared
router in one binary run. That is the shape that catches this class --
every affected service passes its own suite in isolation.
Closes gopherstack-vpoh
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The last service below A. Two gaps that three previous passes had deferred as buildable-but-not-done are now closed, which takes the whole corpus to 159 A with nothing below. Orders and capacity tasks jumped straight to their terminal state. They now move through the real sequences, with enum spellings read from the pinned SDK's types/enums.go rather than invented: an order goes PREPARING to IN_PROGRESS to DELIVERED to COMPLETED with LineItem.Status moving in lockstep, and a capacity task goes REQUESTED to IN_PROGRESS to COMPLETED, with CancelCapacityTask pausing at CANCELLATION_IN_PROGRESS before resolving. The transitions use the chained work.After idiom mgn already uses, and two snapshot tests prove an intermediate status survives a restore mid-flight. Modelling the real sequence exposed three correctness bugs that only exist once intermediate states do: CancelOrder's window was too narrow and now stays open through IN_PROGRESS, closing at DELIVERED; the in-progress-order guard for a site now matches IN_PROGRESS as both operations' own doc comments already claimed; and order completion sets Outpost.ContractEndDate from PaymentTerm, which previously only CreateRenewal did. WAITING_FOR_EVACUATION is still not modelled, and stays a gap rather than moving to structural. The capacity model is additive only, so no running instance can legitimately block a task -- reaching that state needs a capacity-reduction path, which is a separate and larger piece of work, not the single-hop problem this closes. buildOrderingRequirements went from 2 of 17 checks to 12. The new ones are all derivable from state this backend already holds: a quote pointing at a deleted outpost, contract renewal due, missing operating or shipping address, country-code mismatch, US zip format, rack physical properties, and the three shipping-contact checks. Five are not implemented and each says why individually. Three are structural: AWS publishes no order quota anywhere in its documented limits, the real types.Outpost carries no generation fields at all, and there is no support-plan model. Two stay ordinary gaps because implementing them would be invention rather than emulation -- UNSUPPORTED is a catch-all with no documented trigger, and OUTPOST_STATE_CHANGED has no "changed relative to what" anchor in the SDK. The new white-box test needs a testpackage exemption, documented in .golangci.yml with its reason: the shipping-contact checks require a partially populated Address that the real SDK client's own validators refuse to construct, since every Address field becomes client-side required once the address is non-nil. That path cannot be reached through the real client the way this package's other tests are. Gates: build and vet clean, -race tests pass, golangci-lint 0 issues, and the Docker-backed integration suite passes driving each intermediate state through the real SDK client. Closes gopherstack-b9mg Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
services/account was graded A while meeting only B criteria, and was the only one of 161 services with no SDK-completeness coverage at all -- the account SDK was not even in go.mod, so no sdk_completeness_test.go could exist. The repo-wide sweep that reports every service as covered simply never saw this one. The two other services without that filename, iam and rds, call CheckCompleteness from handler_test.go and dispatch_test.go. Adding the module and the test surfaced two real operations that were never routed: GetPrimaryEmailUpdateStatus, which the bd issue named, and GetGovCloudAccountInformation, which nobody had noticed. Coverage is now 16 of 16 with an empty notImplemented list. GetPrimaryEmailUpdateStatus is backed by real state wired into StartPrimaryEmailUpdate and AcceptPrimaryEmailUpdate, with UpdatedAt as epoch seconds -- confirmed from the SDK's deserializer, which treats it differently from AccountCreatedDate's ISO8601. AcceptPrimaryEmailUpdate reports the terminal status ACCEPTED that its own real output type declares, rather than a fabricated COMPLETED. GetGovCloudAccountInformation returns ResourceNotFoundException, which the AWS reference documents as the response for an account with no GovCloud linkage -- true here, since this backend models a single standalone account. Recorded as an ordinary gap rather than structural, because services/organizations already models GovCloud linkage and the data could be produced by cross-service wiring later. The new integration suite immediately caught a fourth instance of the router prefix-collision class: services/inspector2 matched "/enable" and "/disable" as unscoped prefixes, swallowing Account's /enableRegion and /disableRegion before Account's own correctly-gated matcher ran. Those are exact fixed paths with no children in inspector2's own dispatch table, so they are now exact matches. EnableRegion and DisableRegion were unreachable end to end before this. One correction to that pass: it bumped accountSnapshotVersion from 2 to 3 for a purely additive field change. Restore discards on version mismatch via registry.ResetAll, so that would have destroyed every user's persisted account state on upgrade -- the same landmine already documented in services/dynamodb/persistence.go, repeated here because the warning lived only in that one file. Reverted to 2, since encoding/json decodes an older snapshot missing a new field perfectly well, and the reasoning is now recorded on this const too. Grade stays A, now on evidence: every routed op is ok across wire, errors, state and persist, completeness is green, and the integration suite passes against the container. Closes gopherstack-303i Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…egration cases Go 1.24+ cancels the context from t.Context() immediately before t.Cleanup runs, so every cleanup passing that context to an AWS call failed instantly with "context canceled". The calls are best-effort, so the failures were swallowed and the resources simply leaked. That matters more now that seven services have gained integration suites: state outliving its test makes a later test pass or fail for the wrong reason. Roughly 140 files now derive a fresh context through a cleanupContext(t) helper in test/integration/main_test.go rather than repeating the same four lines everywhere, so the pattern cannot quietly regress. Ten repeatable cases became three tables: grafana's three rejects-nonexistent-reference cases, networkmanager's two unknown-EC2 reference cases, and directconnect's not-found and tag-validation groups. The rest stay sequential deliberately. The backups parity test is one create-backup-describe-list-restore-delete pipeline where every step consumes the previous step's output. The tag-routing test tags every probe before listing any of them, which is the whole point -- collapsing it into independent cases would drop the ordering that catches cross-service contamination. Grafana's lifecycle subtests are distinct feature areas rather than variations of one call, and its accepts-real-resource cases each need different setup, so neither shares a row shape. Also fixes a tparallel failure in the new account suite: its subtests share the single account record and must run in order, which is now stated as a justified nolint rather than left failing. One correction worth recording. A detector I wrote to find the remaining cleanup blocks anchored on a closing brace at exactly one tab of indent, which does not match the nested subtests this same change introduced. It overran past the real end of each block and blamed unrelated code, reporting twenty phantom hits. A brace-balanced detector finds zero. The sweep was already complete; the tool was wrong. Gates: go vet clean, golangci-lint 0 issues across the whole repo, and the integration suite passes against Docker. Closes gopherstack-e5it, closes gopherstack-hgbq Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ht wire bugs Four unrelated pieces of hygiene. cmd/gendocs builds the root README parity table, every per-service README and the badges from PARITY.md frontmatter, and nothing in CI ran it, so those artifacts drifted silently -- they were wrong for a long stretch before anyone noticed by hand. A new job runs make docs and then git diff --exit-code, so editing a manifest without regenerating now fails the build. It caught stale output immediately: account's two new operations and cloudfront's manifest change had already moved the counts. test/terraform fixtures all hardcoded the same VPC CIDR, so parallel subtests raced for 10.0.0.0/16 and collided. Each fixture now takes its CIDR through a template variable derived per test, which removes the overlap. A flaky gate is worse than a slow one -- this one made every verification run ambiguous, which is exactly the wrong property while a parity campaign is landing. nav.test.ts previously globbed only top-level routes when checking for drift. It now reads cli.go and asserts that every advertised dashboard route has both a backend directory and a registration, so "the UI offers a service with nothing behind it" becomes structurally impossible rather than something a person has to spot. That exact problem shipped once before. Two quicksight bugs found while implementing TopicV2 and left open at the time. SearchTopics read MaxResults and NextToken from query parameters, but the real serializer carries both in the JSON body for that operation, so SDK-driven pagination was silently ignored and callers always got the first page. DeleteTopic omitted the Arn its real output type declares. SearchTopicsV2 and DeleteTopicV2 already did both correctly; the difference is now documented inline so the next reader sees why the two operations differ. Gates: go build and vet clean, quicksight tests pass under -race, golangci-lint 0 issues, 1912 UI tests pass, and the CI workflow parses. Closes gopherstack-pvv1, closes gopherstack-6oc4, closes gopherstack-cmo1, closes gopherstack-fp77 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…vice import resolution CloudFront distributions never left InProgress. They now transition to Deployed on their own, using the worker-group After idiom that mgn and outposts already use rather than the older ticker pattern CloudFront's own invalidations use. That transition also survives a restart, which the existing implementations of this pattern do not: a scheduled timer is not part of any snapshot, so mgn and outposts both silently drop an in-flight transition on restore. Restore here re-arms any distribution left mid-InProgress. The same latent gap in those two services is worth fixing separately. Rooting the worker group's lifetime means the constructor now takes a context, matching mgn, outposts and grafana, which all already have that shape. That is a repo-wide change: about fifty call sites inside the package plus cli_test.go, internal/teststack and a cloudformation test. Package- scoped verification missed the last three -- only go build ./... catches a change to an exported constructor. resiliencehub's ImportResourcesToDraftAppVersion accepted SourceArns and EksSources as opaque strings. It now resolves them through the same sibling-service mechanism ResolveAppVersionResources already used, extended to EC2, RDS and DynamoDB, dispatching on the ARN's service segment. An ARN whose service is wired but whose resource does not exist fails the import with a not-found message; an ARN for a service with no resolution wired stays honestly unresolved, matching the existing precedent for AppRegistry and Terraform sources. Building that surfaced two wire bugs in other services, filed rather than fixed here since both are outside this change: DynamoDB's CreateTable omits TableArn although DescribeTable emits it, and RDS omits DBInstanceArn from both CreateDBInstance and DescribeDBInstances despite building that ARN elsewhere. Both confirmed live. The integration test constructs those ARNs by hand as a result. The quicksight re-audit found three of its four "spot-checked in full depth" claims were false. CustomPermissions does not model Governance at all. Brand omits VersionStatus even though the backend tracks it and an unused JSON key constant for it exists -- a wiring bug, not a structural gap -- along with Errors and Logo, which genuinely have no backing state. AccountLevel was half right: AccountSettings holds up, AccountInfo is missing IAMIdentityCenterInstanceArn. Only Embed survived intact. The manifest now says what is actually true, and states that only the two types the original claim named were re-checked rather than implying the whole family is clean. Gates: build and vet clean repo-wide, -race tests pass, golangci-lint 0 issues, and the Docker-backed integration suites pass including the new distribution-transition and import-resolution tests. Closes gopherstack-k3fi, closes gopherstack-8hw8, closes gopherstack-taqn Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two reported omissions turned out to be one much wider defect. DynamoDB built TableArn correctly for DescribeTable but dropped it from the three other places that construct a TableDescription -- create, update and delete. The value existed; it was simply never serialized on those paths. Backups, exports and imports were already correct. RDS was worse than reported. DBInstance had no ARN field at all, on any operation, despite the tag store already computing the same ARN as its map key -- the value was being derived for tagging and then thrown away. The same was true of DBCluster, DBClusterSnapshot, DBSnapshot and DBParameterGroup, none of which carried an ARN anywhere. All five now do, with field and XML names checked against the pinned SDK deserializers rather than guessed. Instances needed fixing at six construction sites but only one serializer, since a single function serves create, delete, describe, modify, read-replica, restore, reboot, start and stop. The reason this class keeps appearing is that unit tests marshal through our own structs on both sides, so a field missing from the wire never fails. Both fixes therefore ship with integration tests driving the real SDK client, and both were proven red before green: stashing only the source changes and rebuilding made all five new tests fail on the exact missing ARNs, and restoring made them pass. Anything that resolves an RDS or DynamoDB resource by ARN -- including the cross-service wiring resiliencehub now uses for ImportResourcesToDraftAppVersion -- previously could not obtain one from the API at all and had to synthesize it. Gates: build and vet clean, -race tests pass, golangci-lint 0 issues, and the Docker-backed integration suites pass. Verified live afterwards: create-table returns TableArn, and create-db-instance and describe-db-instances both return DBInstanceArn. Closes gopherstack-x9qe, closes gopherstack-pimh Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nct histories Two real defects, both of the same shape: a key that nothing ever wrote to, and a key that collapsed things that should be distinct. EC2's tag filter for key pairs looked up tags under a synthetic "keypair-"+Name key, but CreateTags and setTagsLocked store key pair tags under the bare name. So a tag: filter on DescribeKeyPairs matched nothing, silently, forever -- the filter appeared to work and simply returned empty. Fixed, and the adjacent gap closed while there: DescribeKeyPairs now returns KeyPairId, KeyType, CreateTime and TagSet, and CreateKeyPair and ImportKeyPair honour create-time TagSpecifications, all field-diffed against the pinned SDK. Most of that ticket's other items had already been fixed across four prior passes. Each claim was re-verified directly against the code and the SDK rather than trusted, and they hold. SWF keyed executions and history by domain and workflow id alone, so a second run of the same workflow silently overwrote the first. The SDK makes RunId a required field on WorkflowExecution, and this backend was already parsing it off the wire and then discarding it. Executions and history are now keyed by domain, workflow id and run id, with an index and resolver threaded through about twenty-five call sites across activity tasks, decision tasks, orchestration, signals and executions. The same issue's LRU eviction bug is fixed too: evicting an execution left pending and active task rows pointing at something that no longer existed. Eviction now purges them. One pre-existing SWF test had encoded the single-history-blob bug as expected behaviour; its assertions are corrected rather than worked around. EC2's DescribeApplicationStatus per-check timestamps and details move to structural_gaps -- they need real HTTP health-check execution, which this backend cannot have. Everything else stays in gaps, buildable but not attempted: ED25519 key generation, ENI security groups, EBS DataEncryptionKeyId, MaxResults truncation across about twelve families, and SWF's queue snapshot exclusion and ScheduleLambdaFunction. Gates: build and vet clean, both packages pass under -race, the full short suite passes repo-wide, golangci-lint 0 issues, and the integration suite passes including outposts and resiliencehub, which read EC2 state through cross-service wiring. Closes gopherstack-8pce, closes gopherstack-jsi8 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ite hints Continues the Region All rollout. rds, lambda, dynamodb, kinesis, cloudwatch, efs, firehose, eventbridge, sfn, dax, secretsmanager and ssm now fan out concurrently across the regions that hold data, render a region chip on every row, and show the "using <region>" hint beside create actions while All is selected. Single-region behaviour is unchanged. Four pages carry a chip without fan-out, deliberately: detective, lambda/function and sagemakeruntime are single-resource detail views with nothing to fan out, and route53 is global, so querying it per region would be meaningless. The chip still belongs on all four, since it is a filter affordance rather than a claim about storage. Caches keyed on a bare resource name are re-keyed by region and name. Under All that is not a nicety: the same name legitimately exists in several regions at once -- a table called orders really does render twice, once for eu-west-2 and once for us-east-1 -- so a name-keyed cache shows one region's data under another region's row. Clearing on region change does not help here, because in All mode there is no change event to hang it on. Also fixes three type errors I introduced by committing the nav test without re-running svelte-check: it reads cli.go and the services directory from disk to assert every advertised route has a real backend, which needs node typings that were not configured. The guard is worth keeping, so the typing is fixed rather than the test weakened. Gates: svelte-check 0 errors across 19955 files, oxlint clean, formatting clean, 1958 tests pass across 174 files, production build succeeds. Refs gopherstack-hrrz, refs gopherstack-ks2s.20, refs gopherstack-b1m8 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Four follow-ups, and three of them turned out to be things that looked implemented but did nothing. Bedrock Runtime's chaos hooks could never fire. ChaosServiceName returned "bedrockruntime", but the real SDK signs every request with "bedrock" -- confirmed in the pinned module's auth.go. Since the chaos middleware matches fault rules against the signing name in the Authorization header, no rule could ever match real client traffic, so fault injection for InvokeModel and Converse was silently dead despite the hooks existing. A one-line fix, with a test that fails without it. An audit of every other service's ChaosServiceName against its SDK signing name found no further mismatches, so the class is contained. EMR's ListInstances returned nothing at all for fleet-based clusters. Fleets now synthesize instances from their real provisioned on-demand and spot capacity, and the InstanceFleetId and InstanceStates filters -- which were dead -- work, along with InstanceFleetType, which was missing entirely. RunJobFlow also carried four Cluster fields it then dropped on the floor: monitoring configuration, log encryption key, repo upgrade on boot, and the legacy AMI version. They now reach DescribeCluster. WAF's GetSampledRequests accepted any WebAclId and succeeded. It now validates against real state and returns WAFNonexistentItemException for one that does not exist. RuleId stays unvalidated because AWS accepts three different shapes there and there is no single store to check against. Textract now validates AdaptersConfig against real adapter and adapter version state, returning InvalidParameterException rather than ResourceNotFoundException -- the documented trap here, since AnalyzeDocument's real error set has no not-found case at all. HumanLoopConfig's required members are validated too. What genuinely cannot be produced moved to structural_gaps with individual justification: WAF sample and managed-key content, because nothing proxies requests so there is no traffic to sample; Textract's human-loop activation decision, which needs a SageMaker A2I rules engine that exists nowhere here; and four EMR fields needing cross-service topology, a real EC2 instance, undocumented AWS policy data, and a runtime clock respectively. Fleet instances still report a blank InstanceType, which is buildable and stays in gaps rather than being reclassified. WAF Classic had no integration coverage at all and now does. Also picks up regenerated READMEs for ec2 and swf, which were stale relative to manifests committed earlier. Closes gopherstack-smld, closes gopherstack-dqd8, closes gopherstack-n1bo, closes gopherstack-ayfw Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…-step ones Region All now covers 24 pages with fan-out and 28 with region chips. This batch adds ecr, eks, glue, sagemaker, backup, codebuild, codepipeline, acm, cloudformation, sqs and sns, plus the two flat-list tabs of athena. Several needed more than a single list call: glue fans out five separate lists, sagemaker five, and codebuild and codepipeline each do a two-step List-then-describe per region. Per-row actions rebuild their client against that row's region, so acting on a resource shown in eu-west-2 targets eu-west-2 rather than whatever the write default happens to be. athena is deliberately partial. Its Workgroups and Data Catalogs tabs are flat resource lists and are fanned out; the Query Editor, Sessions, Notebooks, Prepared Statements, Saved Queries and Query History tabs are each keyed to one workgroup or session chosen in a selector, so there is no per-row region to fan against and pretending otherwise would misrepresent what Run Query targets. Two things fixed along the way that now apply everywhere. Optional-chained narrowing of the form selectedX?.foo === bar && selectedX.region === row.region does not reliably narrow the type here, so it is written out explicitly. And making region resolution async let independent loaders race: ECR fires two on region change, and the unrelated one consumed a response the test had mocked by call order. The page behaviour was correct; the tests were keyed on ordering that no longer holds, so they key off command name instead. Every page test also had to pin a region, since none of them did and the jsdom default is now All with no stored preference — something those tests were never written against. Twelve pages remain, and they are the largest: s3, ec2, iam, kms, ecs, apigateway, apigatewayv2, cloudwatchlogs, elasticache, elbv2, cognitoidp and batch. iam still needs the global-service treatment specifically. Gates: svelte-check 0 errors across 19955 files, oxlint clean, formatting clean, 1994 tests across 174 files, production build succeeds. Refs gopherstack-hrrz, refs gopherstack-ks2s.20, refs gopherstack-b1m8 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…lent no-ops securityhub needed no work: its GetFindingsV2 composite filters, the real BatchUpdateFindingsV2 wire shape and the ListMembers documentation had all landed in a prior pass. Verified the implementation is a genuine field-by-field ASFF crosswalk rather than a disguised stub, then left it alone. vpclattice gains four families -- Resource Gateway, Resource Configuration, Service Network Resource Association and Domain Verification -- twenty operations, field-diffed against the pinned SDK. That included preserving a real inconsistency in AWS's own API, which names the field vpcIdentifier on Create and vpcId on Get and Update; matching the SDK matters more than making it tidy. Three silent defects turned up while doing it, all of the same shape as the day's other finds. PutAuthPolicy and PutResourcePolicy keyed their map by whatever identifier the caller passed, an ID or an ARN, while cascade delete always removed by ARN. A policy written with a short ID was orphaned the moment its parent service was deleted -- nothing errored, the row simply survived pointing at nothing. CreateServiceNetworkVpcAssociation accepted dnsOptions on the wire and discarded it. It now round-trips. AppSync ignored a resolver's Code field entirely, so every APPSYNC_JS resolver silently behaved as if it had no mapping at all, and PIPELINE resolvers were never distinguished from UNIT -- field resolution read DataSourceName directly, which a pipeline resolver does not set, so configured Functions never ran. Both fixed by sharing one mapping abstraction between resolvers and functions. The VTL renderer also had no $context.prev.result support, which a real pipeline template would have rendered as a literal string. awsconfig's PutConformancePack parsed only JSON despite the API documenting YAML, and TemplateS3Uri and TemplateSSMDocumentDetails were absent from the wire struct altogether -- a client sending either got it dropped by the decoder with no error and deployed zero rules with no indication why. Both are now parsed, and specifying more than one of the three mutually exclusive template sources is rejected as the real API requires. Left honestly in gaps rather than reclassified: fetching the S3 and SSM template bodies needs cross-service wiring in cli.go, outside this pass; vpclattice's endpoint associations are populated only through EC2 CreateVpcEndpoint, which this backend does not model; and AppSync pipeline before-mapping and DynamoDB JS helpers are outside the documented subset this evaluator implements. Gates: build and vet clean, all four packages pass under -race, golangci-lint 0 issues with a RouteMatcher complexity finding fixed by decomposition rather than suppression, and the Docker-backed integration suite passes. Closes gopherstack-8j08, closes gopherstack-lx2k, closes gopherstack-ivwh, closes gopherstack-ag85 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
apigateway, apigatewayv2, cloudwatchlogs and batch now fan out across regions with chips and write hints. IAM gets the chip without fan-out, which is the correct shape for a global service: its resources are not regional, and hiding IAM users because someone selected eu-west-1 would read as a bug rather than a filter. The chip is a filter affordance, not a claim about where something is stored. Region All now covers 28 pages with fan-out and 33 with chips. Seven remain, all among the largest files in the app: s3, ec2, kms, ecs, elasticache, elbv2 and cognitoidp. Gates: svelte-check 0 errors across 19955 files, oxlint clean, 2009 tests across 174 files, production build succeeds. Refs gopherstack-hrrz, refs gopherstack-b1m8 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… s3/ec2/kms fan-out The starkest find of the day is in Firehose. Its Redshift delivery built a live aws-sdk-go-v2 redshiftdata client with no endpoint override and no credentials, so every delivery attempt would have travelled to real AWS and failed. It looked like working code and had never delivered a record. Replaced with a RedshiftDataExecutor interface following the existing S3Storer and LambdaInvoker pattern, and delivery now does what AWS documents: stage the records to the destination's S3 bucket, then issue a real COPY from that key with the configured columns and options. Wiring it to the local redshiftdata service belongs in cli.go and is deferred, so it is an honest logged no-op rather than a silent live network call. CloudWatch metric streams now actually deliver to Firehose. The cross-service contract was verified rather than assumed: firehose's PutRecordBatch structurally satisfies the new FirehosePutter interface with no adapter, and an end-to-end test wires a real firehose backend and confirms a record lands in its S3 destination. PutInsightRule's validation also deepened from "is well-formed JSON" to the real Contributor Insights rule syntax. Cleanrooms' PrivacyBudget wire struct labelled its type key privacyBudgetType when the real key is type, carried three invented duplicate identifier fields, and omitted createTime and updateTime entirely -- the same systemic bug a previous pass fixed across this service and missed on this one struct. Change requests are now a real typed union instead of a bag of maps, and committing one applies genuine effects: adding a member, toggling receive-results ability, writing auto-approved change types. Privacy budgets compute real epsilon and aggregation counts rather than returning fixed shapes. ELBv2 gains rule transforms end to end, with the documented Transforms/ResetTransforms mutual exclusion enforced. On the UI side, s3, ec2 and kms complete another slice of Region All. s3 takes the chip without fan-out: the bucket namespace is global and ListBuckets returns every bucket from any region, so fanning out would issue N identical calls, while each row still shows its real location. One judgement worth recording: an over-strict reading of the Contributor Insights schema broke a pre-existing, passing integration test, and the right call was to relax the new validation rather than assume documentation beat a test that was already green. Gates: build and vet clean, all four services pass under -race, golangci-lint 0 issues, 2020 UI tests pass, and the Docker-backed integration suite passes. Closes gopherstack-ohdc, closes gopherstack-q1z2, closes gopherstack-kiqa, closes gopherstack-lrmf Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nfigurations Two more of the nine missing serverless families, picked for being the most self-contained: resource policies depend on nothing, and snapshot copy configurations only on namespaces. Delete is not uniform across this service. Deleting a snapshot copy configuration returns the deleted object, and the response marks it required, where deleting a resource policy or a custom domain association returns nothing at all. Assuming one shape for all three would have been wrong in both directions. The envelope convention does hold for both of these, so the custom domain family's flat responses remain the exception rather than a pattern. No one-configuration-per-namespace limit is modelled, because the service documents none -- unlike its non-serverless counterpart, which does. The remaining five are recorded. Recovery points, table restore status and the two restore operations are mutually dependent and should be taken together; endpoint access and the managed workgroup listing are separate and smaller. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…eir restore operations The entangled group, taken together because a table restore from a recovery point needs a real recovery point to name. There is no operation that creates a recovery point. The API documents them as made automatically every thirty minutes and kept for a day, so one is generated when a workgroup is created rather than exposed as an endpoint that does not exist. Seeding more for tests goes through an internal helper, not the wire. The per-field timestamp split this service is prone to shows up inside this one group: a recovery point's creation time is ISO 8601 while a table restore's request time is epoch seconds. Restoring a namespace from a snapshot is deliberately still absent -- it depends on no recovery point, so it was never part of this group -- along with converting a recovery point to a snapshot. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Timeouts were accepted, stored and echoed back on describe, and never enforced -- the timed-out status existed and nothing ever set it. That also left terminate as the only way to trigger a child policy, where the real service invokes it on exactly two events, terminate and timing out. An execution past its limit now closes with a timed-out event carrying the child policy and timeout type the API requires, and the cascade runs through the same code terminate already used. The sweep is synchronous, taking the instant to evaluate as an argument, and runs at the top of the operations that read or change execution state. No goroutine, and no waiting in tests. Only the execution-level limit is enforced. Decision task and the four activity task timeouts are still accepted and ignored, and the audit now says so per operation -- a timeout that fires for some kinds and not others is worse than one that never fires, since the difference is invisible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Create and modify endpoint accept nineteen engine-specific settings blocks and modelled none of them, so a client configuring an S3 target or a Kafka broker got a success and an endpoint with none of that configuration. Modelling them properly means about three hundred fields across nineteen heterogeneous structs, which is more than one change can do faithfully, and a subset would be worse than the gap: a caller seeing some settings kept would reasonably assume the rest were. So the request is refused, naming the block that is not supported, the way unsupported inputs are already refused elsewhere in this repo. That does mean refusing something the real service accepts. It is the honest of the two failures -- a caller now learns immediately, instead of discovering later that the endpoint was never configured. Nothing is stored, so describe has nothing new to omit, and the password handling from the earlier pass is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Endpoint access, managed workgroup listing, restore from snapshot and converting a recovery point to a snapshot. All nine families the audit recorded as absent now exist. Endpoint access omits its VPC endpoint object entirely, following what this package's classic Redshift already decided: the network interfaces underneath need availability zones, addresses and subnets that nothing here can produce, and inventing identifiers with no interface behind them would be worse than leaving the object out. The VPC filter is refused for the same reason. What is real -- address, ARN, status, port, subnets, security groups -- is served. Managed workgroups always list empty, and that is the honest answer rather than a stub: the source ARN is pattern-locked to a Glue catalog, so these exist only where Lake Formation federation provisions them, and this backend has no such integration for anything to come from. Restoring a namespace from a snapshot follows the recovery-point restore already here. Managing the admin password is honoured only in the direction that has meaning; the other reinstates credentials as they were when the snapshot was taken, which is not reconstructible, so it is left alone rather than faked. Deleting an endpoint access echoes the deleted object, unlike deleting a resource policy or a custom domain association. That is the third distinct delete shape in this service. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A pipeline definition given as an S3 location was rejected outright, which was honest but useless. It is now fetched from the S3 backend, wired the way the other cross-service integrations are. Rejection remains only where the object genuinely cannot be read -- no backend, missing bucket or key, or a failed read -- so a caller is told rather than handed a fabricated pipeline. The wiring test drives initializeServices, so deleting the call site fails it; the helper compiling proves nothing. Restricted instance groups stay unmodelled for a third pass, and the audit now records the whole verified type tree so the next attempt does not re-derive it. Two findings from that reading: the instance storage config really is a discriminated union, unlike the orchestrator beside it, which only reads like one; and there is a second top-level field nobody had named, carrying its own shared environment config. Eight further types, across two fields rather than one -- comparable to the whole four-field pass that preceded it, and not something to shave down. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… a stack Neither an app nor a resiliency policy could be created through a stack. Both follow the supplemental-resource pattern the KMS and Secrets Manager types already use, calling the real backend and failing loudly rather than returning a stub id. Resilience Hub already imports this package, so the reverse import would cycle. The dependency is declared here as an interface the other side satisfies structurally, which is the same technique its own cross-service resolution already uses. The template body and resource mappings are required by the resource type and are not fields of the create call at all -- they are separate operations chained after it. Tags on these two are a plain map rather than the array of pairs most resources take, and Ref yields the ARN, which is what the physical id is set to. Drift status via GetAtt still falls back to the physical id. Reading it needs a backend, and the attribute resolver is deliberately pure, so that would change every resource type's signature. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two operations had no surface. Everything they return was already shown elsewhere except the additional-info map, which nothing displayed and no route referenced -- the earlier judgement that they were redundant held for every field but that one. The app detail view now lists it and edits it, following the tags editor beside it. Updates replace the whole map rather than merging, so both adding and removing resend all of it. The draft version is addressed directly, which is what this emulator assesses, so nothing here assumes a published version exists. The other fifteen unwired operations stay unwired: they return empty by design here, and a tab over nothing is worse than no tab. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…led one The compatibility setting was stored without being checked at all, so any string was accepted as a mode and none of the modes did anything. Create and update now reject anything outside the eight legal values, and registering a second version under the disabled mode is refused, which is that mode's entire meaning. The six diffing modes stay unenforced and are recorded as such. Each needs real structural comparison per schema format, and a heuristic would be worse than the current absence: a caller trusts a compatibility pass, so wrongly accepting an incompatible evolution defeats the point of asking. DQDL is untouched for the same reason at larger scale. Validating it means a lexer and parser for a dozen rule types, and there is no slice of it that can be done without that scaffolding, so a partial check would accept malformed rules while looking like validation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The create call had no field for a schema definition at all, so a client doing the documented thing -- creating a schema and its first version in one request -- got a versionless schema and no error. It could not even be attempted: there was no parameter to pass one through. A definition supplied at create now becomes version one, and the response carries what it made: the version id and status, the latest and next version numbers, and the checkpoint. An invalid definition creates nothing at all rather than leaving a schema behind. That settles where the single version allowed under the disabled compatibility mode comes from. Creating with a definition consumes it, so a later registration is refused; creating without leaves it open for the first registration. Both are asserted, since the difference is invisible from the outside. The audit said this was still an open gap. Corrected, along with the note from the previous pass, which was written when registration was the only way a first version could exist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… quota A policy created through the simplified default-policy flow came back without the flag that says so, so a client following AWS's own documented path could not tell what it had made. The flag is derived from the policy language at read time rather than stored a second time, so the two cannot drift apart. Creating policies was also unbounded. The service publishes a default of a hundred per region, and this refuses past it with the error the API's own catalogue defines for the case. StatusMessage needed no change and that is the finding: it is populated only for a policy in the error state, which this backend never enters, so an empty value here matches the real service rather than standing in for one. The detail view shows the flag, checked in a browser against a policy created through the real form. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e services that own them Applying security groups or attaching subnets accepted identifiers that did not exist, and an HTTPS listener accepted any certificate ARN. All three have real typed errors in the API for exactly those cases, so the emulator was accepting what the service rejects. The backends needed were already here, so this wires them rather than recording another gap: EC2 for groups and subnets, and both ACM and IAM for certificates. A certificate ARN may name either, which the error's own wording says, so consulting only ACM would have refused valid ones. An unwired resolver stays permissive, as the other cross-service checks in this repo do, so nothing that worked before now fails. The policy limit stays unenforced. The published quotas for this service list load balancers, listeners and registered instances, and nothing for policies -- checked because a sibling issue today found a real quota where one had been assumed absent. Here it is genuinely absent, and inventing a number would be worse than the gap. Create's own inline groups and subnets are still unchecked, which is a narrower gap than before and recorded as such. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s that were dropped SAML settings and auto-tune maintenance schedules were parsed and thrown away. Both are modelled now, with the validation the SDK itself performs, and SAML echoes back without the credentials real AWS never returns. Adding the schedules exposed a worse fault underneath: the domain config response used the wrong auto-tune shape entirely -- the domain-status one, which has no maintenance schedules to carry -- and a generic status where this field has its own. It was impossible to add the schedules faithfully without correcting that first, and a test asserted the wrong shape. Deployment strategy and package timestamps are modelled too. Package error details stay absent: nothing here can fail a copy, so there would be nothing to report. Domains still become ready immediately, and that is deliberate. Every field a client polls agrees with the others, so nothing claims to be pending while its neighbour says finished, and this API has no waiter of its own. VPC id and availability zones still need an EC2 lookup this service cannot reach; what the wiring would take is recorded. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… three published quotas A serverless cache already recorded which user group it belonged to, but the user group never listed them back, so the association was only visible from one side. The reverse lookup mirrors the one replication groups already have. Three quotas the service publishes are now enforced with the fault types its own API defines for them: subnet groups per region, subnets per subnet group, and serverless caches per region. Each was checked against the operation's real error set rather than assumed to belong there. Recurring charges stay empty. They are live pricing state rather than a fixed table, and no published rule reproduces the amounts, so any value here would be invented. Snapshot contents stay metadata-only for a different reason: replaying real keys is buildable but spans every Redis type, which is more than this warranted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… stop accepting LIMIT Select results were only ever served back through GetJobOutput. The real service writes them under the output location the job asked for -- a job snapshot, the result parts, and a manifest listing them, with errors and their own manifest on failure. That is wired now, idempotently and best effort, so a missing bucket logs rather than failing a job that already ran. GetJobOutput still serves the bytes as well, since nothing documents what the real service returns there for a select job. The grammar subset turned out to be wrong in the opposite direction from the note. Joins and subqueries are genuinely unsupported by the real service, so their absence here is correct. But LIMIT was accepted and honoured, and the real service documents it as not supported -- the parser had a clause for it and the tests listed it as valid. It is refused now. Still missing, and recorded rather than guessed at: CAST, NOT, BETWEEN, IN, LIKE, arithmetic and the null-coalescing functions are all real and absent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
No description provided.