docs: stop the per-service pages promising the opposite of what the code does - #167
Merged
Merged
Conversation
…ode does
The five per-service pages were last touched on 2026-04-18. Four of them
describe a DevCloud that no longer exists, and they fail in the direction that
costs a reader the most: their "Known Limitations" lists deny features that are
now implemented, so someone reads "No batch operations" and writes the
workaround for a BatchWriteItem that has worked for months.
The operation tables are now derived from internal/generated/fidelity — the
hand-verified tier per service, which is the same source the coverage gates
read — rather than from memory:
- S3: 8 operations documented, 37 hand-verified. Multipart upload, CORS,
bucket policy, ACL, versioning, tagging, ListObjectsV2, CopyObject,
DeleteObjects and HeadBucket were all listed as absent.
- DynamoDB: 8 documented, 20 hand-verified. UpdateItem, batch, transactions,
GSI/LSI, streams, TTL, conditional writes and filter/projection expressions
were all listed as absent.
- Lambda: 6 documented, 25 hand-verified. Versions, aliases, event source
mappings and resource-based policies were all listed as absent.
- IAM/STS: 6 IAM operations documented, 58 hand-verified. Groups, inline
policies, instance profiles, tagging and the whole delete/update half of
the user and role lifecycle were listed as absent. STS was missing
GetAccessKeyInfo.
SQS is the one page that was already current and is untouched.
What replaces those lists is the limitation that is actually load-bearing, and
it is the same shape in three services: a sub-resource round-trips faithfully
and changes nothing. S3 stores a versioning status without assigning version
IDs, stores ACLs and bucket policies without ever denying a request, and stores
CORS without emitting a single Access-Control header. Lambda accepts a
resource-based policy it never evaluates. IAM stores policy documents nothing
parses. Each is now stated as "stored, not evaluated" where the operation is
listed, because a green response is exactly what makes it dangerous.
Two claims were wrong about the storage layer rather than the API surface:
- DynamoDB is SQLite, not BadgerDB. internal/storage/ contains only sqlite/
and badger appears in neither go.mod nor go.sum, so README.md,
configuration.md and contributing.md were pointing new service authors at a
dependency the tree does not have.
- configuration.md documented three config keys that do not exist:
services.lambda.runtime, services.lambda.warm_containers and
services.iam.enforce_policies. config.ServiceConfig has exactly two fields,
and parse() uses a non-strict yaml.Unmarshal, so writing one of those is
dropped in silence. That is the failure mode config.go already grew a
warning for on auth.enabled; the fix here is to stop advertising the keys
and say plainly that a knob outside the table does nothing.
Lambda's headline limitation survives unchanged because it is still true —
Invoke returns a fixed placeholder and the handler never runs. It is now stated
with the response body, since nothing in the shape of that reply distinguishes
it from a real one, and a test asserting on the status code alone passes
against code that did not execute. The event source mapping rows say what they
really do: the SQS and DynamoDB stream pollers run, build the AWS-shaped event
and POST it to that stub.
Numbers that a gate already owns were not touched. The 431/426 figures, the
fidelity shares and the 1,530-test suite were each re-derived and already
agreed with the binary.
skyoo2003
added a commit
that referenced
this pull request
Sep 13, 2026
…e fragments The 400-character ceiling was wide enough to hold two full sentences plus a subordinate clause, so it never pushed against the one-sentence rule it was meant to back — the #163 fragment reached 484 and still read as being in the spirit of the limit. At 200 the ceiling and the rule push the same way. Refits the eight unreleased fragments that were over. What came out is detail the linked issue already carries: the eight service names in #161, the CI-runner timing in #163, the DynamoDB and Lambda operation counts in #167. Also trims RELEASE.md's "right length" example, which was 203 characters and would have failed the limit the paragraph above it states, and labels both examples with their length.
5 tasks
skyoo2003
added a commit
that referenced
this pull request
Sep 13, 2026
…g to 200 (#168) * fix: give six changelog fragments the issue link the release tag checks Six fragments wrote `Issue:` at the top level instead of under `custom:`, where `.changie.yaml` declares it. `changie batch` rendered them as `[#<no value>](.../issues/<no value>)`, which release.yml:234 rejects — the tag would have failed at the notes-validation step, after the guardrails had already passed. The pre-flight grep in RELEASE.md (`grep -L 'Issue: "[0-9]'`) matches both spellings, so it did not catch this. Also trims the #163 fragment from 484 to 337 characters, under the 400-char ceiling `.changie.yaml` sets and `changie new` enforces on fragments it writes itself. The CI-runner timing detail it dropped is in the issue. * docs: correct the two protocol-table rows that miscount EC2 as having no model The protocol table said 12 services have no in-tree Smithy model and exactly one speaks a protocol the parser cannot read. Counted against internal/generated/fidelity/manifest_gen.go, it is 11 and two: `ec2` is model-backed but speaks `aws.protocols#ec2Query`, which parser.go:441-453 does not recognise alongside the five it does. That put the page at odds with fidelity-manifest.md:106 and compatibility-policy.md:78, which both say 11, and left a core service's missing engine coverage unexplained. Rows now sum to 431 either way, so the arithmetic did not expose it, and no test gates this table. Adds a paragraph separating what EC2 loses from what a registered-only service loses: EC2 is served by a hand-written provider and is not in the registered-only five, but its model-declared tail stays `unimplemented` rather than falling back to `auto-crud`. * docs: halve the changelog body ceiling to 200 characters and refit the fragments The 400-character ceiling was wide enough to hold two full sentences plus a subordinate clause, so it never pushed against the one-sentence rule it was meant to back — the #163 fragment reached 484 and still read as being in the spirit of the limit. At 200 the ceiling and the rule push the same way. Refits the eight unreleased fragments that were over. What came out is detail the linked issue already carries: the eight service names in #161, the CI-runner timing in #163, the DynamoDB and Lambda operation counts in #167. Also trims RELEASE.md's "right length" example, which was 203 characters and would have failed the limit the paragraph above it states, and labels both examples with their length.
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
The five per-service pages under
docs/services/were last touched on 2026-04-18. Four of them describe a DevCloud that no longer exists, and they fail in the direction that costs a reader the most: their Known Limitations lists deny features that are now implemented. Someone reads "No batch operations" and writes the workaround for aBatchWriteItemthat has worked for months.Operation tables are now derived from
internal/generated/fidelity— thehand-verifiedtier per service, the same source the coverage gates read — rather than from memory.Changes
Operation tables re-derived
s3.mddynamodb.mdlambda.mdiam-sts.mdGetAccessKeyInfosqs.mdwas already current and is untouched.Limitations rewritten around what is actually load-bearing
The same shape recurs in three services: a sub-resource round-trips faithfully and changes nothing. S3 stores a versioning status without assigning version IDs, stores ACLs and bucket policies without ever denying a request, and stores CORS without emitting an
Access-Control-*header. Lambda accepts a resource-based policy it never evaluates. IAM stores policy documents nothing parses. Each is now stated as stored, not evaluated at the operation that stores it — a green response is exactly what makes it dangerous.Lambda's headline limitation survives unchanged because it is still true:
Invokereturns a fixed placeholder and the handler never runs. It is now stated with the response body, since nothing in the shape of that reply distinguishes it from a real one and a test asserting on the status code alone passes against code that did not execute. The event source mapping rows say what they really do — the SQS and DynamoDB stream pollers run, build the AWS-shaped event, and POST it to that stub.Two storage-layer claims were wrong
internal/storage/contains onlysqlite/, andbadgerappears in neithergo.modnorgo.sum.README.md,docs/configuration.mdanddocs/contributing.mdwere pointing new service authors at a dependency the tree does not have.docs/configuration.mddocumented three config keys that do not exist —services.lambda.runtime,services.lambda.warm_containers,services.iam.enforce_policies.config.ServiceConfighas exactly two fields, andparse()uses a non-strictyaml.Unmarshal, so writing one of those is dropped in silence. That is the failure modeconfig.goalready grew a warning for onauth.enabled; this stops advertising the keys and says plainly that a knob outside the table does nothing.Files Changed
docs/services/s3.mddocs/services/dynamodb.mddocs/services/lambda.mddocs/services/iam-sts.mddocs/configuration.mddocs/contributing.mdREADME.mdTesting
go test ./cmd/devcloud/— green. The published-figure gates were re-run: 431/426, the fidelity shares and the 1,530-test suite each re-derived and already agreed with the binary, so no gated number was touched.make docs-build— green. 903 internal links across 24 pages all resolve.HandleRequestdispatch for behaviour,config.ServiceConfigfor config keys, andinternal/storage/plusgo.modfor backends.Related Issues
None.