fix: a list result names the object by the key the resource is addressed by - #108
Merged
Conversation
…sed by A collection GET with no id in its path is a list resource wherever a resource of the same kind exists. Classification says so and derives 34 of them from ThousandEyes; emission served 11, and narrowed the rule for a difference in wording. A list result is an identity and an identity is the resource's id. The resource takes its id from the item path key where the object declares no property of that name — ensureID has always done this — but the list element did not, so an API spelling its key testId rather than id published no identity and lost the entity outright. Deriving the element's id the same way exposed a second refusal behind the first. An identity is the parents that scope an object plus its id, and the item path key is the id; counting it as addressing too required the same value under two names, of every import and of every list result, wherever the document also declared that key as a property. List resources go 73 to 98: ThousandEyes 11 to 30, GitHub 23 to 29, Jamf Pro unchanged. What still refuses names the key it looked for and the fields the element does carry, so the eleven that need the field named as data can be found without reading the toolkit. 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.
ThousandEyes emitted 35 resources and 11 list resources. The count was accurate;
the gap was a defect.
The rule, and where it was lost
A collection
GETwith no id in its path is a list resource wherever a resourceof the same kind exists.
classify.goimplements exactly that(
listOK := resourceOK && e.list != nil && e.list.SuccessSchema() != nil) andderives 34 for ThousandEyes. Emission served 11 and refused 23, narrowing a
classification rule from a stage that was never meant to decide it.
Defect one: the element had no id to publish
A list result is an identity, and an identity is the resource's id. The resource
takes its id from the item path key wherever the object declares no property of
that name —
ensureIDhas always done this, so/tests/{testId}gives theresource an
idreadingtestId.derive.listResourcenever called it, so theelement kept only the document's own spelling as
test_id, andfindIdentityNodelooked for a literalidand refused the entity.The split was exact, which is what confirmed it: 11 of 34 ThousandEyes
elements declared a literal
id, and 11 emitted. Every one of the other 23carried the key — as
testId,ruleId,dashboardId,snapshotId.Fixed by calling
ensureIDon the element with the same key the resource uses.Not a new rule; the rule the resource already follows, applied to the entity
that needs the same answer.
ensureIDreturns early when anidexists, so theentities that worked are untouched by construction.
Defect two, which the first was hiding
With the element publishing an identity, entities got one refusal further and
hit a second: "the list block cannot supply
rule_id, which the resource'sidentity names".
An identity is the parents that scope an object plus its id, and the item path
key is the id.
addressingNamescollected every path parameter includingthat one, so wherever a document also declared the key as a property —
/alerts/rules/{ruleId}beside aruleIdfield — the identity required thesame value under two names, of every import and of every list result. Only
resourceIdentitychanges; thejoinTreecallers still want the full set.Measured
All three trees regenerate, pass postcheck and report no drift under
provider verify:docs/emittance_tracker.mdis re-measured.What still refuses, and why it is data
Eleven entities across the three documents are one shape: the path spells the
key generically while the element names it specifically —
/roles/{id}besideroleId,/users/{id}besideuid,aid,groupId. No rule derives those.Taking the element's only id-shaped scalar would resolve some and silently pick
wrong on
dashboard, which carries four; a wrong identity lists the wrongobjects and says nothing.
So the refusal now names what it looked for and what the element does carry:
Naming the field as data — an
x-tfpfgen-*key on the list operation — is thefollow-up, and gated on the naming decision.
Verification
make checkpasses at 91.3%. New derivation tests cover an element keyed theAPI's way and one that declares its own
id; new emission tests cover theidentity being published from the element's own key, the refusal naming its
candidates, and the item key not doubling as addressing.
derive_test.gopassedthe 800-line ceiling, so the list-resource cases moved to
derive_list_resource_test.go.Both defects were found by regenerating the three documents, not by a test.
🤖 Generated with Claude Code