Skip to content

parity-3: true AWS parity across all services (in progress)#2402

Merged
agbishop merged 173 commits into
mainfrom
parity-3
Jul 25, 2026
Merged

parity-3: true AWS parity across all services (in progress)#2402
agbishop merged 173 commits into
mainfrom
parity-3

Conversation

@agbishop

Copy link
Copy Markdown
Collaborator

parity-3: true AWS parity, service by service

Ongoing campaign to bring every one of the ~154 emulated services to true AWS parity — closing every gaps:/deferred: item in each services/<svc>/PARITY.md, deleting fabricated (non-SDK) ops/fields, fixing resource/lock leaks, and removing banned complexity //nolints by decomposition.

Status: in progress (~51 / 154 services). Each service is one squash-ish commit; the main thread independently re-runs 6 gates (build · test -race · vet · gofmt · golangci-lint 0 · banned-nolint grep empty) before committing. Per-service residuals are filed as bd tasks under epic gopherstack-9x62.

Recurring bug classes agents keep finding (all client-breaking)

  • Epoch-seconds wire bug — awsjson/REST-JSON services marshaling time.Time as RFC3339 strings where the SDK deserializer needs epoch-seconds numbers (real clients hard-fail). Hit sagemaker (25 types), glue, ssm, iot, cloudtrail, others.
  • Fabricated surface — ops/fields/enums/paths not in the real SDK; deleted (polly tagging API, s3control PublicAccessBlock ops, elbv2 revocation field, fis "completing" status, many more).
  • Ghost-row leaks — delete ops not cascade-cleaning secondary maps; unbounded growth.
  • Wrong list envelope keys / disguised no-ops — list ops returning empty to every real client; handlers discarding the request body or backend error.
  • Wrong error codes / HTTP status — e.g. backup/memorydb whole-service 400 convention, rds 5 codes → 500 instead of 400.

