Repository navigation
feat: measure demand for unregistered services, and re-scope the coverage target - #138
Merged
Merged
Conversation
…rage target
DevCloud aimed at every AWS service AWS publishes — 431 model files. That
target rested on an assumption nobody had tested: that the ~283 services it
does not register are services anyone wants. This tests it before the bulk
work is funded, and the assumption did not hold.
The three validation methods the PRD named — issue telemetry, a poll, gateway
instrumentation — all need calendar time this project does not control, and
Milestone 3 gates Milestones 4-6. So the work splits in two: build the
instrument, and take the verdict from demand evidence that already exists.
INSTRUMENT
The registry miss in ServeHTTP was already one branch; UnroutedCollector
hangs off it. A map, not LogCollector's ring buffer: a 100-entry ring
discards exactly the accumulation that makes this evidence. Nil-receiver
safe, so the miss branch stays one unconditional call and the
admin-disabled path costs nothing. Service IDs come from caller-controlled
headers, so keys are truncated at 64 bytes and capped, and the report
carries droppedServiceIds — an evidence structure that silently stopped
recording would read as complete.
GET /devcloud/api/unrouted, plus a "Service Not Supported" issue form that
asks for its output.
Ceiling, documented at the collector, in coverage.md, and in the issue
form: DetectProtocol falls through to ("rest-xml", "s3") for anything it
cannot classify, and s3 is registered, so unclassifiable traffic is never
counted. The endpoint reports a floor, not a census.
VERDICT
Decision rule with four outcomes fixed before the first fetch, including
one for "the method itself failed". Readings:
R1 missing set M 283
R2 M built by all three of moto/LocalStack/tf-aws 8
M built by at least two 57 (20.1%)
M built by none 115
R3 DevCloud's own service asks, all time 0
R4 instrument live, verified with boto3 yes
Outcome 3 fired (< 100 services with support >= 2): the 100% claim is
dropped from published docs before any bulk work. Published target is 205
services — 148 registered plus 57 with demonstrated demand. The remaining
226 are not refused; any can be onboarded on request. They are no longer
promised.
Two join bugs were fixed before the rule was read, because the verdict
deletes a published claim and a deflated count would have produced it
dishonestly: moto's "## Unimplemented:" section headings were counted as a
service, and separator-stripping alone does not resolve abbreviations (ds,
cur, elb, sdb name services in M; ce, logs, events, config name services
already registered). Unmatched names went 15/14/17 -> 0/4/4.
demand_rank.py is run by hand and never in CI, like
download-smithy-models.sh and for the same reason: the sources are
third-party and change under us. docs/demand.md is the evidence; the
script is how it is re-derived, byte-identical from the same inputs.
DOCS
README.md advertised 104 services and faq.md 101, against 148 registered;
fidelity-manifest.md also carried stale tier totals. Per the PRD's top
risk, no count now appears without its depth split — 148 registered, 117
serving at least one operation.
The verdict rests on a proxy: those three projects measure emulator effort,
not DevCloud's users. That is stated everywhere the number appears, and it
was the deliberate trade for not blocking on an unbounded wait. One real
service request outranks all three, and the instrument now accrues them.
Zero services onboarded — git diff --stat internal/services smithy-models is
empty, which is a check and not a description.
go test ./... green (110 packages); -race clean on admin and gateway;
golangci-lint 0 issues; 790 boto3 compat tests pass.
Refs: .claude/plans/aws-service-coverage-100-milestone-3.plan.md (Tasks 1-6)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
DevCloud's roadmap aimed at every AWS service AWS publishes — 431 model files. That target rested on an assumption nobody had tested: that the 283 services it does not register are services anyone wants. This PR tests the assumption before any bulk work is funded, ships the instrument that keeps measuring it, and applies the pre-registered decision rule. The assumption did not hold: the 100% target is dropped and the published target becomes 205 services.
Related Issue
Refs #
Milestone 3 of the AWS service coverage PRD (
.claude/prds/aws-service-coverage-100.prd.md, gitignored). Follows #136 (Milestone 1 — onboarding cost) and #137 (Milestone 2 — one category end to end).Changes
The instrument
internal/admin/unrouted.go—UnroutedCollectorcounts requests for services the gateway does not register. A map rather thanLogCollector's ring buffer: a 100-entry ring discards exactly the accumulation that makes this evidence. Nil-receiver safe, so the miss branch stays one unconditional call and the admin-disabled path costs nothing.internal/gateway/router.go— one line on the!okbranch that already existed. Nothing needed re-plumbing.GET /devcloud/api/unrouted— per-service count, first seen, last seen. Requiresadmin.enabled: true..github/ISSUE_TEMPLATE/service_request.yml— "Service Not Supported", asks which operations you actually call and takes the endpoint output.Service IDs come from caller-controlled headers, so keys are truncated at 64 bytes and capped, and the report carries
droppedServiceIds. An evidence structure that silently stopped recording would read as complete.Two ceilings, documented at the collector, in
docs/coverage.md, and in the issue form:DetectProtocolfalls through to("rest-xml", "s3")for anything it cannot classify, ands3is registered — so unclassifiable traffic is never counted. The endpoint reports a floor, not a census. And a non-zerodroppedServiceIdsmeans the list is incomplete.The verdict
Four outcomes were fixed before the first fetch, including one for "the method itself failed", so the result could not be argued into whichever answer was most convenient once it arrived.
MMbuilt by all three of moto / LocalStack / terraform-provider-awsMbuilt by at least twoMbuilt by noneSource sizes: moto 163, LocalStack 119, terraform-provider-aws 273.
Outcome 3 fired (fewer than 100 services with support ≥ 2). Per the rule written in advance: the 100% claim is dropped from published docs before any bulk work, and the published target becomes the demand set.
Published target: 205 services = 148 registered + 57 with demonstrated demand. The other 226 are not refused — any can be onboarded on request, and one real service request outranks all three proxies — but they are no longer promised.
scripts/demand_rank.py— stdlib only, run by hand and never in CI, likedownload-smithy-models.shand for the same reason: the sources are third-party and change under us. Exits non-zero on an empty source rather than writing a file that silently under-counts.docs/demand.md— the committed evidence: 283 ranked rows with per-source hits. Byte-identical on re-run from the same inputs.docs/coverage.md— the target and the rule that set it, on the same page.Two join bugs were found and fixed before the rule was read, because the verdict deletes a published claim and a deflated count would have produced it dishonestly:
## Unimplemented:section headings were counted as a service.ds,cur,elb,sdbandmeteringmarketplacename services inM;ce,logs,events,configand nine others name services already registered.Unmatched names went 15/14/17 → 0/4/4. The residue is exactly the four services these projects support that AWS publishes no model for (
elastictranscoder,qldb,iotanalytics,evidently) — deliberately left unmatched, since mapping them would invent demand for a service that is not in the denominator.Stale counts
README.mdadvertised 104 services anddocs/faq.md101, against 148 registered;docs/fidelity-manifest.mdalso carried stale per-tier operation totals. Per the PRD's top risk — "431 services is read as a capability claim, then a user finds most operations are stubs" — no count now appears without its depth split: 148 registered, 117 serving at least one operation.Zero services onboarded.
git diff --stat internal/services smithy-modelsis empty. That is a check, not a description.Files Changed
internal/admin/unrouted.gointernal/admin/unrouted_test.goscripts/demand_rank.pydocs/demand.md.github/ISSUE_TEMPLATE/service_request.ymlchanges/unreleased/*.yamlinternal/gateway/router.gointernal/gateway/gateway.goNewtakes the collector, nil-ableinternal/admin/api.goGET /devcloud/api/unroutedcmd/devcloud/main.gointernal/{admin,gateway}/*_test.godocs/coverage.mdREADME.md,docs/{README,faq,fidelity-manifest,services-matrix,compatibility-policy}.mdTest Plan
14 new tests. The two that carry the behaviour:
TestServiceRouter_RecordsUnroutedService(a miss is counted) andTestServiceRouter_DoesNotRecordRoutedService(a served call is not — otherwise every DevCloud looks like it is missing everything it has).R4, against the built binary with
admin.enabled: true:The registered DynamoDB call is absent, as required. Then with a real boto3 client:
boto3.client("appflow").list_connector_entities()records asappflow— the canonical service ID, via the SigV4 signing name. That is the population that matters.Known limitation
The verdict rests on a proxy. moto, LocalStack and terraform-provider-aws measure emulator and provider effort, not DevCloud's users. This is stated everywhere the number appears —
docs/demand.md,docs/coverage.md, the PRD — and it was the deliberate trade for not blocking Milestones 4–6 on an unbounded wait for organic signal. The real measurement now accrues behind it, and either channel can reopen the target.R3 = 0is recorded as a finding, not a missing measurement. It is the expected value for a project with no telemetry and two issues, and it is exactly why the proxies carried the verdict.Checklist
golangci-lint run— 0 issues)