Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
161 commits
Select commit Hold shift + click to select a range
cb188a8
fix(apigateway): revert the snapshot version bump that discarded ever…
Aug 11, 2026
e448587
fix(ec2): error on an over-bound RunInstances count instead of silent…
Aug 11, 2026
c3d8440
build: add a diff-scoped lint gate so changes outside services/ stop …
Aug 11, 2026
6098648
fix(datasync): stop UpdateLocationNfs dropping ServerHostname
Aug 11, 2026
f735a8a
fix(databrew): reject CreateJob against a dataset, project or recipe …
Aug 11, 2026
973aa01
fix(workspaces): reject CreateWorkspaceBundle and CreateWorkspaceImag…
Aug 11, 2026
3ab51d4
docs: bring guardduty's PARITY.md back in line with what the code act…
Aug 11, 2026
572c89e
test(apigatewayv2): pin the basepath route-key transforms for ImportA…
Aug 11, 2026
4983d44
fix(datasync): stop UpdateLocationSmb and UpdateLocationObjectStorage…
Aug 11, 2026
b468280
fix(workspaces): reject CopyWorkspaceImage and CreateUpdatedWorkspace…
Aug 11, 2026
29d3136
fix(gendocs): stop silently dropping PARITY.md entries whose key is n…
Aug 11, 2026
3f88750
docs: rename the PARITY.md keys gendocs could not parse
Aug 11, 2026
0573045
feat(elasticache): model the six fields the SDK added since the audit…
Aug 11, 2026
1bc24d3
docs: regenerate READMEs after the PARITY.md key renames and the elas…
Aug 11, 2026
67a4a45
feat(cloudwatchlogs): model DestinationConfiguration.LookupTableConfi…
Aug 11, 2026
364d48e
fix(mediatailor,mediaconvert): stop dropping fields the SDK added aft…
Aug 11, 2026
c242bab
docs: regenerate READMEs for the cloudwatchlogs, mediatailor and medi…
Aug 11, 2026
64934a8
fix(gendocs): stop dropping a block entry whose key collides with a r…
Aug 11, 2026
94122f0
fix(ssoadmin,workspaces): model the fields the SDK added, and stop Mo…
Aug 11, 2026
18d2a67
docs: regenerate READMEs after the reserved-key parser fix and the ss…
Aug 11, 2026
15413eb
feat(organizations): populate Account.Paths and OrganizationalUnit.Path
Aug 11, 2026
a20eb5b
feat(neptune): thread NetworkType through clusters and instances
Aug 11, 2026
f973952
docs: regenerate READMEs for the neptune and organizations parity upd…
Aug 11, 2026
b4f91c2
feat(ssm): model AutomationExecution.WarningMessage on the wire, deli…
Aug 11, 2026
7b6f4ea
feat(transfer): thread IpAddressType through connectors and web-app V…
Aug 11, 2026
e10afa6
docs: regenerate READMEs for the ssm and transfer parity updates
Aug 11, 2026
ae77322
chore(beads): record this session's queue work and follow-ups
Aug 11, 2026
1c5923b
docs: refresh the session checkpoint for the follow-up queue branch
Aug 11, 2026
ac7c0e1
Merge remote-tracking branch 'origin/main' into chore/queue-2026-08-11
Aug 13, 2026
b0b4801
fix(beads): stop the blanket .beads/ ignore from blocking explicit gi…
Aug 13, 2026
1bf3568
chore(beads): close nejg and ky42
Aug 13, 2026
7a255f8
chore(beads): record the 7rq1 wire-field audit and split out its find…
Aug 13, 2026
47612a0
fix(ec2): size the outpost RunInstances reservation to the requested …
Aug 13, 2026
9902e86
feat(mediatailor): model HlsConfiguration.DualStackManifestEndpointPr…
Aug 13, 2026
1224bbc
chore(beads): close 2vgi and ic73
Aug 13, 2026
ae4d6f0
fix(workspaces): read ResourceId, not DirectoryId, on six Modify oper…
Aug 13, 2026
571dfb8
chore(beads): record the 9q6f query/XML audit and split out its findings
Aug 13, 2026
9a7ff65
fix(sesv2,awsconfig): model the required members these four ops never…
Aug 13, 2026
f5fc72e
chore(beads): close rcmn and m0ow
Aug 13, 2026
5b1d86a
fix(ec2,iam): read the wire keys these two operations actually receive
Aug 13, 2026
f1213c4
chore(beads): record the iam caller-identity limitation
Aug 13, 2026
4c0fec3
fix(s3,cloudfront,rds): read three request shapes the handlers never saw
Aug 13, 2026
3393d14
chore(beads): close difi and i101, file the cluster-role follow-up
Aug 13, 2026
a47392f
chore(beads): close b9mg as stale, file the outposts unskip follow-up
Aug 13, 2026
3eccaf7
fix(dms,ce): honour the Filters and SortBy members these ops silently…
Aug 13, 2026
3a81291
fix(sagemaker,athena,fsx,ecs): model seven request members and unskip…
Aug 13, 2026
1c1a040
chore(beads): close o53q, a8y0, cgq3, h0x1, vh89
Aug 13, 2026
dff699f
chore(beads): record the redshift-serverless audit and size the inlin…
Aug 13, 2026
246d197
chore(beads): record the zusp query-tail audit and split out its ten …
Aug 13, 2026
72903f3
fix(docdb,neptune,elbv2,ses): read the wire keys real clients actuall…
Aug 13, 2026
09cdb5f
chore(beads): close einq, file the docdb copy-paste follow-up
Aug 13, 2026
4c4efc6
fix(redshift): pin redshiftserverless and close nine serverless wire …
Aug 13, 2026
89726ec
fix(sts): enforce aws:MultiFactorAuthPresent on AssumeRole
Aug 13, 2026
86dbb0f
chore(beads): close 41fl, file the trust-policy fail-open finding
Aug 13, 2026
a772705
fix(docdb,elbv2): strip neptune's wire shape from docdb, wire the tru…
Aug 13, 2026
ea045ae
chore(beads): close xou3 and hl3h
Aug 13, 2026
0883bd0
fix(elasticache,ses): read the required list and flag members these o…
Aug 13, 2026
19dd6f5
chore(beads): close sro9 as premise-stale, file the audit-coverage pr…
Aug 13, 2026
fea0152
fix(sts): enforce Null and the Arn operators, and stop failing open s…
Aug 13, 2026
67d6361
fix(sagemaker): name the Domain/App/Space/UserProfile request structs…
Aug 13, 2026
9cd0313
chore(beads): record sagemaker inline-struct progress on oc9v
Aug 13, 2026
583c68f
feat(redshift): implement five Redshift Serverless operations, defer …
Aug 13, 2026
76b03b9
docs: regenerate READMEs and the operations badge
Aug 13, 2026
523c6b4
fix(iot): thread aggregation and update fields through the fleet-metr…
Aug 13, 2026
bd334b7
fix(docdb,neptune,elasticbeanstalk,elb): resolve nine ambiguous ignor…
Aug 13, 2026
dee1dd3
chore(beads): close uhsb
Aug 13, 2026
32613a1
chore(beads): file the required-member sweep findings and its unfinis…
Aug 13, 2026
2b6f45e
fix(bedrock,appstream): wire the required members these create ops di…
Aug 13, 2026
e5fbae2
fix(cloudfront): six ops were unreachable or silently discarding thei…
Aug 13, 2026
6613514
chore(beads): close nfka, file the discarded-unmarshal and route-mism…
Aug 13, 2026
4099a4f
chore(beads): close 4nek with a clean result, file its continuation a…
Aug 13, 2026
dd188b2
chore(beads): record required-member pass 2 and its eight findings
Aug 13, 2026
1a42028
fix(cloudfront,s3): three more whole-request wipes, two dead routes, …
Aug 13, 2026
99b79e3
chore(beads): close ob1g, file the cloudfront /config routes, qualify…
Aug 13, 2026
bfa4273
fix(bedrockagent,lightsail): model the real document identifier and c…
Aug 13, 2026
c503cfd
chore(beads): close wzwn and jigw, file the vacuous-test-fixture pattern
Aug 13, 2026
f36c23c
fix(cloudfront): 24 more unreachable operations, found by diffing all…
Aug 13, 2026
af19a32
chore(beads): close o31x, file the cloudfront residuals, record the r…
Aug 13, 2026
38d3ee9
fix(iam): four dropped required members, and a delegation family no a…
Aug 13, 2026
85d37ac
chore(beads): close oxuf, file the remaining delegation ops
Aug 13, 2026
00f9a47
fix(iam,cloudfront): finish the delegation family, correct three clou…
Aug 13, 2026
06df25e
chore(beads): close qb3x, file the cloudfront sibling and iam delegat…
Aug 13, 2026
0f7e9fd
chore(beads): record the vacuous-test hunt coming up empty
Aug 13, 2026
c8f5f8d
chore(beads): record required-member pass 3 and its seven findings
Aug 13, 2026
2b675f6
fix(quicksight,redshift): datasets get their tables, namespace regist…
Aug 13, 2026
939bce6
chore(beads): close 2qk4 and 3jqz, file the two redshift stubs
Aug 13, 2026
59a49be
fix(opensearch,lambda,route53): 35 unreachable operations, plus perma…
Aug 13, 2026
029a923
chore(beads): close l5ir, correct the 4nek false negative, file the p…
Aug 13, 2026
e56b745
fix(backup): route five operations that had handlers but no path
Aug 13, 2026
e3aec69
chore(beads): record route re-run pass 1
Aug 13, 2026
f5a241d
fix(macie2): route ListManagedDataIdentifiers, and lock six services …
Aug 13, 2026
058212d
chore(beads): record route re-run pass 2
Aug 13, 2026
d5b81fd
fix(securityhub,dms,workspaces,glue,rds): wire required members, and …
Aug 13, 2026
d334196
chore(beads): close u90v, record the fabricated-shape pattern
Aug 13, 2026
236d0a7
test: lock ten more services behind per-op SDK route tables
Aug 13, 2026
c4b2b75
chore(beads): record pass 3 and the tapering yield
Aug 13, 2026
9a5d435
fix(iam,cloudfront): drop a phantom field, correct two error codes an…
Aug 13, 2026
ea16f62
chore(beads): close xh42 and bhhx, record why the vacuous-test hunt c…
Aug 13, 2026
b88211d
fix(redshift,glue): implement two stubs and repair a response a real …
Aug 13, 2026
151c8d3
chore(beads): record required-member pass 4 and its thirty findings
Aug 13, 2026
be78976
fix(kinesis): rebuild three fabricated wire shapes, and one that was …
Aug 13, 2026
211258e
chore(beads): close nbg8, correct the kinesis attribution, note the o…
Aug 13, 2026
a2a589b
fix(lambda,opensearch,backup,ssm): five operations that could never w…
Aug 13, 2026
8b31dc6
chore(beads): close m53b, file the ssm ListNodes sibling
Aug 13, 2026
d353d14
chore(beads): file the response-member sweep findings and its unfinis…
Aug 13, 2026
0628bb6
fix(securityhub,cloudformation): six analytics ops and a handler impl…
Aug 13, 2026
91605ce
chore(beads): close jo2r and 66oz, record the both-directions pattern
Aug 13, 2026
979bf77
fix: thirteen required-member drops, and the larger bugs sitting behi…
Aug 13, 2026
093e06b
chore(beads): close 4ggy, file the organizations responsibility-trans…
Aug 13, 2026
0190c00
fix: wrong and missing response keys across seven services
Aug 13, 2026
9aba88d
chore(beads): record the lx5h fixes and the parked-agent process note
Aug 13, 2026
ea79bd3
fix(cleanrooms,wafv2,cloudwatch): sixteen wrong response keys, and wo…
Aug 13, 2026
baddbb7
chore(beads): close bv5d, record the three-layer shared-type class
Aug 13, 2026
c41d36c
fix(omics): resource-prefixed wire keys, and an id that is two keys d…
Aug 13, 2026
f1832bb
chore(beads): close lx5h and kb66, file the omics store and item-shap…
Aug 13, 2026
a82df36
fix(iam): use the real element name for ListPoliciesGrantingServiceAc…
Aug 13, 2026
a58220f
test(bedrock): integration coverage for the automated-reasoning-polic…
Aug 13, 2026
851feb7
test: integration coverage for six response-key fixes
Aug 13, 2026
c41d0ab
fix(organizations): model ResponsibilityTransfer, and stop one op imp…
Aug 13, 2026
c328195
chore(beads): close 0m6h, record the borrowed-behaviour variant
Aug 13, 2026
6922d78
fix: reject requests omitting required members, and one response nobo…
Aug 13, 2026
80f6a99
chore(beads): close wl0s, record the untested-inference lesson
Aug 13, 2026
8dc21e8
docs: rewrite the checkpoint around what this session learned
Aug 13, 2026
28aee02
fix(elasticsearch): one op returning another's response, and a VpcOpt…
Aug 13, 2026
0dc4446
chore(beads): close p2mx, correcting my own unverified premise
Aug 13, 2026
e688179
fix(omics,ssm): list responses that were too wide, and a node shape t…
Aug 13, 2026
1e78b7c
chore(beads): close 7s8r and 6uag, file the over-wide and empty-struc…
Aug 13, 2026
4c16d00
feat(cloudfrontkeyvaluestore): register the data plane as its own ser…
Aug 13, 2026
b458a35
chore(beads): close 4ara, file the snapshot-bump guard
Aug 13, 2026
904d6f5
test: refresh the snapshot-inventory golden, red since 4c0fec3bd
Aug 13, 2026
3d4b690
fix(iot,quicksight,backup): scope List responses, and two ops no clie…
Aug 13, 2026
c575c2c
chore(beads): close g3jk and k26u, file the iot GetCommandExecution gap
Aug 13, 2026
342eebe
fix(iot): resolve GetCommandExecution, unreachable despite a matching…
Aug 13, 2026
ccf799a
chore(beads): correct the route-guarantee claim, file the strengthening
Aug 13, 2026
9c2f8b1
test: correct two integration tests that encoded shapes fixed today
Aug 13, 2026
5bb28f1
chore(beads): record required-member pass 5 and its twenty-six findings
Aug 13, 2026
43f5d31
test: drive Handler() in 25 route tables, not just ExtractOperation
Aug 13, 2026
a469045
fix: five ops that dropped the field defining what they do
Aug 13, 2026
4898f59
chore(beads): correct the caller-identity premise across four issues
Aug 13, 2026
e7af1ba
chore(beads): file the pass-2 over-wide findings and three byproducts
Aug 13, 2026
de3ccfb
fix(personalize): scope all sixteen List responses to their real Summ…
Aug 13, 2026
42097cd
chore(beads): close sm02, record the standing-policy-note failure mode
Aug 13, 2026
f833df8
fix: nine required-member drops, and three wrong shapes behind them
Aug 13, 2026
58994c8
fix(glue,opensearch,medialive,bedrock,eks): scope seven List response…
Aug 13, 2026
fe5a199
chore(beads): close uult, correct two wrong findings in the over-wide…
Aug 13, 2026
b434d6b
fix(ecs,eventbridge,awsconfig): a wrong response shape, two epoch bug…
Aug 13, 2026
9fb5804
chore(beads): record the stale-SDK-comment variant
Aug 13, 2026
c76de68
fix(bedrock,medialive): five members that never arrived, and a field …
Aug 13, 2026
343d4ff
docs: refresh the checkpoint for the second half of the session
Aug 13, 2026
2094eff
chore(beads): close 45 issues whose fixes shipped but were never clos…
Aug 13, 2026
adb374d
fix(emrserverless,codeartifact,servicediscovery): scope six List resp…
Aug 13, 2026
333fa37
fix(appconfig): scope seven List responses, and correct the note that…
Aug 13, 2026
5be9121
chore(beads): close xs7l
Aug 13, 2026
04e216f
fix(cloudfront): stop TestFunction faking success, and scope ListDoma…
Aug 13, 2026
6614cd7
chore(beads): close 3izo
Aug 13, 2026
ca811c7
fix(bedrock): four ops that dropped their defining field, one unreach…
Aug 13, 2026
0134b84
chore(beads): close 4sov
Aug 13, 2026
95dc12e
chore(beads): manifest false-rationale sweep findings
Aug 13, 2026
e96ff85
fix(kms,cloudtrail): stop ListGrants returning a grant token, split t…
Aug 13, 2026
a0e5092
chore(beads): record 4gzs progress
Aug 13, 2026
6a435d4
fix(ssm): six List ops took an empty input struct and discarded real …
Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 3 additions & 3 deletions .badges/operations.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
147 changes: 123 additions & 24 deletions .beads/issues.jsonl

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ ui/.svelte-kit/
ui/build/
/dashboard/static/spa/*
!/dashboard/static/spa/.keep
.beads/
.beads/*
!.beads/issues.jsonl
.gemini/
.runtime/
CLAUDE.md
Expand Down
226 changes: 226 additions & 0 deletions CHECKPOINT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
# Checkpoint — wire-parity campaign, 2026-08-13

Branch `chore/queue-2026-08-11`, PR #2417 (draft). Merged `origin/main` early;
the only conflict was `.beads/issues.jsonl`, resolved with ours after checking
that no field on their side was newer.

Roughly 135 commits. 82 bd issues closed, 93 filed. Tree clean, all pushed,
full suite verified green.

## What this session actually was

The queue I was given had 8 items. Six of them turned out to be stale — already
fixed, or mis-stated. Verifying premises before dispatching (`gopherstack-9c4a`)
was the single highest-value habit of the session and should be the default.

The real work came out of two audits that the queue's item 4 asked for, which
between them generated more tracked work than they consumed. That is not a
failure — each bug found reliably revealed two adjacent ones — but it means the
queue does not converge. Expect to choose a stopping point rather than reach one.

## The cuts, ranked by what they actually yielded

| Cut | Services | Bugs | Notes |
|---|---|---|---|
| Required **input** members | ~150 over 6 passes | 77 | Best sustained yield by a wide margin. Every bug in an A-graded service. |
| Required **response** members | ~30 over 2 passes | 27 | Nothing forces an output field to exist — absent still returns 200. |
| **Over-wide** List responses | ~20 over 2 passes | 30 | Newest cut. 16 were one root cause in personalize. |
| Route reachability | 40+ | 47 | 41 in five services; the rest genuinely clean. |
| Vacuous-test hunt | ~70 | 0 | Failed as a hunt — see below. |

**Required members are where the bugs are.** A required member the handler never
reads means the operation cannot work for any real client, and that is almost
never defensible. Broad "absent field" sweeps produced 2,217 candidates and a
handful of bugs; filtering to required-ness produced 654 and dozens.

## Findings that generalise

**An A grade certifies op-level wire and routing, not field-level completeness.**
Confirmed independently six times. Every one of the 77 required-member bugs was
in a service graded A, most audited within the preceding three weeks. Re-auditing
a manifest *because* it looked complete found two client-breaking bugs.

**False rationales, ten instances, in four forms.** Five manifests positively
claimed verification that was false — redshift
("spot-checked: real state mutation confirmed", for two no-op stubs), kinesis
(`wire: ok` on three fabricated ops), quicksight ("import job lifecycle diffed
clean", for an import that imported nothing), securityhub (five ops emitting
unreadable keys), cleanrooms. Use `PARITY.md` to avoid re-deriving disclosed
gaps; never as evidence of correctness.

The other three forms are worse in ascending order. Three *code comments* argued
a field was absent for a reason that was untrue — kafka claimed AWS exposes no
rebalancing setting, and it does. One *standing policy note* in personalize's
`PARITY.md`, titled "Extra fields on List summaries are harmless", argued a true
premise to a wrong conclusion and thereby taught prior audits not to look — it is
why sixteen leaking ops survived. And one *upstream SDK doc comment* was stale:
the `pipes` module documents a field as ISO-8601 while its own deserializer parses
epoch seconds. **Cite the deserializer or serializer, never a field comment.**

**Borrowed shapes and behaviour — six distinct layers.** A shared response-key
*constant* correct for one op and wrong for its scoped sibling (cleanrooms, 4
ops); a shared XML *request type* (cloudfront); a shared *domain type* across
unrelated ops (cloudwatch's `AlarmContributor` carrying `InsightRuleContributor`'s
shape); a shared *list-item* shape where Start and Get genuinely differ (omics);
and an operation *reimplemented as a different operation* (organizations
`UpdateResponsibilityTransfer` was Accept/DeclineHandshake in disguise). When two
ops share a constant, struct or type, verify both against the SDK independently.
Plus a shared *Get-versus-List* converter, which produced 30 over-wide responses.
The resemblance that motivated the sharing is usually superficial — reasoning about
types by name or by analogy caused three near-misses that would each have
introduced a bug while fixing one.

**Read the whole operation, never just the reported field.** This produced extra
findings in *every* batch. The severest bug of the session — codecommit
`GetMergeConflicts` with `mergeable` hardcoded `false`, which would make any real
client refuse to merge — was found only because a *cosmetic* wrong-key fix put
someone in that handler.

**Audit field lists are a floor, not a ceiling — in both directions.** Undercounted in eight services
(backup 2-of-5, rekognition, organizations, dms, fsx, forecast, comprehend,
quicksight). Cause: a literal-match tool cannot distinguish a field read by the
*right* op from the same name read anywhere in the package. Per-op scoping via
the dispatch table would fix it and is worth building.

**When an audit says a gap is harmless *because of a pattern* rather than because
someone checked, that is an untested hypothesis.** `gopherstack-wl0s` was filed as
"round-trips fine, only presence unchecked" — inferred, not tested. One of its ops
wrapped its response under a key the real shape does not have, so nothing ever
reached a real client.

## Tests

**Seventeen tests were found wrong in the same direction as their bug**, two of
them in `test/integration`, which service-scoped work never runs. A test that
omits a field the handler also omits looks like a normal happy-path test. One
asserted status was in `200-299` *or* `400` — it could not fail. One called
`h.Handler()` directly, bypassing method-aware routing, so it could not catch a
routing bug. One was named `TestKBDocumentsRealWireRouting` and sent the invented
shape the handler expected.

**A dedicated hunt for these found zero**, while six more surfaced as a side
effect of fixing bugs. The signature is not in the test — it is the *agreement*
between test and handler, visible only once you know the correct behaviour. So
this is not a huntable backlog. It is a checklist item on every wire fix: when you
fix a handler, look at the nearest test and ask whether it agreed with the bug.

**The antidote is driving the real `aws-sdk-go-v2` client.** It builds what AWS
actually sends and cannot encode the handler's assumption. For a wrong response
key it is the *only* proof, since the SDK decodes nothing from an unrecognised key
whatever the raw body holds — a raw-map assertion passes against the bug.

## Tooling knowledge worth not re-deriving

The required-member scanners were rebuilt from scratch six times because the
scratchpad never survives. `gopherstack-569k` and `gopherstack-mven` carry the
full method. Five blind spots, each found the hard way:

1. lowerCamelCase `json:"fieldName"` tags rather than `.FieldName` accessors.
2. Case-insensitive matching (`Arn` vs `ARN`).
3. Tag-suffix tolerance — `json:"TermsId,omitempty"` does not contain `"TermsId"`.
4. Named-constant map keys — `resp[keyFoo]` where `const keyFoo = "Foo"`.
5. Nested XML path tags — `xml:"Parent>Child"`.
6. Dotted query prefixes — `vals.Get("Bundle.S3Bucket")` matches no pattern,
because the literal has a period where a comma or quote is expected.

Fixes 1–3 alone cut raw candidates from 391 to 176 across 135 services.
Check field **access**, not struct **declaration** — that closes the anonymous
inline-struct blind spot (`gopherstack-oc9v`, 1487 of them) for free.

Seven false-positive classes: httpLabel/httpHeader bindings (dominant, ~300+);
httpPayload wrappers (all 113 of pinpoint's); query-protocol member-indexed
arrays; idempotency tokens; disclosed stubs; and cross-package delegation
(`dynamodbstreams` forwards to `services/dynamodb`).

**Route tests are now permanent, and strengthened.** 26 services carry
`TestExtractOperation_SDKRouteTable` — one subtest per op, built from the SDK's
`serializeOpHttpBindings`. That converts a periodic audit into a standing
guarantee. Copy `services/opensearch/handler_paths_sdk_diff_test.go`.

They originally asserted only that `ExtractOperation` resolved the right name —
which is not the dispatch contract, so an op could resolve correctly and still be
unreachable. 25 now also drive `Handler()` and assert the response is not that
service's unmatched-route sentinel. `apigatewayv2` is deliberately excluded: its
route-miss reply is byte-identical to legitimate not-found responses, and an
unsound assertion would be worse than none.

## Decode regimes differ and change what counts as a bug

- stdlib `encoding/json`: case-**insensitive**, so case-only tag differences are
not bugs.
- `url.Values.Get` (query, ec2-query) and `encoding/xml`: case-**sensitive**, so
they are fatal. A root-element mismatch makes `xml.Unmarshal` error and zero the
*whole* struct — and 32 handlers discarded that error (`gopherstack-ob1g`).
- appstream decodes CBOR then bridges through `json.Unmarshal`, so it inherits
case-insensitivity. **cloudwatch hand-rolls CBOR extraction off a `cbor.Map`**
and is therefore case-sensitive — alone among the JSON-family services.

## Open decisions — human required

Three, and none is an agent's call.

- **`gopherstack-ylyb`** — CodeQL alert 254. Reviewed and technically sound, but
"false positive" undersells it: `v = g^x mod N` is stored at rest, so the
KDF-hardness CodeQL wants is genuinely absent. Inherent to SRP, identical in real
Cognito, unfixable without breaking wire compat. Recommendation: re-label
"won't fix". Dashboard state is the user's call.
- **`gopherstack-377m`** — repo-wide fail-open posture. sts trust-policy evaluation
permits on any unmodeled operator or unknown key. Now logs at WARN and enforces
`Null` and the `Arn*` family; `Numeric*`, `Date*`, `IpAddress` and `Binary` are
structurally unimplementable (no key of those types exists). A **second,
independent** fail-open path was then found: sts resolves `CallerArn` only for
callers that are themselves assumed-role sessions, so `aws:PrincipalArn` is
absent for every first-hop caller and the condition is skipped. Whatever posture
is chosen must cover absent-because-unresolvable, not just unmodeled.
- **`gopherstack-cu4g`** — caller-identity plumbing, and it explicitly defers to
`377m` on how absence should behave. Investigation corrected the premise: SigV4
parsing already exists, the access key is parsed in four places, and two
AKID-to-principal stores already work — the gap is plumbing, not resolution. Only
two of the four consumers I had cited are genuinely blocked.

## Process

- **Two agents ran `git stash push`** despite an explicit prohibition, while
another agent was mid-edit. Both scoped narrowly by luck; unscoped would have
destroyed parallel work. The prohibition must name `git stash push` and
`git checkout -- <file>` explicitly — a general "no git-mutating commands" is
not read as covering them.
- **One agent parked and looped**, finishing correct work then returning "waiting
for the monitor" three times. It burned ~346k tokens after finishing and had to
be killed with `TaskStop`. Its output was recovered by inspecting `git status`
and reading its `PARITY.md` diffs. **A parked agent leaves correct work looking
abandoned** — check the tree before assuming failure. Every dispatch now carries
an explicit "report, do not wait" instruction.
- **Scoped gates miss cross-cutting tests.** Verifying each change against only the
services it touched left the `pkgs/persistence` snapshot guard red for much of
the session, and left two `test/integration` tests encoding shapes that had been
fixed. One root cause, two symptoms. Run `./pkgs/...` alongside touched services,
and the integration suite before claiming green.
- **Check what a command actually measured.** A `go test ./... | head` pipeline
reported `exit: 0` from `head`, not from the test run. The real run failed. A
`grep -c "^ok"` returning zero should have been the tell.
- **Snapshot version bumps are a live data-loss hazard.** Two unnecessary bumps for
purely additive fields were caught in review this session (apigateway last
session, cloudfront this one); `Restore` discards *all* state on mismatch. A
guard exists in `pkgs/persistence` and works — it simply has to be run. Bump only
for an incompatible retype, as rds and directoryservice legitimately did.
- Integration tests need `make build-linux` plus a container; both were run green.
`test/terraform` still cannot run locally.

## Where to go next

Bounded and ready: `gopherstack-1jkv` (rds cluster roles, blocked on real-AWS
evidence), `gopherstack-a250` (56 empty-struct inputs, ~49 unverified),
`gopherstack-8kzr`-adjacent cleanups.

Open-ended, will not converge: `569k` (required inputs, six passes deep),
`mven` (required responses; ~120 services whole-directory scanned but never
per-op scoped, so unproven rather than clean), `dv4s` (over-wide responses,
newest and still productive), `jqh2` (routes; yield tapered 5→1→0),
`oc9v` (1487 inline structs, 343 in sagemaker alone), `xwkb` (make the sweep
tooling read `PARITY.md` so coverage gaps stop being miscounted).

Unresolved scope question: **quicksight (277 ops) and iot (272)** are the two
largest REST-JSON services and appear in neither the route tally nor its scope.
Both show signs of prior dedicated passes. Decide explicitly — letting them sit
in the gap is exactly how redshift-serverless escaped two sweeps at once.
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: build ui-install ui-lint ui-check ui-lint-fix ui-fmt ui-fmt-fix ui-test ui-build install-deps install-tofu lint lint-fix test integration-test terraform-test e2e e2e-test total-coverage clean demo all dev-mcp-install dev-mcp-check pgo docs check-pins
.PHONY: build ui-install ui-lint ui-check ui-lint-fix ui-fmt ui-fmt-fix ui-test ui-build install-deps install-tofu lint lint-changed lint-fix test integration-test terraform-test e2e e2e-test total-coverage clean demo all dev-mcp-install dev-mcp-check pgo docs check-pins

BINARY_NAME=gopherstack
VERSION_PKG=github.com/blackbirdworks/gopherstack/pkgs/version
Expand Down Expand Up @@ -132,6 +132,11 @@ lint: install-deps ui-lint ui-fmt ui-check
go vet -vettool=$$(go tool -n mulint-vet) ./...
go tool govulncheck ./...

# Lint + vet only the packages touched by the diff (working tree, or
# branch vs origin/main) instead of the whole repo -- see scripts/lint-changed.sh.
lint-changed:
@bash scripts/lint-changed.sh

lint-fix: install-deps ui-lint-fix ui-fmt-fix
@echo "Running fieldalignment..."
fieldalignment -fix ./...
Expand Down
Loading