Chore/parity upgrade - #2414
Conversation
Six issues from the PITR investigation and the parity survey that preceded it: make docs missing from CI so badges and README drift, stale PARITY.md frontmatter on three shipped services, seven services with no SDK-driven integration tests at all, the grading policy question for guardduty and wafv2, the PITR defects themselves, and a nav test that should assert a backend exists for every advertised dashboard route. Also closes gopherstack-1gfi, whose concrete finding was resolved by 87dee6d; its surviving hardening recommendation carries forward. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
First batch of the dependency upgrade: `go get -u=patch ./...` across all 464 modules, then `go mod tidy`. 43 direct modules moved, all patch-level — roughly 40 aws-sdk-go-v2 service clients (s3 v1.106.0 to v1.106.4, iam v1.56.0 to v1.56.2, lambda v1.100.0 to v1.100.2, and similar bumps for kms, ssm, sqs, sns, secretsmanager, ecr, ecs, eks, dynamodb, route53resolver, redshiftdata, codedeploy, codepipeline, amplify, appsync and iot), the AWS internal support packages (eventstream, config, credentials, internal/v4a, feature/ec2/imds, and the checksum, presigned-url, s3shared and accept-encoding internals), plus gopsutil, moby/moby/client, modernc.org/libc, golang.org/x/exp and genproto. No source changes were needed anywhere — `go build ./...` and `go vet ./...` are both silent. The AWS core is a non-event: aws-sdk-go-v2 v1.43.3 and smithy-go v1.27.6 were already at their latest releases, and the feature/ and internal/ packages had already been carried forward by the patch sweep, so requesting them at @latest changed nothing. Since no new SDK surface appeared, the coverage check is unmoved: zero forward failures across all 159 services, and the reverse phantom check still reports exactly the three known services (iotdataplane's 3 admin-only extensions, rds' GetPerformanceInsightsMetrics, s3's 3 presigned pseudo-ops). 158 direct modules remain behind — the aws-sdk-go-v2 service minors and the non-AWS majors, which are the next batches and are where actual parity fallout is expected. Gates: 66612 tests pass uncached, golangci-lint 0 issues, govulncheck finds nothing our code calls. One pre-existing advisory remains (GO-2026-5932, unmaintained golang.org/x/crypto/openpgp, no fix available) in a required-but-uncalled module. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ling we lack
Roughly 166 packages were behind. Shipped in gated stages:
The AWS SDK: 157 @aws-sdk/client-* packages plus credential-providers,
3.1094.0 to 3.1102.0. This also carried the undici override from 7.28.0
to 7.29.0, which clears two audit findings (one high, one moderate --
response-desync and cache-poisoning advisories) that npm audit already
flagged on this branch.
Svelte, Kit and Vite moved together, since runes and the vite plugin API
are coupled and a partial bump mismatches: svelte 5.56.7 to 5.56.8,
@sveltejs/kit 2.70.1 to 2.70.2, vite 8.1.5 to 8.2.0.
Tooling minors: oxlint 1.75.0 to 1.77.0, oxfmt 0.60.0 to 0.62.0,
svelte-check 4.7.3 to 4.7.4. No new lint or type findings.
jsdom took its major, 29.1.1 to 30.0.1, staged on its own because it is
the test-environment package the deferred goto-mock timing depends on.
url-state.test.ts was verified explicitly on top of the full suite; the
deferred-write mock in vitest.setup.ts is untouched and still behaves.
Tailwind needed no work at all -- it, Vitest, adapter-static and
@testing-library/* were already at their latest versions.
Two upgrades are deliberately not here, reverted rather than forced:
TypeScript 7 is blocked upstream. svelte-check 4.7.4, already the latest,
refuses to run under it: "TypeScript 7 support currently requires both
TypeScript 7 and TypeScript 6 installed... requires using the --tsgo or
--tsgo-experimental-api flag". Taking it would mean a dual-install npm
alias plus an experimental flag. Pinned back to 6.0.3.
@bufbuild/protobuf 1 to 2 and @connectrpc/connect{,-web} 1 to 2 generate
ui/src/lib/api/gopherstack/dashboard/v1/*.ts through buf, driven by
proto/buf.gen.yaml with plugins pinned at bufbuild/es v1.10.0 and
connectrpc/es v1.6.1. That config lives outside ui/, the buf and protoc
CLIs are not available here, and v2 changes the generated code from
class-based to schema-based -- hand-patching generated files is not a
substitute for regenerating them.
Gates: check 19839 files 0 errors 0 warnings, lint clean, fmt clean,
1911 tests pass across 170 files, build succeeds.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…erations
Batch 3 of the dependency upgrade. 156 of the 169
aws-sdk-go-v2/service/* modules moved; 136 were patch-only. The 20
minor bumps are the interesting ones: ec2 v1.317 to v1.319.1, glue
v1.149 to v1.152.0, sagemaker v1.261 to v1.263.2, quicksight v1.121 to
v1.123.1, iam v1.56.2 to v1.58.1, rds v1.123 to v1.124.1, cloudwatchlogs
v1.80 to v1.81.1, dynamodb v1.62.3 to v1.63.1, wafv2 v1.76 to v1.77.3,
and eleven others.
Nothing failed to compile and no source changed -- go build and go vet
are both silent.
What the bump did do is exactly what an SDK bump is supposed to do here:
make new AWS surface visible. TestSDKCompleteness now reports 31
operations we do not implement, across six services:
ec2 13 Application Status Check family, Transit Gateway
policy table entries
quicksight 8 TopicV2 family
kafka 5 Channels family
glue 3 data-quality ruleset evaluation, catalog export config
directconnect 1 ListVirtualInterfaceRoutes
dynamodb 1 SearchVectors
All 31 are additive new feature families, not renames. The reverse
phantom check confirms this: it found zero new entries, still reporting
only the three known exceptions (iotdataplane's admin extensions, rds'
GetPerformanceInsightsMetrics, s3's presigned pseudo-ops). There is no
operation we advertise under a name the SDK has since changed.
The two cleanup categories this batch was meant to sweep were both
empty. No notImplemented manifest entry has gone stale, and no route
needed re-pointing at a renamed operation.
Implementing the 31 operations is deliberately not in this commit -- they
need real backend state and wire shapes verified against the bumped SDK,
which is its own scoped work rather than something to bury in a
dependency bump.
Gates: go build and go vet clean, golangci-lint 0 issues. The unit suite
is red only on the six TestSDKCompleteness failures documented above.
One unrelated pre-existing flake surfaced under full parallel load
(services/eks TestAsyncLifecycle_Nodegroup, "status = CREATING, want
ACTIVE"); it passes in isolation and no eks module or source was touched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
31 new operations across six services, the two UI upgrades deferred for missing tooling, and the eks nodegroup flake. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…r services Four of the six services that TestSDKCompleteness started failing after the service-module bump. ec2 (13 ops) and quicksight (8) follow separately. kafka gains the whole MSK Channels family -- CreateChannel, DeleteChannel, DescribeChannel, ListChannels, UpdateChannel -- backed by real state. A channel created by CreateChannel is findable by Describe and List, mutable by Update, removed by Delete, and survives a snapshot/restore round trip. MSK is REST-JSON, so each route was matched against the SDK's serializers for method and URI path rather than guessed, and DescribeChannel's response was field-diffed against deserializeDocumentChannelInfo including every nested type. ListChannels returns the distinct, smaller ChannelInfo shape the SDK expects, not the full record. Tag operations now recognise channel ARNs, since CreateChannel accepts tags. glue gains BatchGetDataQualityRulesetEvaluationRun, which reads the existing dataQualityEvalRuns table and splits found from missing the way BatchGetCrawlers already does, plus Get and PutDataCatalogExportConfiguration. Neither export-configuration input carries a CatalogId, so it is modelled as one backend-global singleton following the existing identity-centre config pattern, and it really stores the encryption configuration and timestamps. Three of these operations could not be implemented with real data, and took validation plus an honest empty response rather than invented values. dynamodb SearchVectors: gopherstack models no vector index anywhere -- neither CreateTable nor UpdateTable has any code path that attaches one. The operation validates all four required fields, does a real table lookup, and then returns ResourceNotFoundException for the index using the same message format Query and Scan already use for a missing GSI. That is honest rather than evasive: no vector index can exist in this backend, so "not found" is always true. directconnect ListVirtualInterfaceRoutes: BGPPeer records track configuration only, never a live BGP session's route table. The operation validates the virtual interface exists and returns an empty route list. glue's export configuration reports Status settling synchronously to match ExportSetting, since there is no real S3 Tables pipeline to move through ENABLING or DISABLING, and leaves S3TableBucketArn empty because no input field anywhere in the API supplies it. All three are recorded in their services' PARITY.md gaps, along with kafka's: channel lifecycle operations complete immediately with no CREATING window, CreateChannel does not restrict creation to MSK Express clusters since gopherstack has no cluster-type distinction, and it does not verify TopicArn references resolve. Gates: TestSDKCompleteness passes for all four, go build and go vet clean, golangci-lint 0 issues, all package tests pass under -race. Refs gopherstack-dtay Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ady owns The SDK bump to v1.123.1 exposed an eight-operation TopicV2 family: Create, Delete, Describe, List, Search, Update, plus DescribeTopicPermissions and UpdateTopicPermissions. The design question was whether V2 is a separate resource or a second schema over the existing one. Three pieces of SDK evidence say the latter. CreateTopicInput and CreateTopicV2Input carry an identical "unique per Region per account" doc comment for TopicId with no separate V2 namespace, and both return ResourceExistsException on collision. types.TopicUserExperienceVersion, which exists only on the V1 shape, has the value NEW_READER_EXPERIENCE -- the V1 side already models "this topic uses the V2 schema". And the V2 permissions outputs are byte-identical to V1's with no version discriminator, because permissions belong to the topic, not to a schema version. So all eight operations read and write the same b.topics collection rather than a parallel store. Only CreateTopicV2 and UpdateTopicV2 needed new backend methods, since they genuinely accept different parameters -- no UserExperienceVersion or Permissions, plus CustomInstructions and DataSetRelations, with full-replace update semantics. Describe, Delete, List and Search call the existing V1 backend methods, and both permission operations route to the existing V1 handlers. A dedicated test proves the sharing: a topic created through V1 is visible to DescribeTopicV2, a topic created through V2 is visible to V1's DescribeTopic with UserExperienceVersion NEW_READER_EXPERIENCE, DeleteTopicV2 removes a V1-created topic, and an ID collision across the two families conflicts. Routes were read off the serializers rather than inferred, which caught one trap: SearchTopicsV2 carries MaxResults and NextToken in the JSON body, while ListTopicsV2 takes them as query parameters. One gap is recorded honestly. The two schemas are not losslessly convertible -- V1 has ConfigOptions and rich DatasetMetadata, V2 has DataSetRelations and CustomInstructions -- so each family's exclusive fields are stored separately rather than one clobbering the other, and are not projected into the other family's Describe. There is no SDK evidence for how real AWS projects one into the other, so inventing a mapping would be fabrication. Implementing this also surfaced two pre-existing V1 bugs, left unfixed here and filed separately rather than silently carried forward into V2: V1 SearchTopics reads MaxResults and NextToken from query parameters when the real SDK puts them in the body, and V1 DeleteTopic's response omits the Arn the real DeleteTopicOutput carries. Gates: TestSDKCompleteness passes, go build and go vet clean, golangci-lint 0 issues, package tests pass under -race. Refs gopherstack-dtay Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…licy table entries The last 13 of the 31 operations the SDK bump to v1.319.1 exposed. Transit Gateway policy table entries -- Create, Delete and Modify -- build on the policy table model that already existed, adding a real entry store keyed by policy table and rule number, mirroring the metering policy entry pattern. Create validates that TargetRouteTableId refers to a route table that actually exists, Modify implements AWS's "unspecified fields retain their current value" semantics, and DeleteTransitGatewayPolicyTable now cascades to entries as well as associations. This also fixed a claim that the bump falsified. GetTransitGatewayPolicyTableEntries carried a comment stating "Real AWS exposes no API to create policy table entries directly" and returned an always-empty list. That was true when written and is not true now, so it returns real stored entries. Application Status Checks -- ten operations covering create, delete, modify, associate, disassociate, three describes, and suppression enable/disable. The check is a health-check definition associable with instances or tags and individually suppressible per instance. Real documented defaults are applied on create (path /, interval 60, timeout 6, failure threshold 2, success threshold 5, status code matcher 200, initialization grace period 300, aggregation included) and the real 50-check-per-account quota is enforced. Suppression flips genuinely persisted state that the describes then reflect, rather than being accepted and dropped. DescribeApplicationStatus is the one operation that cannot be honest and complete at once, because nothing here executes real HTTP health checks. It never returns ok, impaired or initializing. It returns only the three ApplicationStatusEnum values that are fully derivable from tracked state: suppressed, not-applicable when no included-aggregation check applies, and insufficient-data when a check is associated but has never run -- each matching that value's documented AWS meaning. A test asserts the fabricated values can never be produced. Reading both deserializers rather than assuming symmetry caught a trap: SuccessfulAssociationResponseObject.AssociationType uses INSTANCE_ID and EC2TAG, while ApplicationStatusCheckAssociationObject.AssociationType uses instance-id and tag. Same concept, two vocabularies, in one family. Gaps recorded in PARITY.md: HealthCheckPaths is not modelled, and AvailabilityZoneId, StatusSince and per-check Details are left empty rather than invented. With this, TestSDKCompleteness passes across all 159 services -- the full forward check is clean and the reverse phantom check still reports only the three known exceptions. Gates: go build and go vet clean, golangci-lint 0 issues, package tests pass under -race. Refs gopherstack-dtay Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The reverse check finds operations gopherstack advertises that the AWS SDK does not have. It has been reporting them through tb.Logf as a staged rollout. The rollout is over: across all 159 services only three still report phantoms, and all three are legitimate. So the check now asserts instead of logging, backed by a documented allowlist holding exactly seven names -- s3's PostObject, PresignedGetObject and PresignedPutObject, which are presigned-URL pseudo-operations rather than SDK methods; iotdataplane's ListConnections, ListThingsWithShadows and RegisterConnection, which are gopherstack admin-only extensions served on /_admin paths; and rds' GetPerformanceInsightsMetrics, deliberately kept because deleting it would remove real capability with no replacement. Each entry carries its justification inline. The allowlist is a package-level map keyed by the SDK client's concrete type rather than a new CheckCompleteness parameter, because the function already derives everything from that client by reflection and a new parameter would have meant touching all 160 call sites. Nothing was added to export_test.go. Verified the assertion can actually fail, since a strict check that never bites is worse than the tb.Logf it replaces: injecting a fake operation into a service's supported-operations list produces "Should be empty, but was [...]", and removing it returns to green. check_test.go's TestCheckCompleteness_ReportsPhantomOpNonFatally asserted the old non-fatal behaviour, so it is renamed and now asserts the spy recorded a failure. rds returns to A. Both reasons for its downgrade are resolved: DescribeCustomDBEngineVersions was removed from the wire surface by the same pass that recorded the downgrade, and GetPerformanceInsightsMetrics is no longer an undisclosed gap now that it is an explicit allowlist entry. Its two pre-existing gaps did not block an A grade before and do not now. The old rationale is kept below as history rather than deleted. The terraform-test target's timeout goes from 10m to 45m; the suite takes about 23 minutes, so the gate was failing spuriously. Closes gopherstack-vhw2, closes gopherstack-zv7f Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…cs they feed cmd/gendocs builds the root README table, every per-service README and the public badges from PARITY.md frontmatter, so stale frontmatter is not a cosmetic problem -- it makes the project misreport itself. networkmanager's manifest still opened "PRE-IMPLEMENTATION AUDIT, NOT YET BUILT -- services/networkmanager/ does not exist yet". That was true when written and was falsified by 87dee6d, which shipped the service: 95 operations, 45 Go files, 9662 non-test lines, 17 cli.go references. Its families were all marked gap and it carried no ops rows at all. Every operation row was derived by reading code, not assumed. For networkmanager the route builders across handler.go and the eleven handler_*.go files were diffed against the SDK's own 95-operation list and matched exactly. 81 operations are ok; 14 are partial, each with a specific reason -- cross-service EC2 and DirectConnect ARNs accepted without a live backend reference to validate against, StartRouteAnalysis returning a deterministic NOT_CONNECTED with no transit gateway graph walk, the core network change set and change events endpoints returning an empty diff because there is no policy-JSON diff engine, routing information and network routes empty because there is no BGP engine, and network telemetry reporting UP only. mgn had the same shape of problem -- body prose describing a finished implementation while families and ops stayed stuck on the pre-implementation gap state. Its 95 operations are now recorded, 83 ok and 12 partial, and the prose claims were re-verified against the code rather than trusted: the S3 wiring really is in cli.go, StartImport really does read S3, and the mapper-segment and network-migration result endpoints really do always return empty. directconnect only needed its leftover "Zero operations implemented" line removed; its 64-operation table was already accurate. No overall grade changed. All three depend on the integration-test question in gopherstack-r9yz, which is what actually gates their grades, and networkmanager deliberately keeps its gap marker until that is settled rather than being quietly promoted here. The regenerated docs move the badges from 5681 to 6076 operations and from 154 to 161 services, and networkmanager, mgn and directconnect get per-service READMEs for the first time -- they had never been generated, because a manifest with zero ops rows produces nothing. Closes gopherstack-3ajx Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… check caught
Flipping the reverse phantom check to a hard assertion immediately caught
something the tb.Logf version had been quietly logging: bedrock advertises
GetAgentMemory and DeleteAgentMemory, which are not methods on the
bedrock-agent control-plane client the check reflects over.
They are real AWS operations, on the bedrock-agent-runtime data-plane
client this repo does not vendor as its own service. Both are genuinely
implemented and wire-shape-routed under
/agents/{id}/agentversions/{v}/memories/..., and the reason was already
documented at services/bedrock/handler_agents_dispatch.go:137 -- the
check simply cannot see the runtime client. So they belong in the
allowlist, alongside the rds entry that exists for the same reason.
Worth recording why this was missed the first time. The verification
sweep ran `go test -run TestSDKCompleteness ./services/...`, and 157 of
the 158 sdkcheck call sites use exactly that name. bedrock's is
TestAgentsHandler_SDKCompleteness, so the -run filter skipped it, and the
sweep reported clean while a service was broken. The full `make test` run
is what caught it. A name-filtered sweep is only as complete as the naming
convention it assumes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review skippedToo many files! This PR contains 920 files, which is 820 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 (920)
You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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: Fri, 07 Aug 2026 21:07:28 GMT |
…nistic Comments on this branch were running ~12.5% of added lines, with quicksight/topics_v2.go and pkgs/sdkcheck/check.go around 50%. Per the rule now in CLAUDE.md, comments should be short and pointed or absent -- Go reads fine on its own, and walls of prose cost more context than they explain. Removed: file-level essays restating the package summary, section banners, multi-paragraph quotes of AWS docs, narrated history of what past passes changed, and restatements of the following line. Kept, compressed to a line or two: the reason a decision was made, the landmines, and verified external facts with their source. Specifically surviving are the dynamodbSnapshotVersion warning, every phantomAllowlist justification, the wire-shape traps (SearchTopicsV2 carrying pagination in the body while ListTopicsV2 uses query params; the two different AssociationType vocabularies in one EC2 family), and the no-fabrication reasoning behind DescribeApplicationStatus, SearchVectors and ListVirtualInterfaceRoutes. Godoc on exported identifiers stays. Net: 425 comment lines deleted, no behaviour changed. Separately, services/eks is the first package in this repo to use testing/synctest. Its five sleeps now run inside a bubble against a fake clock, so the async cluster, nodegroup, addon and fargate transitions are deterministic instead of racing a 50ms wall-clock margin -- the shape that produced "status = CREATING, want ACTIVE" under parallel load. The package also got faster, 1.64s to 1.21s, since the real sleeping is gone. Honest note on that: the agent doing the conversion could not actually reproduce the flake, having tried -count=20, -cpu=1, eight concurrent runs, and GOMAXPROCS=1 under sixteen CPU-stress processes. So the fix is justified by the fragile construction and by determinism, not by an observed failure this session. One subtlety worth recording. The sleeps were kept inside the bubbles rather than replaced with synctest.Wait(). Wait() blocks until existing goroutines are durably blocked; it does not advance the fake clock to fire a timer that is not yet due, which is what these tests are actually waiting on. Sleeping past the deadline is the idiom the Go docs use for this. The margin is also deliberately kept strictly greater than the production delay -- an exactly-equal sleep ties at the same fake instant with no defined ordering, which would trade a load-dependent race for a deterministic one. Inside a bubble that margin costs nothing. Refs gopherstack-5biv Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mulint detects mutex self-deadlocks -- recursive locks, missing unlocks,
deferred re-locks. It was initially wired in as a golangci-lint module
plugin, which had to be undone for two reasons.
First, it broke CI. Enabling a module plugin in .golangci.yml makes stock
golangci-lint hard-fail with 'plugin(mulint): plugin "mulint" not found',
and the lint workflow installs a stock binary. Making that work needs a
custom-gcl build in CI, which is workflow machinery we do not want.
Second, and more decisive, the plugin would have guarded almost nothing.
mulint only follows a mutex wrapper when the wrapper type is declared in
the same package. Probing all three shapes: wrapper in the same package
held by value is detected, same package held by pointer is detected,
wrapper in a different package held by pointer is not detected at all.
lockmetrics.RWMutex lives in pkgs/lockmetrics and is used across package
boundaries in 190 of roughly 260 mutex declarations, spanning all 192
service files. So the repo-wide "0 findings" was largely a false clean
rather than a clean codebase.
It is still worth having for the ~70 direct sync.Mutex and sync.RWMutex
declarations, and for new code that reaches for sync directly, so it now
runs in the lint target as a vet tool:
go vet -vettool=$(go tool -n mulint-vet) ./...
Pinned in go.mod's tool block at v1.1.0 alongside govulncheck and
gotestsum, so there is no separate install step and no workflow change.
Both behaviours were demonstrated before landing this. A recursive
sync.Mutex lock in the same package is reported; the identical bug written
against lockmetrics.RWMutex is silently missed. AGENTS.md states that
limit plainly rather than implying coverage the tool does not have.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts: # .beads/issues.jsonl # services/dynamodb/persistence.go
… iot and s3control Two independent sweeps. testing/synctest now covers transfer, sqs, grafana, lambda and pkgs/worker, following the pattern established in services/eks. 50 sleeps moved into bubbles, where the clock is fake and a wait costs no wall-clock time. The sleeps that remain inside those bubbles are not a leftover: sleeping past a timer deadline is the correct idiom, since synctest.Wait only waits for existing goroutines to block and does not advance the clock to fire a timer that is not yet due. Each is kept strictly longer than the delay it waits on, because an exactly-equal sleep ties at the same fake instant with no defined ordering. Three sleeps in services/lambda are deliberately left alone and documented in place: handler_runtime_test.go drives a real loopback HTTP server and a Docker-mock runtime API, and real network I/O is not durably blocking, so a bubble would hang rather than help. That is the boundary for the rest of this sweep too -- test/integration, test/e2e and test/terraform cannot use synctest at all and want require.Eventually instead. All five packages pass -race -count=10. Separately, iot and s3control were the two worst services for oversized comment blocks (59 and 54 blocks of 8+ lines). iot drops 382 comment lines, s3control 304. Removed: narrated history including bd issue numbers, section banners, verbatim AWS doc quotes, and prose restating what the code says. Kept and compressed: AWS wire-shape facts with their SDK source, the no-fabrication notes, landmines, and godoc. The blocks that survive are dense factual content already down to 8-14 lines. Verified comments-only: no identifier, control-flow, or behaviour change leaked into that half of the diff. Refs gopherstack-5biv Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ng guardduty and wafv2 to A A- was rejected as a ceiling for these two, and the schema had no way to express what was actually true about them: not "incomplete", but "correct, and this data cannot exist here". The inconsistency is measurable. 80 of the 151 services already graded A carry non-empty gaps, so gaps have never blocked an A in this repo. guardduty and wafv2 were held lower precisely because their limitation was structural and honestly documented -- a stricter standard than 80 of their peers were held to. So _PARITY_TEMPLATE.md gains a structural_gaps key. A structural gap is one no implementation could satisfy in an emulator because the underlying data source cannot exist: no real traffic, no ML or AI engine, no billing or settlement system, no physical hardware. Those do not block an A, but must be recorded separately rather than buried in gaps. Explicitly not an escape hatch -- anything that could be built with more effort stays in gaps. That line was drawn per gap, not per service, and most entries did not move. guardduty keeps in gaps its missing per-feature member-account enrollment tracking and its lack of a state model for individually scanned files: both are absent state models that could be built. wafv2 keeps its undocumented ApplicationIntegrationURL scheme and its vendor-onboarding-only ManagedRuleSet fields for the same reason. One entry moved in each service -- guardduty's Investigation status, which needs account-level finding correlation and Bedrock-backed analysis, and wafv2's four revenue-reporting operations, which need real HTTP traffic, bot detection and a settlement system. Both already validate requests to AWS's own rules and return honestly empty responses. Nothing was fabricated to reach this grade, and nothing about their behaviour changed. gendocs parses the new key and renders it as its own labelled section in each service README plus a count in the root table, so an A grade always shows what cannot be emulated instead of hiding it. Adding the parser case pushed parseFrontmatter over cyclop's branch cap, so scalar-key handling was extracted rather than suppressed with a nolint. Badges move from 151 A / 3 A- / 4 B to 153 A / 1 A- / 4 B. The six services still below A -- mgn, directconnect, grafana, outposts, resiliencehub and networkmanager -- are blocked on integration-test coverage, not grading policy. See gopherstack-r9yz. Closes gopherstack-4h6q Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
The last four pages -- ecs, elasticache, elbv2 and cognitoidp -- complete the rollout. Region All now covers 34 pages with fan-out and 40 with region chips. elbv2 fans out all four of its top-level lists independently, and every drill-down and mutation threads the owning row's region. CreateListener in particular resolves the target load balancer's region rather than the write default, since a listener attaches to one specific balancer. cognitoidp fans out only the User Pools list, and every pool-scoped tab now targets the selected pool's own region rather than the picker's. That distinction matters here because pool IDs are region-prefixed by construction, so a pool chosen from a fanned list can belong to any region. ecs and elasticache fan out their Clusters tab, with nested services, tasks, container instances and nodes threading the selected cluster's region. Their sibling tabs -- task definitions, capacity providers, account settings, parameter and subnet groups, snapshots, users -- are independent account-and-region resources rather than children of a cluster, so they stay on the active region rather than being fanned for the sake of symmetry. Also corrects a pre-existing type error found on the way: elbv2's trust store revocation used a LastUpdatedAt field the real SDK does not have. Gates: svelte-check 0 errors across 19955 files, oxlint clean, formatting clean, 2034 tests across 174 files, production build succeeds. Closes gopherstack-hrrz, closes gopherstack-b1m8, closes gopherstack-ks2s.20 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…orked at all Two operations in codeartifact could never have succeeded for any real client, and had survived three prior audit passes. CreatePackageGroup read its request body from the JSON key "pattern"; the real wire key is "packageGroup", so every SDK call failed. And PublishPackageVersion was routed at /v1/package/versions/publish, while the real path is singular -- so every real client got a 404, which means the features previously "fixed" on that operation had been unreachable the whole time. Both were found only by driving the service through a real SDK client, which it had never had. About forty unit-test call sites had been asserting the wrong wire shape and are corrected. codecommit's GetMergeConflicts hardcoded mergeable to false, so every client was told a perfectly mergeable pair of branches was blocked -- inverted, not merely absent. MergeBranchesBySquash and MergeBranchesByThreeWay both silently ran the fast-forward path, so the three merge strategies were one strategy wearing three names; squash now produces a one-parent commit and three-way a two-parent one, and both honour TargetBranch, CommitMessage and author fields that were previously accepted and dropped. PutFile and CreateCommit now actually return SameFileContentException, which was wired but unreachable. codeartifact also gains real weak-match package-group association -- casefold plus dash, dot and underscore normalization -- where associationType had been hardcoded to STRONG. ssoadmin gains the ProvisioningStatus filter, backed by a real ModifiedDate bumped on every content change and a provisioned-at stamp, rather than being accepted and ignored. codestarconnections needed no code. Its sync-revision SHAs moved from gaps to structural_gaps: the service holds no representation of repository content anywhere and no routed operation triggers a real sync, so there is nothing a SHA could honestly be derived from -- unlike codecommit, where gopherstack owns the commit graph. One correction to the pass: it bumped ssoadminSnapshotVersion from 2 to 3 for a purely additive field. Restore discards on version mismatch via ResetAll, so that would have destroyed every user's persisted ssoadmin state on upgrade. Reverted. This is the third time today the same reflex has appeared in a different service, so it is now filed as a structural problem rather than fixed in place again. Gates: build and vet clean, all four services pass under -race, golangci-lint 0 issues, and the Docker-backed integration suite passes. Closes gopherstack-3bsb, closes gopherstack-u9e5, closes gopherstack-7mmd, closes gopherstack-dbwi Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
No description provided.