Skip to content

refactor: cut dead surface and duplication found by a repo-wide over-engineering audit - #120

Merged
skyoo2003 merged 8 commits into
mainfrom
refactor/over-engineering-audit
Jul 30, 2026
Merged

refactor: cut dead surface and duplication found by a repo-wide over-engineering audit#120
skyoo2003 merged 8 commits into
mainfrom
refactor/over-engineering-audit

Conversation

@skyoo2003

Copy link
Copy Markdown
Owner

Summary

A repo-wide over-engineering audit, applied: removes surface no code path can reach, folds per-service copies of the same helper into one, and fixes a weekly workflow that was structurally incapable of doing its job. Net -1,951 lines and one fewer dependency, with no intended behaviour change to the AWS API surface.

Related Issue

None — no tracking issue; the findings are listed below.

Changes

Dead surface removed

  • GetMetrics / ServiceMetrics plugin API and the /devcloud/api/metrics endpoints — 102 of 104 implementations returned a zero-valued struct and nobody ever populated TotalRequests/ErrorCount, so the endpoint reported zeros forever. The two services that did fill ResourceCount lose nothing: /devcloud/api/services already derives counts from ListResources. Pre-1.0, so not a v1.x break.
  • The event bus and the admin WebSocket at /devcloud/api/ws — nothing in the binary ever called Publish, and main.go dropped the bus reference at the call site, so the socket accepted connections and could never send a message. Drops gorilla/websocket.
  • shared.ResourceStore (114 lines + 204 of tests) — no production caller; every service writes its own SQL. Its shared.Scanner was a second declaration of the identical sqlite.Scanner.
  • gateway.ExtractAccountID — read the Authorization header into _, returned a constant, no callers.
  • The auth.enabled key — its only effect was a startup warning that it was unimplemented.
  • The custom buffering slog.Handler (92 lines) — replaced by config warnings returned as []string and logged after setupLogging, keeping the same guarantee from fix: config warnings honor logging.format/level (#113) #119 that config-time warnings honour logging.format/level.

Duplication folded

  • 23 copies of the same string-param accessor (strParam / strVal / getString / str — three spellings, identical behaviour) → shared.StrParam; 10 per-service region constants → shared.DefaultRegion; shared.DefaultAccountID now mirrors plugin.DefaultAccountID.
  • The two mirror-image case-conversion walkers in shared → one mapKeys(v, f), moved to kafka, its only caller, with a test.
  • Deliberately left alone: the per-service jsonError/jsonResponse helpers, whose Content-Type differs by protocol (application/json vs x-amz-json-1.0 vs 1.1), and the randHex/generateID variants, which produce genuinely different id formats.

Config

  • default.yaml 325 → 16 lines. All 103 service entries were byte-identical boilerplate (enabled + data_dir ./data/<name>) with zero exceptions, so they are derived now. The services block is optional and authoritative: omit it and every registered service starts; list any service and only the listed ones start — the behaviour existing partial configs already relied on.
  • The deprecated dashboard key shim stays: the rename it protects is still unreleased, so dropping it now would silently break v0.2.0 configs.

Protocol detection

  • normalizeServiceID 248 → 133 lines. 79 of 117 case arms were identity mappings — but not simply redundant: they also lowercased their input, which default: return svc did not. The default now lowercases. Verified by asserting 385 labels (every case arm, every return value, uppercase variants, unmatched samples) map identically before and after. One arm, "simpleWorkflowService", could never match a switch on strings.ToLower.
  • serviceFromQueryRequest drops the Action-name whitelist: it only ran for a request with neither a SigV4 credential scope nor an iam/sts/sqs host prefix, and every SDK, the CLI, and Terraform sign their requests.

Weekly Smithy sync — was a no-op

  • download-smithy-models.sh skipped any model already on disk, and all 93 are committed, so the job re-ran codegen over unchanged inputs and found nothing every week. Its hand-maintained 40-line service list had drifted from upstream naming, so 14 entries (secretsmanager, logs, monitoring, events, route53, apigateway, ...) 404'd on every run. Verified against upstream: the committed sqs and kms models are stale.
  • The list is derived from the models present; the workflow passes --refresh; downloads go through a temp file so a failed fetch can no longer delete a committed model (the old code did rm -f on the destination); the change check moves to git status --porcelain, which git diff --quiet cannot do for a newly generated untracked package.
  • The models stay committed on purpose and the script now says why: BASE_URL tracks aws-sdk-go-v2 main, so they are the pin that makes make codegen reproducible and offline.
  • codegen gofmts its output, so a fresh make codegen is byte-identical to the committed tree. That exposed codegen resurrecting internal/generated/sts — 563 lines deleted in refactor: remove dead code and de-duplicate service boilerplate #91 and feat: Phase 1 AWS depth & stabilization for v1.0 #96 — as untracked files the diff check could not see. STS is now skipped.

CI / docs

  • CI ran go test ./internal/..., skipping cmd/devcloud, so the ServicePlugin conformance test that enforces the documented plugin contract never ran. Now ./....
  • The codegen diagram listed interface.go, serializer.go, deserializer.go as generated outputs; none exist, and README claimed codegen produces "serializers". Corrected — this was the source of a recurring misreading of internal/generated as scaffolding waiting to be filled in.

Not in this PR

internal/generated/ is 240,793 lines across 93 packages, of which 88 (224,650 lines) have no importer at all. I looked at whether that is pending implementation work rather than dead weight, and it is not:

  1. No wire glue is generated. parser.go parses httpLabel/httpHeader/httpQuery/httpPayload, but no generator or template reads those fields — only model.go and parser_test.go mention them. Providers get the raw *http.Request and parse map[string]any, so types.go and base_provider.go have nothing to connect to.
  2. errors.go is not adoptable as-is: 1,015 of 2,728 generated error types report HTTPStatus() 0.
  3. router.go is only meaningful for REST services: 34 of 92 packages have any non-empty URI pattern; the rest emit {Method: "", Pattern: ""} rows MatchOperation can never match.
  4. The project already chose two other mechanisms: roadmap Phase 1 records "dead scaffold code removed", and docs/crud-engine.md says the promotion path is "implement it as an explicit case in the service provider" — not the typed BaseProvider. Phase 2 is the IR/ModelSource refactor; no serializer work is planned.

Suggested follow-up, for a maintainer decision rather than this PR: generate router.go only, and only for the 34 services with real URI patterns; stop generating types.go/errors.go/base_provider.go; un-embed BaseProvider from bedrock (which never calls it) and efs. Roughly 209k lines, with codegen still driving everything actually consumed.

Test Plan

  • go build ./..., go vet ./..., go test ./... — green (./..., which now includes the conformance test).
  • golangci-lint run — 0 issues.
  • boto3 compatibility suite: 764 passed (DEVCLOUD_BIN=dist/devcloud pytest tests/compatibility/). This exercises the riskiest changes end to end — the derived service config (the server started from embedded defaults with no services block), protocol detection, and the StrParam rewrite across 23 services.
  • make codegen over all 93 models → git status clean, i.e. byte-identical to the committed tree.
  • normalizeServiceID rewrite checked by differential assertion over 385 labels.
  • Startup smoke test with admin.enabled: true and logging.format: json: 104 services initialise, the dashboard deprecation warning is emitted as JSON after logging is configured (confirming the fix: config warnings honor logging.format/level (#113) #119 guarantee survives without the buffer handler), /services and /logs respond, /metrics and /ws return 404, and data lands in ./data/<service>.
  • download-smithy-models.sh --refresh tested against upstream in a temp directory: updates real models, and a 404 leaves the existing file untouched.

Checklist

  • Self-reviewed the code
  • Added/updated tests
  • Lint/format passes (golangci-lint run)
  • Updated documentation (if applicable)
  • Added a Changie changelog fragment for user-facing changes (changie new, see docs/release.md) — or N/A (docs/tests/chore only)

A repo-wide over-engineering audit turned up surface that no code path can
reach and helpers copied per service.

Remove the GetMetrics/ServiceMetrics plugin API: 102 of 104 implementations
returned a zero-valued struct, and TotalRequests/ErrorCount were never
populated by anyone, so /devcloud/api/metrics reported zeros forever. The two
services that did fill ResourceCount (DynamoDB, Lambda) are unaffected in
practice — /devcloud/api/services already derives resource counts from
ListResources. The interface is still pre-1.0, so this is not a v1.x break.

Delete the generic shared.ResourceStore (114 lines plus 204 of tests): no
production caller ever used it, every service writes its own SQL. Its
shared.Scanner was a second declaration of the identical sqlite.Scanner, so
configservice now uses the latter.

Fold 23 copies of the same string-param accessor (strParam / strVal /
getString / str — three spellings, identical behaviour) into shared.StrParam,
point 10 per-service region constants at shared.DefaultRegion, and make
shared.DefaultAccountID mirror plugin.DefaultAccountID rather than repeat the
literal. Left alone deliberately: the per-service jsonError/jsonResponse
helpers, whose Content-Type differs by protocol (application/json vs
x-amz-json-1.0 vs 1.1), and the randHex/generateID variants, which produce
genuinely different id formats.

Merge the two mirror-image case-conversion walkers in shared into one
mapKeys(v, f) and move it to kafka, its only caller, with a test.
The embedded default config was 325 lines in which all 103 service entries
were byte-identical boilerplate: enabled plus data_dir ./data/<name>, with no
exceptions. Derive that instead. The services block is now optional and
authoritative — omit it and every registered service starts under
./data/<service>; list any service and only the listed ones start, which is
the behaviour existing partial configs already relied on. Startup iterates the
plugin registry rather than a config map, so a newly registered service no
longer needs a YAML entry to run.

Delete the event bus and the admin WebSocket at /devcloud/api/ws: nothing in
the binary ever called Publish, and main.go dropped the bus reference at the
call site, so the socket accepted connections and could never send a message.
The REST /devcloud/api/logs endpoint already serves the request log it was
meant to stream. This drops the gorilla/websocket dependency.

Replace the custom buffering slog.Handler (92 lines) with config warnings
returned as a []string and logged after setupLogging — same guarantee that
config-time warnings honour logging.format/level, without a bespoke handler.
The 'config file not found, using embedded defaults' notice is gone: it fired
on the zero-config happy path, and keeping it was the only reason the handler
existed.

Fold the two init loops, whose bodies were identical, into one closure. The
fixed initOrder stays: it encodes core-service-failure-is-fatal, not just the
iam-before-sts ordering.

Keep the deprecated 'dashboard' key shim — the rename it protects is still
unreleased, so dropping it now would silently break v0.2.0 configs.

Drop two of the LogCollector's three redundant size clamps, keeping the
divide-by-zero guard.
normalizeServiceID went 248 lines to 133. Of its 117 cases, 79 arms were
identity mappings (case "s3": return "s3") — but they were not simply
redundant: they also lowercased their input, which `default: return svc` did
not. The default now lowercases, which makes the identity arms genuinely dead
and is strictly better for unmatched names, since every registry key is
lowercase. The rewrite was verified by asserting that 385 labels (every case
arm, every return value, their uppercase variants, plus unmatched samples) map
identically before and after. One dead arm went too: "simpleWorkflowService"
could never match a switch on strings.ToLower.

serviceFromQueryRequest drops the Action-name whitelist. It only ran for a
request carrying neither a SigV4 credential scope nor an iam/sts/sqs host
prefix — and every AWS SDK, the CLI, and Terraform sign their requests. With
the whitelist gone the QueueUrl probe is also redundant, since it returned the
same value as the fallback, so the body argument and the net/url import go
with it.

Delete gateway/auth.go: ExtractAccountID read the Authorization header into
_, returned a constant, and had no callers.
download-smithy-models.sh skipped any model already on disk, and every model
is committed, so the weekly job re-ran codegen over unchanged inputs and found
nothing every week. Its hand-maintained 40-line SERVICES list had also drifted
from upstream naming, so 14 entries (secretsmanager, logs, monitoring, events,
route53, apigateway, autoscaling, dms, ...) 404'd on every run. Verified
against upstream: the committed sqs and kms models are stale.

The list is now derived from the models present, so it cannot drift; name a
service explicitly to add a new one. The workflow passes --refresh to
re-download, and downloads land through a temp file, so a failed fetch can no
longer delete or truncate a committed model — the previous code did rm -f on
the destination. The change check moves to git status --porcelain because
git diff --quiet cannot see a newly generated (untracked) package.

The models stay committed on purpose, and the script now says why: BASE_URL
tracks aws-sdk-go-v2 main, so they are the pin that makes `make codegen`
reproducible and offline. Only the weekly job refreshes them, which is what
turns an upstream API change into a reviewable model diff.

codegen now gofmts what it writes, so a fresh `make codegen` is byte-identical
to the committed tree instead of showing a whole-tree reformat. That made one
thing visible: codegen was resurrecting internal/generated/sts, 563 lines
deleted in #91 and #96 because STS is hand-written in internal/services/iam,
as untracked files the sync's diff check could not see. STS is now skipped; it
is Query-protocol, so it contributes nothing to the JSON-only CRUD registry.
The codegen diagram listed interface.go, serializer.go, and deserializer.go as
generated outputs. None of them exist, and README claimed codegen produces
"serializers". That is the source of a recurring misreading of
internal/generated as scaffolding waiting to be filled in: there is no
generated wire glue, providers parse the raw *http.Request themselves, so
types.go and base_provider.go have nothing to connect to and only router.go is
consumed today. Document the four files actually generated, and why the Smithy
models are committed.

Also drop the event bus and WebSocket sections, the GetMetrics contract row,
the /devcloud/api/metrics endpoint, and the auth.enabled key, all of which
describe code that no longer exists; and state that the services config block
is optional and authoritative.
CI ran go test ./internal/..., which skipped cmd/devcloud — so the
ServicePlugin conformance test over every registered service, the thing that
enforces the documented plugin contract, never actually ran. Use ./... .

`make stats` counted services by parsing the services block out of
default.yaml, which no longer lists them; count the service packages instead.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @skyoo2003, your pull request is larger than the review limit of 150000 diff characters

@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Dependency updates ci CI/CD workflows and scripts tests Test code and test infrastructure codegen Smithy codegen and generated code services AWS service implementations labels Jul 29, 2026
@sourcery-ai

sourcery-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This PR removes unused admin metrics/event bus infrastructure and related plugin API surface, consolidates duplicated helpers and constants, simplifies configuration loading/derivation, tightens protocol detection for SigV4/Query services, fixes and hardens the weekly Smithy model sync/codegen workflow, and updates CI, docs, and codegen to match actual usage, all with no intended change to the AWS API behaviour.

File-Level Changes

Change Details Files
Configuration loading and service enablement are refactored to derive defaults from code rather than a large static YAML, with env overrides producing warnings instead of ad-hoc logging.
  • Shrink internal/config/default.yaml to just server defaults, removing the explicit services list and auth block.
  • Introduce Config.Service(serviceID) to compute effective enabled/data_dir using an optional services block plus DEVCLOUD_SERVICES/DEVCLOUD_DATA_DIR.
  • Change Load and LoadOrDefault to return config warnings alongside Config, letting main log them after logging is configured.
  • Rework env overrides to compute an allowed-service set (with tier expansion) and baseDir, returning warnings for suspicious tokens.
  • Expand and restructure config tests around Service(), zero-config behaviour, authoritativeness of services block, DEVCLOUD_SERVICES filtering, and DEVCLOUD_DATA_DIR overriding.
internal/config/default.yaml
internal/config/config.go
internal/config/config_test.go
Gateway protocol detection is simplified: Query services rely on SigV4/host-based detection, and normalizeServiceID is reduced while preserving behaviour via differential tests.
  • Update DetectProtocol to pass only the *http.Request into serviceFromQueryRequest rather than parsing the body for Action names.
  • Rewrite serviceFromQueryRequest to derive the signing name from SigV4 scope, fall back to host prefix for iam/sts, and default to sqs for unsigned/unprefixed requests.
  • Trim normalizeServiceID cases by lowercasing once at the top and removing identity mappings that are now covered by the default branch; fix unreachable case for simpleWorkflowService.
  • Retain mapping coverage by asserting 385 labels behave identically before/after the rewrite (tests live elsewhere, but protocol.go changes are driven by them).
internal/gateway/protocol.go
Admin API and plugin interface drop unused metrics/event bus surface, retaining only resource listing and log collection, and removing gorilla/websocket.
  • Remove GetMetrics from ServicePlugin interface and delete its implementations across many service providers.
  • Remove /devcloud/api/metrics endpoints and associated aggregate/service metrics handlers from admin API.
  • Delete the in-memory event bus and WebSocket hub/handler, and stop wiring them from main; admin API is now pure REST.
  • Simplify main startup: remove buffer slog handler, use warnings returned from config parsing, and initialize services using Config.Service plus dependency-ordered init with fatal/non-fatal behaviour.
  • Drop gorilla/websocket from go.mod and related code/tests in admin and eventbus packages.
internal/plugin/plugin.go
internal/admin/api.go
internal/admin/api_test.go
cmd/devcloud/main.go
go.mod
go.sum
internal/admin/websocket.go
internal/admin/websocket_test.go
internal/eventbus/eventbus.go
internal/eventbus/eventbus_test.go
cmd/devcloud/buffer.go
cmd/devcloud/buffer_test.go
internal/gateway/router_test.go
internal/plugin/registry_test.go
Duplication across services and shared code is reduced by introducing shared.StrParam, shared.DefaultRegion, and moving key-mapping utilities into kafka.
  • Add shared.StrParam helper and replace local strParam/getString variants in multiple providers (glue, waf, sagemaker, ecs, route53resolver, athena, account, sqs, configservice, swf, pinpoint, account, dms, codeconnections, many others).
  • Consolidate default region constants by using shared.DefaultRegion (mirroring plugin.DefaultAccountID) in services that previously hard-coded "us-east-1".
  • Move camelCase/PascalCase key conversion logic out of internal/shared/response.go into internal/services/kafka/provider.go as mapKeys, toCamelCase, toPascalCase, and add tests for round-trip behaviour.
  • Remove unused shared.ResourceStore/shared.Scanner types and adjust configservice store to use sqlite.Scanner directly.
internal/shared/params.go
internal/shared/arn.go
internal/shared/response.go
internal/services/*/provider.go
internal/services/configservice/store.go
internal/services/kafka/provider.go
internal/services/kafka/provider_test.go
internal/shared/store.go
internal/shared/store_test.go
Smithy model download script and codegen pipeline are fixed to support refresh semantics, atomic downloads, gofmt of generated Go, and skipping hand-written services.
  • Rewrite scripts/download-smithy-models.sh to derive the service list from existing models (or CLI args), support a --refresh flag, download into temp files before overwriting, track update/failure counts, and avoid deleting committed models on failures.
  • Update smithy-sync workflow to call download-smithy-models.sh --refresh and to use git status --porcelain for change detection; run go test ./... instead of ./internal/... for codegen changes.
  • Introduce codegen.WriteGo to gofmt generated content before writing .go files, and use it for service generator outputs and crud registry.
  • Change cmd/codegen to skip generating packages for the hand-written sts provider and log that skip.
  • Adjust mediaconvert and other stores/providers that depended on hard-coded regions to use shared.DefaultRegion.
scripts/download-smithy-models.sh
.github/workflows/smithy-sync.yml
internal/codegen/generator.go
cmd/codegen/main.go
internal/services/mediaconvert/store.go
CI and documentation are aligned with the actual behaviour of tests, codegen outputs, and admin API surface.
  • Change CI workflow to run go test ./... so cmd/devcloud tests (including ServicePlugin conformance) execute in CI.
  • Update architecture and getting-started docs to remove references to interface.go/serializer.go/deserializer.go generated files and to document actual generated outputs (types.go/router.go/errors.go/base_provider.go).
  • Document that codegen does not generate serializers and that providers parse *http.Request directly, and that admin API is REST-only (no WebSocket), with logs endpoint parameters updated.
  • Update configuration documentation to describe the services block as optional/authoritative, remove auth.enabled references, and clarify DEVCLOUD_DATA_DIR and DEVCLOUD_SERVICES behaviour/warnings.
  • Add changelog fragments for Removed, Changed, and Fixed items describing dead-surface removal, config default behaviour, and Smithy-sync fixes.
.github/workflows/ci.yml
docs/architecture.md
docs/getting-started.md
docs/configuration.md
docs/troubleshooting.md
changes/unreleased/Removed-20260730-000000.yaml
changes/unreleased/Changed-20260730-000001.yaml
changes/unreleased/Fixed-20260730-000002.yaml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@skyoo2003 skyoo2003 self-assigned this Jul 29, 2026
A code review of the refactor commits on this branch turned up one behaviour
regression and four silent failures.

serviceFromQueryRequest dropped its Action fallback on the reasoning that every
SDK, the CLI, and Terraform sign their requests. They do — but the fallback only
ever ran for a request with neither a SigV4 credential scope nor an iam/sts/sqs
host prefix, and for those the function now returned "sqs" unconditionally: an
unsigned Action=GetCallerIdentity POST to a bare endpoint reached the SQS
provider. The existing Query tests set Host to iam./sts., so they never covered
the path they were meant to. The fallback is back, ordered after SigV4 and the
host prefix and matching on IAM entity substrings rather than the old 35-name
whitelist, which makes it shorter and wider — DeleteRole and ListPolicies were
both missing from that list. sqs stays the final default.

download-smithy-models.sh counted failures and exited 0, so the weekly sync
would regenerate from stale models, see no diff, and report a successful sync of
nothing — the same silent no-op the previous commit set out to fix. It now exits
1 when any download failed. Its model count also moves from `ls *.json` to find:
under set -euo pipefail a glob matching nothing made ls exit 2 and killed the
script just before it printed the summary.

The removed auth block is parsed again, only to warn. yaml.Unmarshal ignores
unknown keys, so an operator who wrote auth.enabled: true to require signature
validation got no warning that nothing checks signatures — the one deprecation
that must not be silent. Follows the dashboard key's one-release shim.

A services block is authoritative and Enabled is a plain bool, so a block that
lists a service without enabled: true starts zero services with nothing in the
log. main now warns when the active set is empty, which also covers a typo'd
DEVCLOUD_SERVICES. docs/configuration.md claimed enabled defaults to true; it
defaults to false and is required per entry.

Also: make stats counted service directories and reported 103, because STS lives
in internal/services/iam — count registry registrations instead, which gives the
104 README states. Finish the shared.StrParam de-duplication with
StrParamDefault, removing five more copies (29 call sites). Drop the
now-unreachable "simpleWorkflowService" case label, since the switch lowercases
its input. Stop copying the request body into a string to test for "Action=".
Merge the split import groups left in twelve providers. Isolate DEVCLOUD_* from
the process environment in the config tests, which otherwise fail on a machine
that exports them.

Left alone deliberately: the eleven services with no committed Smithy model
(account, cloudcontrol, dms, ...). The script takes an arbitrary MODELS_DIR and
must not know about internal/services; the invariant that every service package
has a model belongs in a codegen test. intParam stays duplicated — two of its
six copies differ in signature and integer width, so folding them would change
behaviour at the call site.
The fragments had grown into commit messages: line counts, per-service tallies,
and the reasoning behind each change. A CHANGELOG reader wants what changed and
why it mattered; the rest is already in git. Trimmed to one or two sentences
each, keeping every name a reader would grep for — config keys, endpoints,
package paths, operation names.
@skyoo2003
skyoo2003 merged commit 4fb3b19 into main Jul 30, 2026
8 checks passed
@skyoo2003
skyoo2003 deleted the refactor/over-engineering-audit branch July 30, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci CI/CD workflows and scripts codegen Smithy codegen and generated code dependencies Dependency updates documentation Improvements or additions to documentation services AWS service implementations tests Test code and test infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant