feat: a documented default sends an attribute to optional and computed - #96
Merged
Merged
Conversation
An API that substitutes a value for an omitted field answers with that value whether or not the request carried one. Emitted as Optional alone, terraform holds null in config against a value in state and reports a diff on every plan, for a field the practitioner never set. A default declared on a request property is the document stating that fact, and joins the two routes already recognised. It is read from the write side only: a default on a response schema says nothing about what happens when a request omits the field. Presence is what counts, so a declared false or empty string states it as much as any other value. The risk this accepts is stated in docs/contract.md: a default on a $ref'd property is shared by every use of that type, so one declaration can move attributes that were never meant to move together. A correction is the remedy where it is wrong. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
mapping.md rows 3 and 10, and the headline figure in
handoff.md:29.The defect
An API that substitutes a value for an omitted field answers with that value
whether or not the request carried one. Emitted as
Optionalalone, terraformholds null in config against a value in state and reports a diff on every
plan, forever, for a field the practitioner never set.
docs/contract.md:172already said so — "emitting it asOptionalalone givesthe practitioner a perpetual diff" — and the ratio was 49 : 1 the wrong way.
A worked example
The document (
Tests_API_AgentToServerWritablePropertyFields):ThousandEyes substitutes
falsewhen the field is omitted, so the createresponse carries
falseeither way."network_measurements": schema.BoolAttribute{ Optional: true, + Computed: true, MarkdownDescription: "View packet loss in 1-second intervals. …", },Note the prose says nothing about a default. The signal is the
default:key,which nothing in the generation path read until now.
What changed
flatgainshasDefault, and the presence switch gains it as a third route toOptional+Computedbesidex-tfpfgen-server-defaultand the responseschema's
required.about what happens when a request omits the field.
default: false,default: 0anddefault: ""state it as much as any other value. The test covers all three.The risk, accepted deliberately
docs/contract.md:178previously rejected this route outright. That paragraph isrewritten rather than deleted, and keeps the objection as a stated risk: a
defaulton a$ref'd property is written onto a schema every other use of thattype shares, so one declaration can move attributes that were never meant to move
together. A correction is the remedy where it is wrong.
The trade is a defect in every plan against a risk in some.
Measured effect
604 attributes moved, and nothing else did.
computedandrequiredarebyte-identical before and after — that is the tight acceptance criterion for a
presence change.
optionalcomputed_optionalThe ratio
handoff.mdreports as 49 : 1 is now 3.9 : 1.Refusals unchanged on all three pilots — 817 / 290 / 343.
provider verifyreports no drift;
postcheckpasses.Deliberately not done
Default:. That changes apply semantics; mapping.md row 3asks for
Optional+Computed, not a default value.UseStateForUnknown(). Row 2 qualifies it with "only if stablepost-create", and stability is a volatility fact only the audit measures.
Gates
gofmt -l internal cmd— emptyscripts/repo_hygiene_gate.sh— passgolangci-lint run— 0 issuesgo build ./... && go vet ./...— passgo test ./...— pass, coverage 91.4% totalprovider generate+provider verifyon all three — no drift🤖 Generated with Claude Code