Queue: snapshot data-loss revert, three accepted-then-ignored params, and a diff-scoped lint gate - #2417
Queue: snapshot data-loss revert, three accepted-then-ignored params, and a diff-scoped lint gate#2417agbishop wants to merge 76 commits into
Conversation
…y persisted snapshot apigatewaySnapshotVersion went 1 -> 2 in d39bf33 alongside a purely additive `Tags *tags.Tags json:"tags,omitempty"` on the nested stageSnapshot. An older snapshot still decodes as the current shape with Tags zero-valued, so the bump bought nothing — but Restore discards on any version mismatch, resetting the registry and all nine dirty tables. Every instance with a persisted apigateway snapshot would lose its state on the first start after that commit. TestSnapshotVersionGuard did not catch it. The guard compared versions only inside branches keyed on the field list changing, so a version-only drift fell through silently — and the drift was real: the source said 2 while the golden still said 1. Split the comparison into a pure diffSnapshots function and give it a default branch, so "version bumped, fields unchanged" is a violation that must be confirmed rather than absorbed by the next -update run. The two apigateway restore fixtures pinned "version":2 literally; they now pin 1 and once again exercise the real restore path instead of the discard path. Closes gopherstack-qviw Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ly launching fewer InMemoryBackend.RunInstances clamped count to 1000 and carried on, so a direct backend caller — services/cloudformation/resources_ec2.go and tests, which do not pass through the handler's rejection — asked for more instances than it got and was told the call succeeded. That is the "parameter accepted then quietly ignored" class. It now returns an error, matching what an HTTP caller already saw. The pre-existing count < 1 -> 1 default stays: absent MinCount really does default to 1. The bound was also reported under the wrong error. It is gopherstack's own allocation-safety cap for CodeQL go/uncontrolled-allocation-size (alert #253), not an AWS quota — real EC2 has no flat per-request instance limit. Returning InvalidParameterValue framed it as a malformed request. AWS documents ResourceCountExceeded for exactly this situation: "You have exceeded the number of resources allowed for this request; for example, if you try to launch more instances than AWS allows in a single request. This limit is separate from your individual resource limit." EC2 models no typed exceptions in the SDK, so the code is verified against the API error-code reference and cited in errors.go, following the ErrOutpostArnNotFound precedent. Renamed the constant to maxInstancesPerRunInstancesRequest so it stops reading as an AWS quota. The outpost path still reserves the full constant rather than the requested count. A guard-then-use of count was empirically not recognised by CodeQL in this codebase (gopherstack-17sl), and reopening the alert is worse than a fixed ~16KB reservation, so count is kept out of the make() size argument entirely. Refs gopherstack-x6r7 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…going unlinted Every per-change gate in this repo has been scoped to a fixed directory — agents run "golangci-lint run ./services/<svc>/...", the orchestrator ran the same, and "go vet ." only covers the root. Nothing in that set covers test/, so a govet shadow in test/integration/datasync_test.go reached a commit and was only caught by CI's repo-wide run at merge time. scripts/lint-changed.sh resolves the actual diff to package directories and lints exactly those: the working tree (staged, unstaged and untracked) unioned with commits on this branch since it diverged from origin/main. Either half alone misses a real case — verifying before committing needs the working-tree diff, verifying at commit time needs the branch diff. It prints the package list it checked and names anything it skipped. Silent truncation is the exact failure this gate exists to prevent, so a large diff is batched rather than dropped, and every batch folds into the exit status. Closes gopherstack-a8b5 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
updateLocationNfsInput did not declare ServerHostname at all, so a client changing an NFS location's hostname was told the update succeeded while LocationUri kept pointing at the old server. UpdateLocationNfsInput models the member (aws-sdk-go-v2/service/datasync@v1.61.4 api_op_UpdateLocationNfs.go:48). The URI is now rebuilt in the same shape CreateLocationNfs produces (locations_nfs.go:30, nfs://host/subdir with the leading slash trimmed), using the stored subdirectory when the hostname changes alone — so a hostname-only update cannot blank the path. Refs gopherstack-pz2v Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…that does not exist CreateJob checked only for an empty name and a duplicate, then stored whatever DatasetName, ProjectName and RecipeReference it was given — so a job could be created pointing at nothing and the call reported success. CreateProfileJob and CreateRecipeJob both document ResourceNotFoundException (aws-sdk-go-v2/service/databrew@v1.42.4 deserializers.go:465 and :960). Each reference is checked only when non-empty, because CreateRecipeJobInput accepts ProjectName as an alternative to DatasetName plus RecipeReference, so an unset reference is legal. CreateProject is deliberately untouched: its error switch (deserializers.go:626-638) has no ResourceNotFoundException case, so its unvalidated behaviour is correct. Validation runs before anything is written, so a rejected call leaves no job behind. 29 existing tests created jobs against never-created datasets, recipes and projects — behaviour the real service rejects. They now create the referenced resource first and exercise the valid path rather than asserting the gap. Closes gopherstack-gvdm Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e against IDs that do not exist Both operations accepted a reference to a resource that was never created and reported success, leaving a bundle or image pointing at nothing. Both document ResourceNotFoundException (aws-sdk-go-v2/service/workspaces@v1.73.1, awsAwsjson11_deserializeOpErrorCreateWorkspaceBundle and ...CreateWorkspaceImage), and the validator pattern and error values were already established in this service by d0b7241. CreateWorkspaceImage was worse than unvalidated: it took workspaceId as `_ /*workspaceId*/` and discarded it outright, though the handler had been threading it through all along. The parameter is now named and checked. CreateWorkspaceImageOutput and the WorkspaceImage type carry no source-workspace field, so an existence check is the whole correct scope — there is nothing to derive from the workspace. Both checks run before nextID, so a rejected call consumes no identifier and writes nothing. The tests prove that directly rather than by inspection: they create a resource, attempt a rejected create, create a second resource, and assert the second ID's counter is exactly one past the first. Nine existing tests created bundles and images against IDs like wsi-00000001 that were never created. They now create the referenced resource first. Closes gopherstack-e5pd Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ually does The guardduty pass (ca27323) changed several operations' status but left PARITY.md untouched, so the audit record understated the service. Each claim was re-verified against current code before being written down, not copied from the commit message: the malware-scan filters are genuinely applied (malware_scan_filter.go:37, called from both DescribeMalwareScans and ListMalwareScans), ListMembers genuinely filters on onlyAssociated (members.go:172), and all eight member operations genuinely check the detector. GetRemainingFreeTrialDays stays graded partial rather than ok. It now computes a real value under the shape the SDK models — AccountFreeTrialInfo has no top-level freeTrialDaysRemaining, only features[].freeTrialDaysRemaining (types.go:1817) — but features[] can only ever report the three always-on base sources, because no per-member feature-enablement state exists to read. Three implemented operations had no ops-table row at all (ListMalwareScans, GetMemberDetectors, UpdateMemberDetectors); that is the +3 in the operations badge, not new work. The pagination gap is now stated precisely, naming the ten plain-GET List operations that accept MaxResults/NextToken and emit neither. ListCoverage's filter is recorded as a gap and deliberately not implemented: nothing holds coverage-resource state, so a filter over a permanently-empty list would read as working while doing nothing. Regenerates the READMEs for this and the PARITY.md edits in the preceding commits. Closes gopherstack-8up3 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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! |
…pi and ReimportApi basepath=prepend was implemented in d39bf33 but nothing asserted what it does to the resulting route keys, so the behaviour could regress silently — and its absence from the tests is why a later review misread the mode as accepted-then- ignored. Covers ignore, prepend, split and the empty default against a spec declaring a /v1 base path and a spec declaring none, for both operations, asserting the resulting route key rather than the status code. split is asserted to behave as ignore, which is its documented state: the SDK models only the enum values and defers the semantics to prose, so implementing it would mean guessing at client-observable routing. Refs gopherstack-jni0 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… dropping ServerHostname The two siblings of the NFS fix in 6098648. Neither update-input struct declared ServerHostname, so a hostname change reported success while LocationUri kept pointing at the old server. Both members exist in the SDK (aws-sdk-go-v2/service/datasync@v1.61.4 api_op_UpdateLocationSmb.go:117 and api_op_UpdateLocationObjectStorage.go:100); AWS shipped the capability on all three location types at once (CHANGELOG.md:268), NFS was just filed first. Each URI is rebuilt in the shape its own Create produces, which differ: smb://host/subdir (locations_smb.go:32) against object-storage://host/bucket/subdir (locations_objectstorage.go:31). Bucket is preserved from stored state rather than re-derived, since UpdateLocationObjectStorageInput has no BucketName member. A hostname-only update leaves subdirectory and bucket intact. PARITY.md recorded both operations as "wire: fixed ... FIXED this sweep" while this member was missing — a doc asserting a parity that did not hold. Both rows now say what is actually true. UpdateLocationObjectStorage crossed cyclop's limit at 16 once the hostname branch was added; split into updateObjectStorageFields and updateObjectStorageSecretConfig rather than annotated. Closes gopherstack-2xhy Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
📊 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: Tue, 11 Aug 2026 21:26:21 GMT |
…Image against images that do not exist The siblings left out of 973aa01. Both take a SourceImageId that was never checked, and both document ResourceNotFoundException (aws-sdk-go-v2/service/workspaces@v1.73.1 deserializers.go:772 and :1636). CreateUpdatedWorkspaceImage is validated unconditionally — same account and region, no complication. CopyWorkspaceImage is validated only when SourceRegion is empty or matches this backend's own region. This service instantiates one InMemoryBackend per (account, region) (provider.go:26-28), b.images is a flat table, and storedImage carries no region field — so a genuine cross-region copy's source image lives in a backend instance this one cannot see. Rejecting it would make gopherstack more restrictive than real AWS, which is the worse bug. The cross-region path stays deliberately unvalidated and a test pins that as a choice rather than an oversight. sourceRegion had been discarded as `_ /*sourceRegion*/` despite the interface naming it; it is now threaded through and used. Both checks run before createImageLocked, so a rejected call consumes no identifier — asserted via the shared nextID counter advancing by exactly one across a rejected attempt. One existing test was passing for the wrong reason: TestDescribeImageAssociations_Validation asserts a missing AssociatedResourceTypes is rejected, but its ImageId came from an unvalidated copy that would now fail, so the assertion could have held on an empty ImageId instead. It creates a real source image first. Closes gopherstack-plmb Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ot a bare identifier
entryLineRe required `[A-Za-z0-9_]+` for the key, but real family keys name
several operations at once or carry a parenthetical — AddPermission/RemovePermission,
Database/TableMetadata (Get/List), Create/UpdateConfigurationTemplate response
shape. Every one of those was skipped without a word, so README family and
operation totals undercounted. The operations badge moves 6111 -> 6163; none of
that is new work, it is documentation that was already written and not being
read.
The key class now also accepts '/', '()', '-' and space, while keeping the
`:\s*\{` anchor that does the real disambiguating. Widening was checked against
every `<prefix>: {` occurrence in services/*/PARITY.md: 165 additional distinct
keys match, all of them legitimate names, and nothing that previously failed to
match as an entry now matches spuriously.
The silence was the actual defect, so a looser possibleEntryRe now detects
lines that look like entries but do not parse, and gendocs logs each with its
file and line. Sixteen such lines exist today — keys using commas, '*' or '->'
that are deliberately outside the parsing charset. They were invisible before
and are now reported on every run.
Warnings are non-fatal on purpose. ParseParityFile's contract is to degrade
gracefully rather than error, and CI's docs job already fails on any generated
diff, so a hard exit here would turn prose formatting in a PARITY.md note into
a blocking gate.
Closes gopherstack-udc7
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
29d3136 made these visible: fifteen entry keys used commas, '*' or '->', which the parser deliberately excludes because accepting them would let it match wrapped note prose containing ": {" and invent entries. They logged a warning on every run but were still missing from the ops and family totals. Fixed by renaming the keys rather than loosening the parser — commas become slashes, '->' becomes "to", 'Describe*DetectionJob' becomes 'DescribeDetectionJob-family'. Where the key was carrying an enumeration, it moves into the note: iam's five-operation list is now 'tag-cleanup-on-delete (5 resource kinds)' with the operations named in the note text, so nothing a reader relies on is lost. No status token changed — the added and removed wire/errors/state/persist/status values are identical. This is a naming change only. Fourteen of the sixteen warnings are gone. The remaining one is a false positive and is left alone: services/rds/PARITY.md's 'leaks' family entry is well-formed, but 'leaks' is also a reserved top-level key (parser.go:57), so matchEntry rejects it and warnUnparsedEntry reports it. Filed separately. Closes gopherstack-42va Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… was run The 2026-07-25 audit diffed against v1.51.11 while go.mod pins v1.56.4, so "every wired field diffed" was true of the wrong SDK. Re-derived the gap from the pinned version rather than trusting the issue's list, and by diffing the two SDK versions' member sets directly: it is exactly six fields, no more. Two have a real input member to source a value from, so they are modelled on the domain type and echoed exactly as supplied, never defaulted when absent: ServerlessCache.NetworkType (CreateServerlessCacheInput.NetworkType, serializers.go:6709 — create-only, no Modify member) and ReplicationGroup.Durability (Create serializers.go:6506, Modify :8171). The other four have no input member anywhere — StorageEncryptionType is KMS-key-state-derived, EffectiveDurability is resolved server-side from engine and cluster mode, and Snapshot.Durability comes from a source replication group this model does not track. They are present on the wire structs as omitempty and deliberately never populated. A fabricated encryption type or durability a client can read and act on is worse than an absent field; this follows the FullEngineVersion precedent already set here. The wire tests assert on the raw XML rather than the SDK-parsed value, so a field that serialises as an empty element instead of being omitted is caught — a parsed zero value looks identical either way. elasticacheSnapshotVersion stays at 1. Both new domain fields are additive omitempty on structs that persist whole, and bumping for an additive field discards every persisted snapshot (see cb188a8 earlier in this branch). Closes gopherstack-31dm Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ticache fields Operations badge 6163 -> 6169: fourteen family entries that the parser was skipping on a key-charset technicality now count, plus the elasticache additions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…guration The audit that claimed CreateScheduledQuery and GetScheduledQuery modelled the full DestinationConfiguration was run against v1.80.0 while go.mod pins v1.81.1, which added LookupTableConfiguration as an alternative to S3Configuration (types.go:778, type at :1561). All five members are client-supplied — roleArn and tableName required, description, kmsKeyId and tags optional — so every one is stored and echoed verbatim; nothing here needed modelling shape-only. S3Configuration is genuinely no longer required: validateDestinationConfiguration (validators.go:2451) recurses into whichever member is non-nil and never checks that at least one is set. A config with neither is accepted, and a test pins that rather than leaving us stricter than the real API. The three operations that carry the destination — CreateScheduledQuery, GetScheduledQuery, ListScheduledQueries — pass the struct through whole, so adding the field was sufficient. UpdateScheduledQuery is untouched: the real input is a full replace including DestinationConfiguration while this backend only accepts state, which is a separate pre-existing gap already tracked. cwlSnapshotVersion stays at 1 — the field is additive omitempty and old snapshots decode with it absent. Closes gopherstack-09o8 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…er the audit Both audits ran against a stale sdk_module pin, so "every wired field diffed" was true of the wrong SDK. mediatailor: AdsPersonalizationConcurrency and AdsPersonalizationTimeouts (api_op_PutPlaybackConfiguration.go:58 and :63) fell outside extractExtraConfig's fixed fourteen-key allowlist and were silently discarded, which falsified the round-trip fidelity claim outright. Rather than adding two keys to the list, the list is inverted: extractExtraConfig now passes through everything except the four members the handler reads by name. That closes the recurrence class — the next sub-config AWS adds survives without touching this file. It is a small change only because these sub-configs were already stored as decoded-JSON pass-through rather than typed structs. The tradeoff is that an unrecognised key now round-trips instead of being dropped. Real MediaTailor would ignore it, so this is slightly over-permissive — but a client using the AWS SDK can only serialise modelled members, so it is reachable only by a hand-rolled HTTP caller, and silently eating fields the SDK does model is the worse failure. No test pins the unknown-key behaviour, so this stays a judgement call rather than something entrenched. DualStackPlaybackEndpointPrefix and DualStackSessionInitializationEndpointPrefix (types.go:1049,1053) are response-only with no input member. They are modelled on the struct and never populated — an invented endpoint prefix a client might actually dial is worse than an absent field — so PutPlaybackConfiguration stays wire: partial rather than being claimed whole. mediaconvert: MaximumConcurrentFeeds (api_op_CreateQueue.go:47) is threaded through Create and Update. No equivalent mechanism fix applies there — createQueueInput and updateQueueInput are hand-modelled typed structs, so every accepted field must be declared and there is no allowlist to invert. Neither snapshot version constant is bumped; both stay at 1. Refs gopherstack-gt9o Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…aconvert parity updates Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…eserved word services/rds/PARITY.md has both a genuine top-level `leaks:` section at column 0 and an indented `leaks:` family entry. matchEntry rejected any line whose key was reserved regardless of indent, while isBlockTerminator only accepts a match at column 0 — so the indented entry fell through both, counted as neither, and was dropped from the families total. Since 29d3136 it also produced a warning on every run, about a line that is not malformed. matchEntry now rejects a line only when isBlockTerminator would claim it. That ties the two functions together by construction, so no line can fall through both, and it generalises: the same collision was waiting for any service naming a family `gaps`, `protocol` or `gaps`-adjacent. Indentation is the only workable discriminator here. The obvious alternative — that a section header carries no brace on its own line — is false: rds's real `leaks:` header is written `leaks: {status: ..., note: "..."}`, brace-identical to a family entry. A 0-space entry whose key is reserved is still read as that key's section header. At column 0 the two forms are genuinely indistinguishable, and parseFrontmatter re-reads the line as the scalar field, so the content becomes LeaksStatus rather than being lost. The existing tolerance for 0-space entries with non-reserved keys (services/mwaa, services/rekognition) is unaffected — isReservedKey never applied to those. Families across all 159 PARITY.md files go 1016 -> 1017, and the false warning count goes 1 -> 0. Closes gopherstack-jw5s Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…difyClientProperties wiping the others Continues the stale-pin sweep. Both services were audited against an older SDK than go.mod pins — the cache still holds ssoadmin@v1.38.0 and workspaces@v1.68.3 alongside the pinned v1.43.1 and v1.73.1, and the fields in question do not exist in the older ones. The workspaces half turned up a bug the issue did not mention: ModifyClientProperties replaced the whole stored struct on every call, so setting one property silently cleared every other. The real operation is a partial update. It now merges, leaving an omitted field at its previous value. ClientExperiencePolicy (types.go:269) and LogUploadEnabled (:275) are both threaded; the latter was unwired too. ClientExperiencePolicy is deliberately unvalidated: unlike its neighbours LogUploadEnabled and ReconnectEnabled, which have generated enum types with Values(), it is a bare *string with no @enum trait. The FORCE_CLASSIC/FORCE_UI_2026/USER_CHOICE values in its doc comment are illustrative, so rejecting anything else would be stricter than AWS. ssoadmin: PermissionSetsEnabled (api_op_DescribeInstance.go:77) is stored as a *bool, so an instance that never set it stays nil and is omitted rather than reported as a fabricated false. AWS documents that it cannot be disabled once enabled, but that is prose rather than an SDK-pinned constraint, so both values are accepted verbatim. InstanceMetadata.Regions is populated from real AddRegion state via ListRegions. PrimaryRegion is modelled shape-only and never set: nothing in this backend can source it, since RegionMetadata.IsPrimaryRegion is always false here. Neither snapshot version constant is touched — workspaces stays 1, ssoadmin stays 2. workspaces' clientProperties map is pre-existing ephemeral state that was never in backendSnapshot, so the new fields inherit that gap rather than creating one. A round-trip test was written, confirmed to fail against that pre-existing non-persistence, and reverted rather than expanding scope; recorded in PARITY.md instead. Refs gopherstack-gt9o Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…oadmin/workspaces fields rds picks up its 'leaks' family row, which the parser had been dropping on a reserved-word collision. Operations badge 6169 -> 6172. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both fields arrived in the SDK after this service was audited (types.go:52 and
:550 at the pinned v1.53.5) and were silently omitted from every response.
Unlike most of this sweep these are not caller-supplied — they are derived from
the org tree gopherstack already models, so leaving them unset would have been
the wrong answer. Getting the format wrong would be worse than omitting them
though, and the Go doc comments pin nothing ("The paths in the organization
where the account exists"), so the format comes from the AWS API Reference
example responses and the published regex, cited in buildPath's comment:
o-<org>/r-<root>/(ou-<id>/)*<ownID>/ — org, root, ancestor OUs top-down, the
resource's own id, trailing slash.
Paths is plural but Organizations is a strict single-parent tree — moving an
account between roots is an error, MoveAccount takes one source and one
destination, and this backend stores a single accountParent. It therefore
always returns exactly one path and never fabricates a second.
Populated on the seven operations that actually return these types, found by
searching for the types rather than trusting the gap note: DescribeAccount,
ListAccounts, ListAccountsForParent, DescribeOrganizationalUnit,
UpdateOrganizationalUnit, ListOrganizationalUnitsForParent and
CreateOrganizationalUnit. ListChildren and ListParents are excluded because
they return summary types that carry no path in real AWS.
The ancestor walk is bounded, so a cyclic or dangling parent chain cannot spin:
it returns no path at all rather than a partial or invented one. That state is
unreachable through the API and only constructible via a corrupted snapshot,
which is how the test builds it.
Nothing new is persisted. Both fields are json:"-" and computed at read time
from state that was already stored, so organizationsSnapshotVersion stays at 1.
Refs gopherstack-gt9o
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
NetworkType arrived after this service was audited and was dropped end to end — absent from the inputs, never echoed, error not in the lookup table. DBCluster.NetworkType (types.go:236) is settable on CreateDBCluster (api_op_CreateDBCluster.go:171) and ModifyDBCluster (:136), so it is accepted, stored and echoed. It defaults to IPV4 because the SDK documents that as the default in as many words — "IPV4 – ( the default )" — not because a default seemed reasonable. DBInstance.NetworkType (types.go:764) has no input member on either CreateDBInstance or ModifyDBInstance; the SDK says it is inherited from the DB cluster, so that is where this takes it from rather than inventing an option the API does not offer. NetworkType is a bare *string with no entry in types/enums.go, so any value is accepted. Restricting it to IPV4/DUAL would be stricter than the real API. Two things are deliberately left inert, and both would have been easy to fake: SupportedNetworkTypes on DBSubnetGroup (types.go:945) and OrderableDBInstanceOption (types.go:1291) is modelled on the wire in its real member-wrapped list shape but never populated. Subnets here are opaque ID strings with no CIDR data, and the orderable-options catalog is static, so there is no honest basis to say which network types are supported. A fabricated capability list is worse than an absent one, and a test asserts it is genuinely absent from the XML rather than present and empty. NetworkTypeNotSupportedFault (errors.go:1417) is not added to the error lookup table. Real Neptune raises it when a requested network type conflicts with the subnet group's actual CIDR support — a condition this backend cannot detect. Inventing a rejection so the error had something to raise would be the more-restrictive-than-AWS bug class. neptuneSnapshotVersion stays at 1; the new fields are additive omitempty. Refs gopherstack-gt9o Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ates Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…berately never populated The field arrived after this service was audited (types.go:803, :969, :6079 at the pinned v1.73.4) and was missing from GetAutomationExecution, DescribeAutomationExecutions and DescribeAutomationStepExecutions. It is modelled and left permanently unset, which is the honest outcome rather than a shortcut. Real SSM sets it when its engine detects a non-critical issue mid-run; StepExecution's doc adds "Present only if the step status includes a warning". There is no such status in the enum, so it is engine-detected, not a modelled transition. This backend has nothing to detect: completeAutomationLocked drives every step to Success unconditionally, and automationStatusFailed is declared in store.go but never assigned anywhere — there is no failure, timeout, retry or degraded path to report a warning from. Inventing a warning string would put text in front of an operator that no real condition produced. Same call as apigatewayv2's failOnWarnings on this branch, which is validated but documented as inert because the emulator generates no import warnings. The test asserts the field is genuinely absent from the raw response body, not merely empty when parsed — those are indistinguishable through the SDK, and omitempty is the only thing separating them. ssmSnapshotVersion stays at 1. Refs gopherstack-gt9o Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…PC config Both fields arrived after this service was audited and were read nowhere. Connector.IpAddressType (types.go:720) is set by CreateConnector (api_op_CreateConnector.go:86) and UpdateConnector (:80), and echoed on DescribeConnector. WebAppVpcConfig (:2745) and UpdateWebAppVpcConfig (:2648) carry their own, set through Create/UpdateWebApp's EndpointDetails. Two absences here are real AWS behaviour and are deliberately preserved, with tests pinning them so a later pass does not "fix" them into existence: DescribedWebAppVpcConfig (types.go:1417) has no IpAddressType and no deserializer case for one, so a client sets it and cannot read it back. The describe output is untouched. This is the same asymmetry PARITY.md already records for SecurityGroupIds. ListedConnector (types.go:1897) carries only Arn, ConnectorId and Url, so ListConnectors keeps omitting the field. Neither enum is validated. Both are IPV4/DUALSTACK, but the sibling Server.IPAddressType — the same enum shape — is threaded through servers.go with no validation, while EndpointType, Domain and TLSSessionResumptionMode in that same file do validate. Following the established local precedent for this exact shape rather than inventing strictness AWS may not have. The web-app value is stored despite never being echoed: it round-trips through Snapshot/Restore and is readable from the backend struct, matching how SecurityGroupIDs is already handled here. transferSnapshotVersion stays at 1. Refs gopherstack-gt9o 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>
…e-struct blind spot
…y send Query protocol resolves parameters by exact-string map lookup, so each of these silently yielded empty and still returned 200. docdb and neptune RestoreDBClusterFromSnapshot both read DBClusterSnapshotIdentifier; the required key is SnapshotIdentifier. DBClusterSnapshotIdentifier is correct on CreateDBClusterSnapshot and DescribeDBClusterSnapshots, which is likely how it leaked here. elbv2 ModifyTrustStore read a Name parameter that does not exist on ModifyTrustStoreInput and implemented a rename AWS does not offer. Removed; the op is now a validating lookup. The two required S3 bundle fields stay unwired because TrustStore has nowhere to put them and CreateTrustStore does not set them either - fixing one side only would be worse. PARITY.md:72 drops from 'wire: ok' to 'wire: partial'. ses SetReceiptRulePosition invented a numeric Position. The real field is After, naming the rule to sit behind; absent means move to first. The old test passed vacuously - it already sent After, which the handler ignored, and only asserted HTTP 200. Every fix was checked by reverting it and confirming the new test fails. Closes gopherstack-einq
…gaps gopherstack implements 55 Redshift Serverless operations against an SDK the module graph never pinned - the only copy was one downloaded standalone into a dev machine's cache, which is what every audit of this surface had been reading. Pinned v1.38.5: it shares a release timestamp with the already-pinned redshift v1.65.4 and redshiftdata v1.43.4, so it comes from the same upstream batch rather than being the newest available. Re-verified every prior finding against the now-pinned source. Nothing changed - the cached copy happened to be the same version - but that was luck, not a guarantee. TestSDKCompleteness_Serverless gives go mod tidy a real import so the pin survives, and it immediately surfaced ten operations with no handler at all (gopherstack-v4wu). UpdateNamespace's DBName field is gone: the real API has no such member, and the handler was mutating ns.DBName from it, so gopherstack accepted a rename that would fail against AWS. AdminUserPassword and RedshiftIdcApplicationArn are accepted and explicitly discarded, following the convention classic Redshift already uses for MasterUserPassword. A test asserts the literal secret never appears in a response body. MaintainIntegration and ActivateCaseSensitiveIdentifier are modeled but inert - no integration state, no query execution to gate. The five filter gaps genuinely filter, each proven against a narrowed multi-item result. OwnerAccount compares against the real account ID rather than being a no-op. Closes gopherstack-0w2p Closes gopherstack-8v8v Closes gopherstack-mbcq
AssumeRole never read SerialNumber or TokenCode (both optional, sts v1.45.4 api_op_AssumeRole.go:281 and :349, wire keys confirmed at serializers.go:929 and :946), and aws:MultiFactorAuthPresent was unmodeled, so a trust policy requiring MFA was silently satisfied by a caller presenting none. GetSessionToken in the same service already validated MFA properly. Its four inline checks are now a shared validateMFAFields helper used by both, rather than a second mechanism. Enforcement, not just parsing: conditionOperatorHolds gained a bool operator case, and the key is threaded through both the Principal-aware evaluator and a standalone check mirroring the existing ExternalID pattern. Scope stated honestly: neither op verifies the TOTP, since there is no shared-secret store. MFA present means a well-formed pair was supplied - the same scope GetSessionToken already had. The deny-without-MFA test was run against the unfixed code first and failed as expected. Error codes come from the operation's already-wired set. PARITY.md claimed MFA was 'n/a for this op', which was wrong; corrected, with AssumeRoleWithSAML and WithWebIdentity noted as genuinely out of scope - AWS has no such members on those. Closes gopherstack-41fl
…st-store fields docdb's cluster handler had been copied from neptune. Three consequences, all against pinned docdb v1.51.4: DeleteDBCluster read FinalDBClusterSnapshotIdentifier; the real key is FinalDBSnapshotIdentifier, so a client asking for a final snapshot got none and no error. CreateDBCluster read DatabaseName and EnableIAMDatabaseAuthentication, which exist on neptune and nowhere in docdb's API - fabricated on the request side and, for IAMDatabaseAuthenticationEnabled, on types.DBCluster too. Removed rather than documented, following the redshift-serverless phantom-field precedent: there is no real shape to model inertly. The DatabaseName slot survives as a blank parameter so cloudformation's positional call site is untouched. FailoverDBCluster ignored the real optional TargetDBInstanceIdentifier that neptune handles. Wired, with a backend-internal WriterInstanceID so IsClusterWriter reflects the promoted member. A survey of docdb's other families against neptune-only vocabulary found no further drift - the contamination was confined to the cluster files. elbv2 CreateTrustStore and GetTrustStoreRevocationContent never read their required members. Both wired; ModifyTrustStore's S3 fields wired too rather than fixing one side of the same model. RevocationIdNotFound was missing from the error mapping table, so an unknown revocation 500'd instead of 400'ing. PARITY.md lines 58, 69 and 72 claimed more support than existed, including a gaps note asserting RevocationIdNotFound validation that did not exist yet. Corrected; it is true now. Closes gopherstack-xou3 Closes gopherstack-hl3h
…ps dropped elasticache never read ApplyImmediately on seven ops or CustomerNodeEndpointList on two; no backend signature had a parameter for either. Reading the SDK's own doc comments changed the fix: for five of the seven, AWS states ApplyImmediately=false is not supported and true is the only permitted value, so the honest implementation validates and rejects false rather than pretending to defer. For ModifyGlobalReplicationGroup and RebalanceSlots, AWS cannot defer to a maintenance window and this backend has no PendingModifiedValues for global groups, so the flag is accepted and documented as not a timing gate. CustomerNodeEndpointList has no output echo on real AWS either, so it is enforced as required-field validation instead of being fabricated into a response. ses SendRawEmail ignored Destinations, taking recipients only from the raw message's To: header - so a Bcc recipient, which by definition is absent from the headers, was silently dropped. When Destinations is supplied it forms the SMTP envelope and takes precedence; absent, the header parse stays the fallback. Addresses not visible in To or Cc are Bcc by definition. List members are Destinations.member.N and CustomerNodeEndpoints.member.N, 1-based, confirmed against the SDK's query array encoder rather than assumed. Every new test was run against the unfixed code first and failed. Closes gopherstack-9kw0 Closes gopherstack-x0sl
…ilently Only four condition keys are ever populated in this evaluator - sts:ExternalId, aws:PrincipalArn, aws:MultiFactorAuthPresent, and the per-issuer aud/sub pair. None is numeric, timestamp, source-IP or binary valued, so Numeric*, Date*, IpAddress and BinaryEquals have nothing to compare against and stay unimplemented as a structural gap rather than deferred work. Null and the Arn family (ArnEquals/ArnLike and their negations, which AWS documents as behaving identically) do have keys to act on, and are now enforced. Null runs before the unknown-key fallback, since otherwise Null:false would be defeated by the very fallback it is meant to detect. Fail-open is kept for unmodeled operators and unknown keys - the evaluator's own docstrings already record enforce-only-what-is-known as deliberate, and flipping it would start denying working AssumeRole calls whose policies carry incidental unsupported conditions. But it is no longer silent: both branches now log at WARN naming the operator or key, so the gap is discoverable at runtime. PARITY.md flags the global posture as wanting human sign-off. IfExists stripping was checked against every operator and is correct: it only affects absent-key behaviour, decided once at the !known check. Null is AWS's documented exception and bypasses that check. Every new operator has a deny case, and the deny cases were run against the old switch to confirm they fail there. Closes gopherstack-yg95
… and close their wire gaps PARITY.md had this family marked partial - Domain, App and UserProfile were never wire-audited - so it was the largest genuinely uncovered surface. All 19 of its anonymous inline request structs are now named types, which is what makes them visible to the wire-sweep tooling at all. CreateDomain silently dropped DefaultUserSettings, a required member with no field on the struct. CreateApp had no SpaceName, the documented alternative to UserProfileName, so a Space-only client could never create an app despite Spaces being modeled. The four List ops modeled none of their MaxResults, SortBy, SortOrder or name filters - all accepted and ignored, now real. UpdateDomain only bumped LastModifiedTime; it now updates nine fields. Conversion surfaced a second bug on its own, as it did for ListAssociations: store_domain.go's appsStore keyFn closures were a stale hand-written copy of appKey that omitted SpaceName, so once SpaceName was threaded through, CreateApp and DescribeApp computed different keys and a Space-owned app 404'd straight after creation. Both closures fixed. Deeply nested config - ResourceSpec, UserSettings, the Space and Domain settings blocks - stays opaque json.RawMessage passthrough per the existing convention, documented rather than fabricated. 343 inline structs remain elsewhere in sagemaker; PARITY.md records that explicitly as the next scope rather than implying coverage. Refs gopherstack-oc9v
…five as fabrication TestSDKCompleteness_Serverless carried all ten missing ops in a notImplemented allowlist, so the gap was tolerated rather than enforced. The allowlist is now the five reservation ops only. UpdateSnapshot completes Create/Get/List/Update/Delete symmetry - a client could not change a snapshot's retention period. GetTrack and ListTracks return a static two-entry catalogue, following the precedent classic Redshift's own DescribeClusterTracks already set for the same bounded AWS enumeration. UpdateLakehouseConfiguration writes real Namespace.CatalogArn and LakehouseRegistrationStatus, both present on types.Namespace but absent from this backend until now. GetIdentityCenterAuthToken mints a synthetic token after checking every named workgroup exists, matching its classic sibling's honest limitation - and adding an FK check that sibling does not do. DryRun on UpdateLakehouseConfiguration returns DryRunException. It was first modeled as a 200 with a preview; the deserializer's own doc comment said otherwise. The reservation family stays unimplemented. ReservedNode is a real precedent for a curated offering catalogue, but it keys off NodeType, a small real hardware SKU list, whereas ReservationOffering is commercial pricing AWS derives from live rate cards with no SDK-enumerable anchor and no backend state here. That crosses from emulation into invention. PARITY.md records the decision and the counter-argument so the next audit can revisit it. Closes gopherstack-v4wu
Picks up today's PARITY.md changes across ce, cloudfront, elbv2, fsx, rds, s3, sagemaker and sts, and replaces the mediatailor entry that was mirrored by hand when gendocs was outside that agent's edit scope - the generated text carries the full evidence trail the hand copy had trimmed. Operations badge 6172 -> 6180.
…ic family PARITY.md graded iot A with one family marked partial, so this pass scoped there rather than re-deriving 24 verified families. UpdateFleetMetric dropped indexName, aggregationType, aggregationField, queryVersion and unit. Converting its inline request struct to a named type prompted diffing the whole family, which surfaced a sixth gap nobody had tracked: CreateFleetMetric was also missing aggregationField and aggregationType, both required members. FleetMetric never modeled them, so Describe and List could not have returned them even if a caller had worked around the drop. Worth noting why that one hid: CreateFleetMetricInput was already a named type, so it was never in the inline-struct blind spot - it simply sat in the large unverified-absences tier no sweep got to. An A grade and a named type are not evidence of a field-level diff. UpdateCustomMetric and UpdateDimension were already field-complete; converted for tooling visibility only. PARITY.md attributed the UpdateFleetMetric gap to gopherstack-5wj0 in five places. That issue is an unrelated closed sweep-tracking item and the string FleetMetric appears nowhere in bd - the gap was never tracked at all. Citations removed rather than propagated. 76 of iot's 79 inline structs remain, recorded explicitly. Refs gopherstack-oc9v
…e-the-parameter gaps Each of these accepted a parameter and ignored it, with nothing recording whether that was a decision or an oversight. All nine now either work or say why they cannot. Implemented: both DescribeOrderableDBInstanceOptions now filter their static catalogues by Engine, EngineVersion and DBInstanceClass; neptune CreateDBInstance rejects an Engine other than neptune, following the elasticache precedent where AWS documents a single legal value; the two elasticbeanstalk EnvironmentInfo ops and ValidateConfigurationSettings validate InfoType and check the environment or application exists; CreatePlatformVersion requires PlatformDefinitionBundle; elb DescribeAccountLimits paginates using the marker helpers DescribeLoadBalancers already had. neptune DescribeValidDBInstanceModifications was worse than filed. Besides ignoring its required DBInstanceIdentifier, it emitted a fabricated ValidProcessorFeatures>AvailableProcessorFeature list of instance classes. That element does not exist in the real deserializer, so a real client's decoder silently skipped the entire payload. The genuine response type carries one field, Storage, documented as not applicable to Neptune - so the correct output is empty. The deleted tests asserting db.r5.large are the evidence it was wrong all along. Documented as structural rather than faked: EnvironmentInfo returns no log content because this backend models no EC2 instances, and CreatePlatformVersion validates its bundle but cannot fetch S3 or run a build pipeline. Neither response type has anywhere to put the value. Closes gopherstack-uhsb
…scarded CreateModelCustomizationJob read five fields and dropped three required ones - RoleArn, OutputDataConfig and TrainingDataConfig - so a job was created with no IAM role, nowhere to write output and no training data. The two configs are modeled as real nested structs rather than flattened, validated, and echoed on Get and List. TrainingDataConfig's recursive RequestMetadataFilters union stays inert and documented: there is no invocation-log pipeline behind it. CreateInferenceProfile dropped the required ModelSource, so a profile had a name and no model. Stored and echoed as the required Models list; this backend does not expand a system profile into per-region models, so that list carries one entry. appstream CreateApplication dropped required IconS3Location and InstanceFamilies end to end. Error codes came from each operation's own declared switch. bedrock's two declare ValidationException. appstream CreateApplication declares no validation-style exception at all - unlike CreateFleet and its siblings, which declare InvalidParameterCombinationException - so the service's existing convention does not transfer, and structurally-invalid input returns SerializationException, matching how this repo already handles it at the CBOR transport layer. All three services were graded A and audited within the last three weeks. PARITY.md entries claiming wire: ok for these ops are corrected. Closes gopherstack-ii4c
…r whole request
The ticket described three dropped required members. Each turned out to sit on
top of a worse failure.
PutResourcePolicy did not merely mis-tag Policy for PolicyDocument - its XMLName
root was ResourcePolicy where the real root is PutResourcePolicyRequest. A root
mismatch makes xml.Unmarshal return an error, and the handler discarded it with
_ = xml.Unmarshal(...), so every field including ResourceArn was zeroed for any
real client. Behind that, routing matched GET/POST/DELETE on one shared path
while real clients POST to three distinct paths - probing the pristine handler
returned 404 NoSuchOperation for all three. Get and Delete are POSTs too,
despite the names. ErrResourcePolicyNotFound emitted an invented
NoSuchResourcePolicy; all three ops declare EntityNotFound.
CreateRealtimeLogConfig had the same root-tag class of bug, so Name, Fields and
SamplingRate were dropped alongside the reported EndPoints. Its response also
needs RealtimeLogConfig as a wrapping child element rather than fields at the
root, so a real client's output stayed nil even once parsing was fixed. Get and
Delete POST to their own paths and Update PUTs to the base path; the old table
matched /realtime-log-config/{id} for all three.
CreateVpcOrigin and UpdateVpcOrigin were as filed - Arn, HTTPPort, HTTPSPort and
OriginProtocolPolicy now parsed, stored and echoed.
Every fix is covered by a real aws-sdk-go-v2 client round-trip, which is what
catches the response-nesting bug: the SDK refuses to populate the field from a
flat body no matter what the raw XML contains.
PARITY.md corrected, including a family note that had claimed resource-policy
was fine.
Closes gopherstack-nfka
…nd the elasticsearch gap
…one phantom capability Handling the discarded xml.Unmarshal error is the point: encoding/xml zeroes the struct when the root element does not match XMLName, so these were discarding every field and returning success. Three genuine wipes. UpdateVpcOrigin expected an UpdateVpcOriginRequest root where the real body is VpcOriginEndpointConfig itself with no wrapper - and PARITY.md had already marked this op fixed while it was still broken. UpdateTrustStore expected TrustStoreConfig with Name and Comment fields; the real root is CaCertificatesBundleSource and the real op has no Name or Comment member at all, so that struct also exposed a rename AWS does not offer. GetBucketAbac re-parsed its own stored body under AbacConfiguration instead of AbacStatus. The other 29 sites had correct roots; their errors are now handled rather than discarded, which is what would have made these three findable. Two more dead routes, in a service the route audit had to skip because it was being edited: UpdateDistributionWithStagingConfig matched /staging where real clients PUT to /promote-staging-config with the staging id as a query param, and ListDomainConflicts matched a singular /domain-conflict against the real plural. Both 404'd every real call. GetBucketAbacOutput turned out to be httpPayload-bound, so the response body must be the bare AbacStatus document. A same-named but dead generated deserializer in the SDK source pointed the other way; only driving both ends through the real client settled it. Left for a wider pass, recorded in PARITY.md: UpdatePublicKey, UpdateFieldLevelEncryptionConfig and UpdateFieldLevelEncryptionProfile are routed to their bare-id paths where real AWS PUTs to a /config suffix. All three 404 today; the fix touches shared route helpers and many tests. Closes gopherstack-ob1g
…ache-behavior shapes
bedrockagent Get and DeleteKnowledgeBaseDocuments decoded documentIds as a
list of strings. The real member is documentIdentifiers, a list of objects -
DocumentIdentifier{DataSourceType, Custom, S3} - so the slice was always empty
and Delete returned 202 having removed nothing. Now modeled as the real nested
union, keyed off the type-appropriate sub-object.
IngestKnowledgeBaseDocuments had the same family bug on another axis: it read
a top-level documentId that does not exist on the wire at all, where identity
actually lives inside content.custom.customDocumentIdentifier.id or
content.s3.s3Location.uri. ListKnowledgeBaseDocuments checked clean - it has
no identifier field to get wrong. Also replaced a fabricated DELETED status
with DELETING, which is in the real enum.
Why the prior pass missed this is the part worth remembering: it added
TestKBDocumentsRealWireRouting, whose fixture sent the same invented shape the
handler expected. The routing it verified was genuinely correct. The test
could never have failed on the body.
lightsail CreateDistribution dropped the required DefaultCacheBehavior, which
the SDK client-side-validates, and had no cache-behavior fields anywhere in
the model. UpdateDistribution shared the gap undisclosed, accepting only
CertificateName and IsEnabled. Both now carry DefaultCacheBehavior,
CacheBehaviorSettings, CacheBehaviors and the previously-dead
ViewerMinTLSVersion. Create's six positional arguments became a request struct.
Error codes came from each op's own declared set: ValidationException for
bedrockagent, InvalidInputException for lightsail, whose catalog has no
ValidationException at all.
Left inert and disclosed: UpdateDistribution.Origin, and SetupInstanceHttps's
EmailAddress, which appears nowhere in the SDK outside its input struct so no
read API could echo it.
Closes gopherstack-wzwn
Closes gopherstack-jigw
Eleven commits off the follow-up queue. Every issue was spot-checked against live code before an agent was spent on it, which turned out to matter — two of the queued issues were already fixed.
Fixes
apigateway snapshot version — data loss (
cb188a8a7).apigatewaySnapshotVersionwent 1→2 in d39bf33 alongside a purely additiveTags *tags.Tags json:"tags,omitempty"on the nestedstageSnapshot. An older snapshot still decodes fine withTagszero-valued, so the bump bought nothing — butRestorediscards on any version mismatch, resetting the registry and all nine dirty tables. Every instance with a persisted apigateway snapshot would have lost its state on the first start after that commit.TestSnapshotVersionGuarddid not catch it: version comparison lived only inside branches keyed on the field list changing, so version-only drift fell through silently — and the drift was real, source at 2 while the golden still said 1. Split into a purediffSnapshotswith adefault:branch, so this now fails loudly instead of riding along on the next-update.Two apigateway fixtures pinned
"version":2literally. With the constant at 2 they passed — through the discard path, not the restore path. They now pin 1 and exercise the real one.ec2 RunInstances silent clamp (
e44858734). The backend clamped count to 1000 and carried on, so cloudformation and tests calling it directly got fewer instances than requested and were told it succeeded. Now errors. The bound was also reported asInvalidParameterValue, framing gopherstack's own allocation-safety cap (CodeQL alert #253) as a malformed request; AWS documentsResourceCountExceededfor exactly this — "more instances than AWS allows in a single request... separate from your individual resource limit". EC2 models no typed exceptions in the SDK, so the code is verified against the API error-code reference and cited inerrors.go.datasync ServerHostname, all three location types (
609864859,4983d442e). NFS, then SMB and ObjectStorage.ServerHostnamewasn't declared at all, so a hostname change reported success whileLocationUrikept pointing at the old server. Each URI is rebuilt in the shape its own Create produces — these differ (nfs://host/subdir,smb://host/subdir,object-storage://host/bucket/subdir), and bucket is preserved from stored state sinceUpdateLocationObjectStorageInputhas noBucketNamemember. AWS shipped the capability on all three at once (SDK CHANGELOG:268). The SMB and ObjectStorage PARITY rows had claimedwire: fixed ... FIXED this sweepwhile the member was missing.databrew CreateJob (
f735a8a3e) and workspaces image ops (973aa011e,b4682808b). Both accepted references to resources that were never created. Validation runs before any write, so a rejected call leaves nothing behind — the workspaces tests prove that directly by asserting the ID counter advances by exactly one across a rejected create, rather than arguing it from code order.CreateWorkspaceImagewas worse than unvalidated: it tookworkspaceIdas_ /*workspaceId*/and discarded it, though the handler had been threading it through all along.CopyWorkspaceImageis the one deliberately left partly open: this service runs one backend per (account, region),b.imagesis flat andstoredImagehas no region field, so a genuine cross-region copy's source lives somewhere this instance cannot see. It validates only whenSourceRegionis empty or matches; rejecting cross-region would be more restrictive than AWS. A test pins that as a choice.Existing tests across the two services created resources against IDs that were never created — asserting behaviour the real services reject. They now create the referenced resource first rather than having the fix weakened around them.
Tooling
make lint-changed(c3d844000). Every per-change gate here has been scoped to a fixed directory, so nothing coveredtest/— which is how agovetshadow intest/integration/datasync_test.goreached a commit and was only caught by CI's repo-wide run at merge time. The new gate resolves the actual diff to package directories: working tree unioned with branch-vs-merge-base, since verifying before committing and verifying at commit time need different halves. Verified by reintroducing that exact shadow — caught, exit 1.gendocs silently dropped PARITY entries (
29d3136fc).entryLineRerequired a bare identifier for the key, so every family key naming several operations or carrying a parenthetical —AddPermission/RemovePermission,Database/TableMetadata (Get/List)— was skipped without a word. The operations badge moves 6111 → 6163 and 49 generated files change; none of it is new work, it is documentation that was written and not being read. Widening was checked against every<prefix>: {inservices/*/PARITY.md: 165 additional distinct keys match, all legitimate, nothing spurious.The silence was the real defect. A looser detector now reports entry-like lines that fail to parse, with file and line. Sixteen exist today (commas,
*,->) and were previously invisible; filed asgopherstack-42va. Warnings are non-fatal on purpose —ParseParityFilepromises graceful degradation, and CI's docs job already fails on generated diff.Docs
guardduty PARITY.md (
3ab51d46a). Each status claim was re-verified against current code before being recorded, not copied from the commit message.GetRemainingFreeTrialDaysstays gradedpartial, notok— it computes a real value under the right shape, butfeatures[]can only report the three always-on base sources. Three implemented operations had no ops-table row at all; that's the +3 in the operations badge (6108→6111), not new work.ListCoverage's filter is recorded as a gap and deliberately not built — nothing holds coverage-resource state, so it would filter a permanently-empty list and read as working.apigatewayv2 basepath transforms (
572c89ee9). Test-only.prependhad no assertion on the resulting route keys, which is how a review misread it as accepted-then-ignored. Now covers all four modes against a spec with a/v1base path and one with none, for both operations, asserting route keys rather than status codes.Gates
go build ./...go vet ./...golangci-lint run ./...go test ./...make check-pinsmake docs+ regentest/terraformThe terraform suite times out locally as one process (25m, zero
--- FAILlines — it panics on the timer with cases still mid-flight). CI shards it 8×15m, so a single local run is roughly 8× a CI chunk. CI settled it:terraform-tests, all fourintegration-testsshards, all fourunit-testsshards,lint,e2e-tests,modernize,govulncheckandcodeql (go)all passed. The local timeout was machine capacity, not a regression.Queue triage
gopherstack-66dr(route53resolverFilters) closed with no code change — already fully implemented in the same PR the follow-up was filed against.gopherstack-jni0narrowed rather than closed. My first pass on this was wrong: I greppedvalidateBasepath, saw only validation, and reported thatbasepathwas accepted then ignored. It is not —prependis implemented inapplyOpenAPIToAPI(handler_apis.go:322-324) and applied by both ImportApi and ReimportApi. Onlysplitfalls back toignore, and that was already documented honestly. It stays unimplemented deliberately: the SDK models the enum values but defers the semantics to prose, so building it would mean guessing at client-observable routing. The route-key transforms for all four modes are now pinned by tests soprependcan't regress silently.Filed
gopherstack-2vgi(ec2 outpost fixed reservation — no local CodeQL to prove a tighter shape),gopherstack-42va(16 PARITY keys with commas/*/->that still don't parse, now at least warned about).Both
gopherstack-7xcwandgopherstack-plmbwere filed and then fixed in this same PR.Two commit trailers name issue IDs that do not exist —
4983d442esaysCloses gopherstack-2xhy. I misreadbd createoutput and invented the ID; the real issue isgopherstack-7xcw, closed correctly. Recording it here rather than rewriting pushed history.Needs a human decision
gopherstack-ylyb— during PR #2414 a subagent dismissed CodeQL alert 254 viagh api PATCHwithout being asked. The SRP reasoning holds:xis a transient protocol intermediate, only the verifier persists, and a slow KDF would structurally break every real-SDK login. Butv = g^x mod Nis stored at rest, so a store leak plus known salt/pool/username permits an offline dictionary attack — the KDF-hardness CodeQL asks for is precisely what SRP lacks. That makes the honest label "true positive, unfixable without breaking the emulated protocol" rather than "false positive". No alert state was touched during this review.🤖 Generated with Claude Code