Notes

  • Working-tree doc aggregates (README.md, .badges/*) are regenerated once at the end, not per-service.
  • Draft until the sweep completes. Watch commit history for per-service progress.

🤖 Generated with Claude Code

Witness Patrol and others added 30 commits July 22, 2026 23:10
…lints

Fix UpdateDataSet SPICE ingestion reporting, CancelIngestion terminal-state
rejection (409 ConflictException), and Tag/Untag/ListTags ARN existence checks
(404). Add Folder.SharingModel round-trip. Reclassify 19 deferred families to
ok after no-stub audit of handler_dispatch routing.

Decompose 13 banned cyclop/gocyclo/gocognit/funlen nolints via extracted
helpers and sync.OnceValue route tables (apigatewayv2 style). Add table-driven
route-map test and regression tests for the fixed behaviors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ckage parity

Fix systemic awsjson1.1 timestamp bug: 25 Describe* and 15 List* handlers
emitted RFC3339 strings where the protocol requires epoch-seconds numbers, so
a real SDK client hard-failed deserialization. Add paired MarshalJSON/
UnmarshalJSON (Unmarshal also required for snapshot restore).

Nest HyperParameterTuningJob Strategy under its config and add required
counter/limit fields; validate DeviceFleet OutputConfig on create and accept
it on update; add required ModelPackageStatusDetails. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
IdcApplication and Partner families used fabricated action/param names making
ops unreachable (InvalidAction) or silently dropping fields; corrected to real
SDK names (CreateRedshiftIdcApplication, PartnerName, etc). Rebuild
ScheduledAction.TargetAction as the real nested union; make
ModifyClusterSnapshotSchedule/ResizeCluster actually mutate observable state;
embed Cluster.Tags inline. Audit ~18 error sentinels against real ErrorCode()
strings and derive wire code from each sentinel. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…amilies

Field-diff against SDK: add missing CrawlerTarget kinds, Crawler policies,
Database params, StartJobRun per-run overrides, Trigger conditions/actions,
dev-endpoint full fields (was a bare-name stub), blueprints, ML transforms,
data-quality rulesets, and workflow MaxConcurrentRuns enforcement. Fix
epoch-seconds wire encoding on 4 *Run types (same class as sagemaker) and
return ConcurrentRunsExceededException where documented. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…idation

Delete the invented tagging surface (TagResource/Untag/ListTags — not real
Polly API) and the fabricated SnsRoleArn field. Complete the voice catalogue
to all 106 SDK VoiceIds and correct ~25 SupportedEngines errors. Add PutLexicon
PLS/quota validation, S3/SNS param validation, and shared SSML well-formedness
checks with the correct per-op error taxonomy. Decompose writeBackendError
(cyclop 24) via a OnceValue table instead of a nolint. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ions

Add previously-dropped LoRaWAN/Sidewalk/Positioning config across device,
gateway, profile, multicast, and FUOTA types. Implement real pagination on
~15 List ops via pkgs/page. Upgrade multicast/FUOTA association tracking from
single-slot maps to real sets and fix a routing bug that discarded trailing
id segments. Cascade-clean dependent maps on delete (ghost-row fix). Swap raw
sync.RWMutex to lockmetrics.RWMutex. Decompose GetSupportedOperations funlen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… de-stub

Resolve version- and alias-qualified stateMachineArns in Start/StartSync/
DescribeStateMachine (real weighted-alias routing). Delete the fabricated
DescribeStateMachineVersion op (no such AWS operation). Add RevisionID,
publish/versionDescription validation, Retry.JitterStrategy validation, and
Activity encryptionConfiguration/tags. Wire Distributed Map S3 ItemReader
through cli.go (SetS3Reader was defined but never called). Fix DeleteActivity
tags-tombstone leak. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add RevocationConfiguration (CRL/OCSP) model wired through Create/Update/
Describe/List; implement ApiPassthrough/TemplateArn so Subject/KeyUsage/
ExtendedKeyUsage/SANs/CustomExtensions actually apply to the signed cert.
Deduplicate IdempotencyToken, enforce RestorableUntil (hide expired-deleted
CAs), the 50-tag limit, and the acm.amazonaws.com principal rule. Fix issued
cert ARNs to embed the decimal serial, add KeyStorageSecurityStandard/UsageMode/
LastStateChangeAt, dash-shape resource IDs, delete the invented
ListTagsForCertificateAuthority op. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Validate capacity-provider strategies across cluster/service/task/taskset ops
and add the missing CapacityProviderStrategy/CapacityProviderName SDK fields.
Gate include=[TAGS] on Describe{CapacityProviders,ContainerInstances,TaskSets,
ExpressGatewayService} and add the absent tag wire fields. Fix three leaks:
DeleteDaemon revision/deployment cleanup (wrong-key bug), resourceTags ghost
rows on every delete path, and make resourceTags authoritative for express
gateway tagging. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…changes)

Field-diffed against timestreamwrite@v1.35.19 (types/deserializers/api_op).
No real bugs found; service was already brought to parity in the prior sweep.
Remaining items are documented intentional deferrals unreachable via a
compliant SDK client. PARITY.md re-audit note + date bump only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fix unreachable ARP update ops routed PUT where the SDK sends PATCH; redesign
UseCaseForModelAccess (real path/POST/base64 body) and EnforcedGuardrailConfig.
Model the PromptRouter, ImportedModel, FoundationModelAgreement, and
FoundationModelAvailability families to real wire shapes (drop invented fields,
fix wrong top-level keys, add required inputs). Add ListEvaluationJobs
pagination+filters and MarketplaceModelEndpoint endpointConfig. Regression
tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eaks

Fix InputDevice ClaimDevice/TransferInputDevice body casing (were silent
no-ops on real callers). Add Cluster.NetworkSettings, Channel.AnywhereSettings
(with ClusterID validation), and derive Cluster.ChannelIds /
ChannelPlacementGroup.Channels / Node.ChannelPlacementGroups live. Add template
List Summary counts and Reservation.RenewalSettings. Fix two leaks: tag ghost
rows on delete across all resources, and DeleteCluster not cascading its
ChannelPlacementGroups. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…pe registry

Fix YAML short-form intrinsics (!Ref/!GetAtt/!Sub/!Join/etc) that silently
decoded to dead literal strings instead of resolving. Thread CreateChangeSet
Capabilities through to ExecuteChangeSet (IAM-touching change sets were
previously unexecutable). Audit and table all 16 type-registry ops, fixing
DeregisterType/SetTypeDefaultVersion disguised stubs. Fix DetectStackSetDrift
(never ran per-instance comparison), DescribeStackSet field completeness,
DescribeStackSetOperation not-found code, and gate CAPABILITY_AUTO_EXPAND on
top-level Transform. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… nolints

Add a leak-safe scheduled-action background scheduler (cron parser + worker,
ctx-parented and Shutdown-drained) so recurring/one-time actions actually fire.
Wire 7 previously-dropped ASG fields (AvailabilityZoneDistribution,
CapacityReservationSpecification, DeletionProtection, InstanceMaintenancePolicy,
etc) and make DeletionProtection a real DeleteAutoScalingGroup gate
(ResourceInUse). Decompose 7 banned nolints into helpers. Add two testpackage
exclusions for the new white-box internal tests. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Return real generatedFields from INSERTs into rowid-alias tables (Aurora
auto-increment semantics). Parse and apply resultSetOptions
(decimalReturnType/longReturnType) threaded handler->engine via context. Add
Field.arrayValue and reject array-valued parameters as BadRequestException
(unsupported, matching AWS). Add continueAfterTimeout wire field. Update all
ExecuteStatement call sites to the new signature. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Delete the fabricated DeleteSolutionVersion op (not in the real SDK). Add
parent/FK existence validation to 12 Create ops. Model CampaignConfig/
RecommenderConfig/SolutionConfig (RecommenderConfig previously dropped all but
one field) and populate latest*Update summaries, autoMLResult, and inherited
solutionConfig. Enforce UpdateRecommender recommenderConfig-required and
DatasetType/Domain enum validation. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rap fix

Rework Topic and Replicator families to real wire shapes (partitionCount/
configs/topicArn; kafkaClusters/replicationInfoList with optimistic-lock
versioning) and synthesize DescribeTopicPartitions leader/replica placement.
Fix GetBootstrapBrokers' 4 wrong JSON field names and ListClientVpcConnections'
wrong envelope key (was returning empty to every client). Store the required
CreateVpcConnection clientSubnets/securityGroups. Advance CurrentVersion on
mutation. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fix 9 structs emitting RFC3339 strings where awsjson1.1 requires epoch-seconds
numbers (real SDK clients failed to parse DescribeInstanceInformation,
maintenance-window executions, instance patches, etc). Rebuild the Sessions
family: delete invented StartSession fields, fix DescribeSessions state enum
and GetConnectionStatus casing, and turn GetAccessToken/StartAccessRequest
stubs into a real AccessRequest resource. Add missing patch-baseline and
maintenance-window fields; register-task Targets were silently dropped.
Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace wholesale-invented wire shapes/ops/enums across cross-cluster
connections, VPC endpoints, packages, applications, reserved instances,
scheduled actions, and direct-query data sources: real error codes
(ENDPOINT_NOT_FOUND), real enums (AVAILABLE not ACTIVE), tagged-union
json.RawMessage encoding, mirrored inbound/outbound connection lifecycle, and
correct domain-scoped routing. Fix CancelDomainConfigChange DryRun mutating
state and cascade-clean connections on DeleteDomain. Snapshot v2->3. Tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ixes

De-stub ListReplacePermissionAssociationsWork with real work-item tracking and
fix its plural response key. Make DisassociateResourceShare soft-delete and
AssociateResourceShare dedup status-aware (reactivate DISASSOCIATED rows). Add
GetResourceShares permissionArn/permissionVersion/tagFilters, enforce the
Disassociate-permission "no resources attached" rule, auto-associate default
managed permissions, and fix ListSourceAssociations wire shape. Decompose the
new logic under gocognit rather than suppress. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ntenance

Add a real parameter-override store so Modify/Reset DB(Cluster)ParameterGroup
values persist and DescribeDBParameters returns them (were silently discarded);
seed a documented Neptune engine-parameter catalog with real ApplyMethod rules.
Implement GlobalCluster Modify/Failover/Switchover (writer promotion), a pending-
maintenance-action queue, and a bounded per-region DescribeEvents log fed by
lifecycle ops. Cascade-clean override entries on group delete. Tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the full App and Branch field sets (Branch.enableBasicAuth was a missing
required member), replace the invented STAGING stage enum with real BETA/
PULL_REQUEST, and validate Platform/Stage/JobType. Add StartJob commitTime +
RETRY support, synthesize real GetJob steps, and produce real ListArtifacts
content via the janitor on job SUCCEED. Fix a cascade leak: DeleteApp/DeleteBranch
now clean jobs/artifacts/domains/webhooks/backendEnvironments. Tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ptions

Delete the fabricated CloneEnvironment op (not in the real SDK). Auto-provision
the Default configuration template on CreateApplication and populate
ApplicationDescription.Versions. De-stub Create/UpdateConfigurationTemplate
(OptionSettings/PlatformArn were silently dropped) and unify their responses
onto the real ConfigurationSettingsDescription shape. Replace the hardcoded
3-option DescribeConfigurationOptions stub with a ~48-option catalog honoring
the request filter. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…plan

Close all 5 gaps + 3 deferred: add RestApi endpoint/status fields,
Stage.DocumentationVersion (incl. persistence DTO), ApiKey.StageKeys,
UsagePlan per-route throttle overrides, Stage canary stageVariableOverrides,
and MethodSetting cache-encryption fields — each with the correct PATCH
patchOperation paths verified against live AWS docs. Implement scalar
PATCH-remove for description/identitySource. Fix an UpdateUsagePlan leak
(returned an unprotected pointer into backend state). Decompose the new
canary handler under cyclop. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lies

Fix list ops that returned empty to real clients (wrong keys:
consumableResources, and narrow summary shapes for scheduling policies /
consumable resources / service jobs). Store JobQueue as ARN not name
(JobDetail.JobQueue is documented as ARN). De-stub SchedulingPolicy
fairsharePolicy and ServiceEnvironment CapacityLimits (a required field
silently dropped); delete the invented ServiceJob serviceEnvironment field and
fix its wire keys. Add JobDefinition RetryStrategy/EksProperties and
jobQueueType/serviceEnvironmentOrder. Update the cloudformation caller for the
changed signatures. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…apes

Fix the service-wide error convention: AWS Backup returns HTTP 400 for every
client-fault exception (verified against botocore service-2.json), not 404/409;
corrected handleError + ~90 call sites and deleted the invented
ValidationException. Redesign TieringConfiguration/RestoreAccessVault routing
and keys to the real API. De-stub CopyJob (materialize a destination recovery
point) and PutRestoreValidationResult (wrote to a map nothing read). Fix
Framework/ReportPlan/RestoreTestingSelection wire shapes and missing required
fields. Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fix a leak: the embedded MQTT broker goroutine had no Shutdown/drain path; wire
it through pkgs/worker.SingleRun so Handler.Shutdown blocks until it exits.
Unify respondErr/handleError so all sentinels (cert/thing/version-conflict/
delete-conflict/limit) map to the right HTTP status (~130 call sites). Fix 8
types emitting RFC3339 instead of epoch-seconds. Reimplement the certificate
transfer state machine (AcceptCertificateTransfer was a near-total stub), add
missing DescribeCertificate fields, and delete invented Job/JobTemplate fields.
Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ill nolint

Apply the previously-parsed-but-ignored User/Group/Resource list filters. Fix a
cascade-cleanup leak: DeleteUser/Group/Resource/Organization left ghost rows in
aliases, mailbox permissions, memberships, delegates, and tags. Add the full
DescribeUser profile field set, access-control impersonation conditions, and
GetMailDomain DKIM/DNS records. Decompose buildOps to remove a funlen nolint.
Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fix a leak: Handler.tags (a side map outside the backend, with a Prometheus
collector registration) was never cleaned when the janitor permanently purged a
key — leaked forever per deleted tagged key. Add an OnKeyPurged callback. Add
GrantConstraints.SourceArn, GrantTokens, and Grantee/RetiringServicePrincipal
with real SDK validation, plus the missing Grant.IssuingAccount. Reject
alias-form KeyId on GetKeyLastUsage. Regression tests incl. a negative-control
leak test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… streams

Fix rdsErrorCode: 15 codes were missing AWS's Fault suffix and 5 proxy/
activity-stream errors had no mapping at all (fell through to a 500 instead of
400). Fix a leak: DeleteDBCluster left custom cluster endpoints and their tags
behind. Add Describe filters + pagination on clusters/snapshots/events, missing
resource-id/snapshot-type wire fields, and de-defer Activity Streams (invented
AuditPolicy element replaced with real PolicyStatus/KinesisStreamName/Mode).
Regression tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Witness Patrol and others added 7 commits July 24, 2026 14:14
…state leaks, comp() race

- delete invented ops: Get{User,Role}PermissionsBoundary (boundary is a field on
  Get{User,Role}), Tag/UntagGroup + ListGroupTags (Group not taggable in real IAM);
  remove Group.Tags model field
- DeleteConflict per real "must remove first" lists: DeleteUser 9 checks (login profile/
  keys/certs/SSH/MFA/inline+attached policies/group membership) not cascade; DeleteRole
  instance-profile-attachment; DeleteGroup membership; DeleteInstanceProfile role
- rename user/group syncs reverse policyAttachments index (stale key blocked DeletePolicy)
- clear handler-level tags on delete of instance-profile/SAML/OIDC/server-cert/MFA
  (recreate resurrected old tags); comp() lazy-init data race -> direct return

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ions, TA language set

- handleError emitted {message} with no __type/X-Amzn-ErrorType -> every error was
  UnknownError to real clients; now service.JSONErrorResponse{Type,Message} + resolveErrorType
- CaseIdNotFound/AttachmentIdNotFound/AttachmentSetIdNotFound 404 -> 400 (awsjson1.1
  client-fault default, no status override in model)
- implement AttachmentSetSizeLimitExceeded (>5MB/>3 per set), AttachmentLimitExceeded
  + DescribeAttachmentLimitExceeded (sliding-window), CaseCreationLimitExceeded (500 open)
- DescribeTrustedAdvisorChecks: TA's own 11-code language set (was reusing 4-code case set)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nion double-wrap, pagination

- SEVERE: Create/Describe/UpdateApplication, DescribeApplicationAssignment,
  GetApplicationSessionConfiguration, DescribeTrustedTokenIssuer wrapped the flat real
  output under invented Application/ApplicationAssignment/TrustedTokenIssuer objects ->
  real aws-sdk-go-v2 clients parsed every field nil; flatten to real shapes; Update* void
- GetApplicationAuthenticationMethod/GetApplicationGrant double-wrapped the union body
  one level too deep -> union deserializer never found the tag; fixed
- delete invented fields: AccountAssignmentCreationStatus.AccountId -> real TargetId/
  TargetType; Describe{Application,Instance,TrustedTokenIssuer} .Tags (tags only via
  ListTagsForResource); TrustedTokenIssuer InstanceArn; PutApplicationAssignmentConfig
  AssignmentRequiredForAllIdentities; SessionConfig re-modeled on real
  UserBackgroundSessionApplicationStatus (was fabricated SessionDuration)
- add pagination to ListApplicationAssignments(ForPrincipal)/AccessScopes/Providers/
  TrustedTokenIssuers (MaxResults/NextToken were ignored)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…OST-body list routing

- build (method,path)->op matrix from SDK v1.60.1 serializers.go (110+ real routes,
  route_matrix_test.go); close remaining 18 unroutable/misrouted routes: RPC tenant/
  resource-tenant (8), deliverability-dashboard sub-resources (5), insights/
  recommendations (3), reputation-entity listing, POST list-export/import-jobs
- ListExportJobs: real POST /v2/email/list-export-jobs (was invented unroutable GET on
  /v2/email/export-jobs)
- ListReputationEntities: real POST /v2/email/reputation/entities; delete invented
  duplicate /v2/email/reputation-entities/ top-level path (not in SDK)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…, RunJobFlow fleets/policies

- GetOnClusterAppUIPresignedURL sent {"URL"} — real type has only PresignedURL/
  PresignedURLReady, so real clients always deserialized nil; fix field name + add
  ready flag (also missing on GetPersistentAppUIPresignedURL)
- delete invented RunJobFlowInstances.IamInstanceProfile; add real top-level
  RunJobFlowInput.JobFlowRole -> Ec2InstanceAttributes.IamInstanceProfile
- RunJobFlow: support Instances.InstanceFleets (+InstanceCollectionType), echo
  KerberosAttributes/PlacementGroupConfigs, derive AutoTerminate, accept inline
  ManagedScalingPolicy/AutoTerminationPolicy
- Get{ManagedScaling,AutoTermination}Policy return nil (omitempty) not a zero-valued
  object when unset (real outputs are pointers)
- Add/RemoveTags/ListTagsForResource resolve Studio IDs, not just clusters
- decompose RunJobFlow (validateRunJobFlowParams/buildNewCluster) to clear funlen

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…r parity-3

Aggregate doc regeneration for the parity-3 sweep (152 services audited).
Deliberately deferred to a single commit so per-service commits stayed scoped
to their own directory.

- operations badge: 5215 -> 5502
- parity badge: 133 A / 19 B -> 138 A / 6 A- / 8 B
- per-service gap/deferred counts refreshed from each PARITY.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… s3Reg param

f6d83af added an 8th s3Reg param (SFN S3 ItemReader wiring) but left the root
wiring test calling it with 7 args. go build ./... skips _test.go, so only
go vet ./... caught it; pass nil for s3 like the test already does for sqs/sns/ddb.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@agbishop
agbishop marked this pull request as ready for review July 24, 2026 21:52
Witness Patrol and others added 16 commits July 24, 2026 22:31
… ImageDetail fields -> grade A

Closes every remaining gaps: item in services/ecr/PARITY.md for real, without
weakening the tests that previously blocked them.

- CompleteLayerUpload: enforce EmptyUploadException (no UploadLayerPart calls) and
  UploadNotFoundException (uploadId matching no live Initiate session); the old
  "direct digest" shortcut path is gone. ~9 test call sites that abused it as a
  seeding shortcut now use a real Initiate/UploadPart/Complete helper.
- UploadLayerPart/CompleteLayerUpload: enforce LayerPartTooSmallException via
  deferred validation (record part boundaries on upload, validate at complete).
- PutImage: enforce ImageAlreadyExistsException on unchanged manifest+tag; trigger
  condition confirmed from the API docs plus a reference emulator implementation.
- Get/StartLifecyclePolicyPreview: honor Filter, ImageIds, MaxResults, NextToken
  (previously always returned the full unfiltered, unpaginated result set).
- DescribeImages ImageDetail: add artifactMediaType, imageScanFindingsSummary,
  imageScanStatus, subjectManifestDigest, and new backing state for
  lastRecordedPullTime / lastActivatedAt / lastArchivedAt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nvokers -> grade A

Closes both execution gaps in services/pipes/PARITY.md.

- runner: source polling was gated to SQS only (isSQSARN); Kinesis and DynamoDB
  Streams sources were modeled in the wire shapes but a RUNNING pipe never polled
  them. New sources_poll.go implements both, with shard-iterator caching, filter
  application, DLQ-on-failure and stale-iterator sweep.
- cli.go: wirePipesRunner only set the SQS reader plus Lambda/StepFunctions
  invokers, so a RUNNING pipe targeting anything else returned
  ErrTargetInvokerUnwired and silently stranded the source message. Adds
  wirePipesSources/wirePipesInvokers/wirePipesTargets and adapter structs for
  SNS, SQS, Kinesis, EventBridge, CloudWatchLogs and Firehose targets plus both
  DLQ senders.
- filter: generalized matchesAnyFilter from *SQSMessage to a body string so the
  same filter path serves every source type.

MSK, self-managed Kafka, RabbitMQ and ActiveMQ sources remain unpolled and are
documented as such: services/kafka and services/mq are AWS control-plane CRUD
only, with no Kafka wire-protocol or AMQP/OpenWire broker anywhere in the repo to
read from. pollPipe leaves those source types unrouted rather than faking delivery.

Integration test TestIntegration_Pipes_UpdatePipe now supplies RoleArn, which
validateOpUpdatePipeInput marks unconditionally required in the real SDK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…config -> grade A

Closes all 4 tracked gaps in services/s3/PARITY.md and fixes 7 real wire bugs found
while field-diffing the families that prior passes never re-diffed.

Gaps closed:
- PutBucketPolicy: full IAM policy-grammar validation (Version/Statement/Effect/
  Principal/Action/Resource) returning MalformedPolicy, replacing the JSON-syntax-only
  check. Bucket policies are resource-based, so Principal/NotPrincipal is required.
- object_lambda: confirmed by investigation that services/s3control already owns the
  access-point resource surface and WriteGetObjectResponse is genuinely an s3 op, so
  the split is correct; the one real remaining limitation (no access-point-ARN routing
  on GetObject) is documented instead of left vague.
- s3StubOperations renamed to s3ExtendedOperations - every op in it is implemented, the
  old name was misleading.
- CopyObject / PostObject / SelectObjectContent / bucket_ops_* config families field-
  diffed against the real SDK.

Wire bugs fixed:
- CopyObject silently ignored copy-source SSE-C headers, so copying an SSE-C source
  without them wrote the raw ciphertext out as plaintext; now rejected with 400. Also
  fixes UploadPartCopy, which shares the path.
- CopyObject: missing checksum fields in CopyObjectResult; LastModified came from an
  independent time.Now() instead of the stored value; destination SSE-S3/SSE-KMS
  headers ignored.
- PostObject silently ignored x-amz-storage-class, x-amz-server-side-encryption(-aws-
  kms-key-id) and x-amz-checksum-algorithm form fields, so a presigned POST asking for
  SSE-KMS was stored unencrypted.
- SelectObjectContent never read or validated SSE-C headers.
- writeConfigListXML double-wrapped each already-rooted stored config, so
  ListBucketAnalytics/IntelligentTiering/Inventory/MetricsConfigurations emitted XML no
  real SDK client could parse.

Integration test delete_non-empty_bucket_succeeds_(async) was asserting the old
non-AWS behavior; renamed and rewritten to expect 409 BucketNotEmpty, which
api_op_DeleteBucket documents as real.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…p/integration fields -> grade A

Closes all 3 tracked gaps in services/rds/PARITY.md. The case-insensitivity gap had
been deferred by three prior passes as "too invasive"; done properly here.

- Identifiers are now case-insensitive for the 6 families real AWS folds
  (DBInstanceIdentifier, DBClusterIdentifier, DBSnapshotIdentifier,
  DBClusterSnapshotIdentifier, DBParameterGroupName, DBClusterParameterGroupName),
  so creating "MyDB" then "mydb" now collides with DBInstanceAlreadyExistsFault.
  Folding happens only at store boundaries; the stored value keeps the caller's
  original casing so wire responses still echo what was sent. Note pkgs/store's
  Table does NOT invoke keyFn on Get/Has/Delete, so every raw call site had to fold
  too - folding the keyFn alone would have been a half-fix. Satellite tables
  (snapshot attributes, tags-by-ARN, roles, ready-at scheduling) and identifier
  Filters matching folded as well, else they re-fragment under mixed-case calls.
- CreateDBInstance/CreateDBCluster validate Engine against allow-lists field-diffed
  from the SDK doc comments (24 instance engines, 5 cluster engines), returning
  InvalidParameterValue. This surfaced a pre-existing bug: 3 tests passed
  engine/instanceClass swapped and only passed because nothing validated Engine.
- DBShardGroup gains DBShardGroupArn/DBShardGroupResourceId and wires
  PubliclyAccessible across all four shard-group ops (Create/Delete/Modify/Reboot
  were all missing them, not just Create). Integration gains KMSKeyId/CreateTime/
  Tags/Errors, with cascade-cleanup added to DeleteIntegration so the shared
  per-ARN tags map does not leak.

Adds pkgs/strs (Fold/Equal/ContainsFold) so this folding has one shared, tested
home rather than being reimplemented per service.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tions -> grade A

Closes all 6 tracked gaps in services/ssm/PARITY.md.

- CreateAssociation/UpdateAssociation/CreateAssociationBatch gain the 11 fields the
  real SDK models and gopherstack dropped: ApplyOnlyAtCronInterval,
  ComplianceSeverity, MaxConcurrency, MaxErrors, OutputLocation, ScheduleExpression,
  SyncCompliance, CalendarNames, AssociationDispatchAssumeRole,
  AutomationTargetParameterName, Duration.
- CreateOpsItem/UpdateOpsItem gain AccountId, ActualStartTime, ActualEndTime,
  Notifications, PlannedStartTime, PlannedEndTime, RelatedOpsItems.
- PatchBaseline.ApprovedPatchesEnableNonSecurity is *bool, matching the SDK, so
  UpdatePatchBaseline can distinguish explicit false from omitted and can finally
  turn the flag back off.
- ExpirationNotification and NoChangeNotification parameter policies were stored and
  round-tripped but never evaluated. They are now swept by the janitor and emitted
  as real EventBridge events (source aws.ssm, detail-type "Parameter Store Policy
  Action"), behind a ParameterPolicyNotifier interface implemented by the
  EventBridge backend and wired in cli.go. Dedupe state resets on write and is
  cascade-cleaned on delete/expiry so it cannot leak.
- ListCloudConnectors/ValidateCloudConnector MaxResults used a guessed cap of 50.
  AWS has since published real bounds (List max 10, Validate max 75); both are now
  enforced with ValidationException.

ValidateCloudConnector still cannot make a real outbound Azure call - no tenant or
credentials exist in the sandbox, and a local AWS emulator reaching out to a third-
party cloud would be wrong even if it could. Documented rather than faked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e -> grade A

Brings dynamodbstreams, mediastore and sts to overall: A.

dynamodbstreams: no code change. Both listed gaps were already closed by 8ba0d8a
(ShardFilter CHILD_SHARDS is applied in streams_ops.go DescribeStream; the wire
helpers now live only in dynamodb/streams_wire.go and are called directly). PARITY.md
was stale; corrected after verifying against current code.

mediastore:
- MetricPolicyRule ObjectGroup/ObjectGroupName now validated against the real
  botocore bounds (max 900 / max 30 plus pattern). The Go SDK's client-side
  validators do not check these, so only raw-HTTP callers could hit it - the
  emulator should still be correct.
- PutCorsPolicy enforces the documented 100-rule maximum.
- Container lifecycle can now express CREATING/DELETING via SetActivationDelay,
  matching the existing house convention in services/redshift and services/efs
  (delay defaults to zero, so behavior is unchanged unless a test opts in).
  Transitions advance lazily rather than from a goroutine, so nothing can leak.

sts:
- OutboundWebIdentityFederationDisabledException is now reachable. IAM already
  routed Enable/DisableOutboundWebIdentityFederation and
  GetOutboundWebIdentityFederationInfo but they were no-op stubs with the wrong
  response shape and no state; they now hold real state, defaulting to enabled.
  STS reads it through an optional AccountSettingsLookup captured in the existing
  SetOIDCLookup call, so no cli.go change was needed.

JWTPayloadSizeExceededException stays open as a proven impossibility: no byte
threshold is published in the SDK doc comments, validators.go, any vendored
botocore/smithy model, or AWS documentation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…de A

Closes the last gap in services/lambda/PARITY.md. All 9 durable-execution ops do
exist in aws-sdk-go-v2/service/lambda v1.97.0, so this is a rewrite, not a deletion
of an invented family.

Wire shapes, field-diffed against the SDK's serializers/deserializers:
- ExecutionArn split into DurableExecutionArn plus DurableExecutionName
- StartTime/StopTime were ISO strings; the real shape uses Unix epoch
  StartTimestamp/EndTimestamp
- added DurableConfig echo, Error, ExecutionDataIncluded (honors
  ?IncludeExecutionData=), InputPayload, Result, TraceHeader, Version
- added the TIMED_OUT status
- GetDurableExecutionHistory emitted an invented "Checkpoint" EventType with no
  pagination; now returns the real types.Event shape with its 5 Execution*Details
  subtypes
- GetDurableExecutionState echoed raw untyped StateData; now returns real
  Operations built from a Checkpoint-Updates state machine

Routing bugs found during the same field-diff - these ops were unreachable by any
real SDK client:
- StopDurableExecution was DELETE on the bare ARN path; real wire is POST .../stop
  returning {StopTimestamp}. Stopping an unknown ARN also silently returned 200 and
  now 404s, matching Get/GetState.
- ListDurableExecutionsByFunction was at GET /durable-executions?FunctionArn=; real
  path is GET /functions/{FunctionName}/durable-executions.
- SendDurableExecutionCallbackSuccess/Failure/Heartbeat were nested under the
  execution ARN; real wire is a separate /durable-execution-callbacks/{CallbackId}/
  {succeed|fail|heartbeat} resource, now indexed by callback owner.

Also fixes a real data race: read handlers returned a live internal pointer that
callers read unsynchronized against concurrent Checkpoint/Stop mutation. Reads now
build the full response under the lock, deep-copying operations, and the store uses
lockmetrics.RWMutex per repo convention.

FunctionArn/DurableConfig/InputPayload/Version are wire-correct but stay empty:
nothing threads them through, because gopherstack's Invoke path does not model
durable-execution semantics and the real API has no StartDurableExecution entry
point. Documented as an architecture gap rather than a wire-shape one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… identitystore -> A

identitystore (A- -> A):
- matchUserSingleValueFilter returned true for an unrecognized AttributePath, so an
  unknown filter silently matched EVERY user. The group side had the same bug via a
  missing default case. Both now match nothing.
- CreateUser accepted a gopherstack-invented ExternalIds wire field and forwarded it
  to the backend - the same bug class already fixed for CreateGroup but missed here,
  and previously documented as safe, which was wrong.
- Primary-email uniqueness is now enforced on CreateUser/UpdateUser; the
  usersByPrimaryEmail index existed and was documented as a uniqueness index but was
  never actually checked.
- Implemented smithy pattern-constraint validation (UserName, GroupDisplayName, the
  shared SensitiveStringType fields, AttributePath, IdentityStoreId, ExternalId
  issuer/identifier), verified against current botocore rather than the stale bundled
  aws-sdk-go v1.55.5 model.
- Implemented the Administrator/AWSAdministrators reserved-name restriction,
  confirmed in the Create request doc strings.
ExternalId uniqueness stays unenforced: no AWS evidence supports it, and IdP
re-provisioning can legitimately reassign one.

iot (stays A-): SearchIndex's ThingGroupDocument emitted parentGroupName (string)
where the real shape is parentGroupNames (the full ancestor list), so a real client
never found the field; added the missing thingGroupDescription, the entirely absent
rootToParentThingGroups on DescribeThingGroup, and sumOfSquares on GetStatistics.
job/jobtemplate and device_defender remain honestly partial.

codebuild (stays A-): Fleet had no id field, Create ignored overflowBehavior/imageId/
fleetServiceRole, and UpdateFleet could change only baseCapacity despite ~9 more real
members. Nested ComputeConfiguration/ProxyConfiguration/VpcConfig/ScalingConfiguration
are still unmodeled and are now recorded as a gap instead of being silently absent.

elasticache (stays A-): serverlessCacheXML wired only 5 of 13 real fields, dropping
CreateTime/DailySnapshotTime/KmsKeyId/MajorEngineVersion/SecurityGroupIds/
SnapshotRetentionLimit/SubnetIds/UserGroupId from every response even though the
domain model already stored them; same for ServerlessCacheSnapshot's CreateTime.
Caught only by a real SDK round-trip test, which is what backend-struct assertions
had been hiding. CacheUsageLimits and several snapshot fields remain unmodeled and
are now recorded as gaps.

iot, codebuild and elasticache keep A- deliberately: this pass found new genuine gaps
in each rather than clearing them, and an empty gaps list is not evidence of parity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ersion signing -> grade A

Closes all three tracked gaps in services/sns/PARITY.md.

- ArchivePolicy/ReplayPolicy were accepted on any topic and fanned out to any
  protocol. AWS documents archiving and replay as available only for A2A FIFO topics,
  which means sqs/lambda/firehose - HTTP/HTTPS/email/sms/application are A2P and never
  eligible even on a FIFO topic. ArchivePolicy is now rejected on non-FIFO topics at
  both CreateTopic and SetTopicAttributes; ReplayPolicy is rejected unless the topic
  is FIFO and the subscription protocol is A2A. The now-unreachable HTTP/SMS/
  application replay branches were deleted.
- Subscribe accepted any string as an endpoint. It now validates per protocol:
  sqs/lambda/firehose/application ARNs by service and resource prefix, and http/https
  as a real URL whose scheme matches the protocol.
- SignatureVersion was stored but ignored - delivery always signed SHA-256. Publish
  now resolves the topic attribute and signs SHA-1 for version 1 (the documented
  default) or SHA-256 for version 2, declaring the version it actually used across
  HTTP/HTTPS, Lambda and Firehose delivery.

Several existing tests only passed because none of this was validated: placeholder
endpoints like "x"/"y"/"q" and scheme-mismatched URLs, archive tests running on
standard topics, and signing tests asserting the old hardcoded "2". All rewritten to
the real behavior. Also fixes a CloudFormation test fixture that passed a queue URL
where Protocol: sqs requires an ARN.

Outside services/sns: pkgs/events gains a SignatureVersion field on
SNSPublishedEvent, and services/sqs/sns_delivery.go now reports the real signature
version instead of a hardcoded "1".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s, unreachable routes

codebuild (A- -> A): implemented Fleet's nested ComputeConfiguration,
ProxyConfiguration, VpcConfig and ScalingConfiguration end to end - parsing, backend
state, wire shape and persistence - field-diffed against the real types. Fleet.VpcConfig
reuses Project's identical type rather than duplicating it. Also fixes a disguised stub:
Fleet.ScalingConfiguration existed as a model field that nothing ever set.

elasticache (A- -> A): added CacheUsageLimits on ServerlessCache and ExpiryTime/
KmsKeyId/BytesUsedForCache/ServerlessCacheConfiguration on ServerlessCacheSnapshot.
While wiring the request side this uncovered a severe bug: the dispatched
createServerlessCache/modifyServerlessCache handlers parsed only ServerlessCacheName,
Description and Engine, silently dropping every other real request field on the actual
wire path. Both now route through the existing *Full backend methods. Confirmed with a
real SDK client probe - the previous backend-struct assertions could not see it.

iot (stays A-): fixed AuditFinding's isSuppressed/reasonForNonComplianceCode/
taskStartTime plus reasonForNonCompliance, and implemented ListAuditFindings filtering.
The same diff found three routing bugs that made ops unreachable by any real client:
ListAuditFindings was served on GET where real AWS uses POST, and
DescribeJobExecution/CancelJobExecution/DeleteJobExecution sat under
/jobs/{jobId}/things/{thingName} where the real path is /things/{thingName}/jobs/{jobId}.
JobExecution's wire shape was also wrong (invented thingName instead of thingArn,
missing statusDetails/versionNumber/forceCanceled/approximateSecondsBeforeTimedOut),
and ListJobExecutionsForJob/ForThing returned a flat shape where real AWS nests
jobExecutionSummary. Cancel/Delete now honor force/expectedVersion/statusDetails.

iot keeps A- deliberately: Job's advanced fields and per-target JobExecution fan-out at
CreateJob time, plus several device_defender families, are real remaining sub-surfaces -
not proven impossibilities, so the grade stays honest rather than inflated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…pe, timestamp epsilon, query decoding

Fixes the remaining CI integration and terraform failures on this branch. Three were
real regressions and three were stale tests asserting pre-parity behavior; each was
judged against the SDK rather than made to pass.

Real regressions:
- kinesisanalyticsv2: DeleteApplication's CreateTimestamp safety check used a 1e-6
  epsilon, but smithy-go encodes unixTimestamp to millisecond precision while
  app.CreatedAt keeps nanoseconds. A real client could never round-trip closer than
  ~1ms, so every legitimate delete was rejected. Epsilon widened to 1e-3.
- acm: CertificateSummary.KeyUsages/ExtendedKeyUsages are plain string enums
  ([]KeyUsageName/[]ExtendedKeyUsageName), unlike CertificateDetail.KeyUsages which
  is []KeyUsage objects. ListCertificates emitted the object-wrapped shape, so a real
  client's deserializer failed with "expected KeyUsageName to be of type string".
  The existing unit test had locked in the wrong shape and is corrected too.
- rolesanywhere: ListTagsForResource parsed the raw query string by hand, so the
  httpQuery-bound ResourceArn arrived percent-encoded and never matched a stored ARN,
  returning ResourceNotFoundException on every call - which is what broke Terraform's
  post-create tag refresh. Now decoded with net/url.ParseQuery.

Stale tests, corrected to real AWS behavior:
- redshiftdata: Database is a required member on ListDatabases/ListSchemas/ListTables;
  the tests called them with empty params.
- cognitoidentity: GetCredentialsForIdentity was called before SetIdentityPoolRoles,
  which is exactly the case InvalidIdentityPoolConfigurationException documents.
- fis: stopping an experiment before it reaches running yields cancelled, not stopped,
  and the test raced the pending->initiating window; it now accepts both terminal
  states.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…pipes wiring test

iot: closes both remaining partial families. Four ops were unreachable by any real
client - CreateJob and CreateJobTemplate were routed on POST where the real API uses
PUT, GetJobDocument sat at /jobs/{jobId}/document instead of /job-document, and the
RouteMatcher whitelist was missing plain /jobs (ListJobs) and the entire
/job-templates and /mitigationactions families, so those silently 404'd.

CreateJob and AssociateTargetsWithJob now fan out a real QUEUED JobExecution per
resolved target thing (thing ARN directly, thing-group ARN expanded to its members),
which is what makes DescribeJobExecution / ListJobExecutionsFor* meaningful;
jobProcessDetails is rolled up live from those rows rather than invented counters, and
DeleteThing/DeleteJob cascade-clean them. Job and JobTemplate gained
jobExecutionsRetryConfig, presignedUrlConfig, schedulingConfig with maintenanceWindows,
and destinationPackageVersions.

device_defender: DetectMitigationActionsTaskSummary emitted an invented "actions" field
instead of the real "actionsDefinition"; DetectMitigationActionExecution used
executionStartTime/EndTime instead of executionStartDate/EndDate; ActiveViolation and
ViolationEvent were missing lastViolationTime and violationEventAdditionalInfo.
ListAuditFindings resourceIdentifier filtering is now implementable and implemented,
because findings carry a real typed ResourceIdentifier instead of a freeform map.

iot stays A-: CreateSecurityProfile still never persists Behaviors/AlertTargets/
AdditionalMetricsToRetain/MetricsExportConfig, which blocks the behaviorCriteriaType
filter. That is a third family the prior gap list did not track, and closing it means
building the SecurityProfile.Behaviors subsystem first.

Also fixes TestWirePipesRunner_SQSSourceTargets, which set an ArchivePolicy on a
non-FIFO topic - legal before this branch made SNS enforce the real FIFO-only rule.
It now observes delivery through a real SQS subscription, since FIFO publishes need a
MessageGroupId the pipes SNS adapter does not send. Caught only under CI's
-shuffle on -short flags.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The e2e package is behind a `//go:build e2e` tag, so neither
`go build ./...` nor a plain `go vet ./...` compiles it. Three backend
signature changes from earlier parity work therefore broke the e2e build
undetected, failing the e2e-tests CI job with 5 compile errors.

- lakeformation.RegisterResource: pass a zero RegisterResourceOptions;
  the test never exercised ExpectedResourceOwnerAccount/WithFederation/
  WithPrivilegedAccess/HybridAccessEnabled.
- route53resolver.CreateResolverEndpoint: pass false, false for the new
  trailing rniEnhancedMetricsEnabled/targetNameServerMetricsEnabled,
  matching the handler default when the fields are omitted.
- verifiedpermissions.CreatePolicyStore: pass an empty trailing
  clientToken; neither test retries the call or asserts idempotent
  replay.

No assertions weakened, no cases removed, no production code changed.

Gate added for future passes: `go vet -tags e2e ./test/e2e/...`

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…issues

All four were notice-level findings failing the CodeFactor check on PR #2402.

- opensearch: CodeFactor's warning-comment rule matches "todo" as a
  case-insensitive substring, and hit the doc comment for
  toDomainPackageDetailsJSON ("toDomainPackageDetailsJSON"). Not a real
  TODO. Reworded the comment rather than renaming the function, since
  the to*JSON prefix is the established convention here (25 helpers).
- verifiedpermissions: exported PolicyScope returned unexported
  *policyScope (unexported-return). Renamed the type to
  PolicyScopeResult and updated the StorageBackend interface. The only
  caller is handler_policies.go in this same package; no cross-service
  caller exists.
- bedrockagent: TestIngestionJobStatistics and TestDeleteAgentCascades
  were flagged Complex Method. Decomposed both by extracting subtest
  bodies and fixture setup/assertions into named helpers with
  t.Helper(). No nolint directives added.

Assertion counts unchanged (46/46 and 24/24), t.Parallel and t.Run
counts unchanged - pure extraction, no coverage lost.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…d routing -> grade A

Closes the last gap in the repo; every service is now overall: A.

- CreateSecurityProfile/UpdateSecurityProfile/DescribeSecurityProfile silently dropped
  Behaviors, AlertTargets, AdditionalMetricsToRetain(V2) and MetricsExportConfig. They
  now persist end to end. UpdateSecurityProfile was rebuilt to the real input shape,
  including ExpectedVersion (a query param, not a body field) and the DeleteX-flag
  versus field mutual exclusion. Removed an invented "tags" field from the Describe and
  Update outputs, which the real shapes do not have.
- With real behavior criteria stored, the behaviorCriteriaType filter (STATIC /
  STATISTICAL / MACHINE_LEARNING) on ListActiveViolations and ListViolationEvents is
  now implementable and implemented, resolved live from the owning profile.
- Wire-shape bugs in all three list ops: ListSecurityProfiles emitted
  securityProfileName/securityProfileArn where SecurityProfileIdentifier uses the
  shortened name/arn; ListSecurityProfilesForTarget was missing the identifier's arn
  and the entire sibling target object; ListTargetsForSecurityProfile emitted an
  invented securityProfileTargetArn instead of arn. All three also gained
  maxResults/nextToken pagination.
- RouteMatcher whitelist was missing plain /security-profiles and
  /security-profiles-for-target, so both 404'd before op dispatch ever ran. Confirmed
  by reverting the fix and observing a real 404 from a generated SDK client.
- DetachSecurityProfile never validated existence (AttachSecurityProfile's earlier fix
  was never mirrored onto it), and DeleteSecurityProfile leaked target attachments in
  securityProfileTargets; both fixed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t grade A

Final doc regeneration for the parity-3 phase-2 sweep.

- parity badge: 138 A / 6 A- / 8 B -> 152 A
- operations badge: 5502 -> 5534

Every service now records overall: A in its PARITY.md, with remaining items only
where they are genuinely impossible to emulate (no real AWS account, no published
spec, or no backing subsystem in this repo) and documented as such.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@agbishop

agbishop commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator Author

📊 Code Coverage Report

Metric Value Status
Total Coverage 0.0%
0.0%
75.0%
0.0%
85.0%
New Code Coverage N/A (0/0 stmts)

Tip

This project maintains a minimum coverage threshold of 85%. Maintain or improve coverage on new code to ensure long-term stability.


Last updated: Sat, 25 Jul 2026 11:08:45 GMT

Witness Patrol and others added 2 commits July 25, 2026 04:51
…e positives

CodeQL's go/insecure-password-hashing rule flagged two hashes as password
hashing. Neither handles a credential, and changing either algorithm would
break correctness, so both are suppressed with the convention already used
on the SHA-256 signer in this file.

- sns/signing.go signSHA1 computes an RSA-SHA1 digital signature over the
  canonical notification string. SHA-1 is required by the AWS SNS
  SignatureVersion=1 spec, which is the documented default. The existing
  //nolint:gosec covers golangci-lint but CodeQL needs its own marker.
- lambda/layers.go layerPolicyRevisionID hashes the sorted StatementId set to
  derive a policy revision ID - a content digest, not a credential.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The markers added in dfd40c3 did not suppress anything - CodeQL honors an
inline suppression only on the flagged line or the line immediately above it,
and in both cases another comment sat in between, so the alerts simply shifted
down by the inserted lines. Moved both markers to trailing same-line comments.

No behavior change; both hashes remain false positives as described in
dfd40c3 (SNS SignatureVersion=1 requires RSA-SHA1 for message signing; the
Lambda hash is a content digest over statement IDs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread services/lambda/layers.go
ids := collections.SortedKeys(stmts)

// Content digest over statement IDs to derive a revision ID, not a credential.
h := sha256.Sum256([]byte(strings.Join(ids, "\x00"))) // codeql[go/insecure-password-hashing]
@agbishop
agbishop merged commit 3c8a7ff into main Jul 25, 2026
34 of 35 checks passed
@agbishop
agbishop deleted the parity-3 branch July 25, 2026 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants