Skip to content

feat: an entity names the property that identifies it - #118

Merged
ShocOne merged 1 commit into
mainfrom
feat/an-entity-names-the-property-that-identifies-it
Aug 25, 2026
Merged

feat: an entity names the property that identifies it#118
ShocOne merged 1 commit into
mainfrom
feat/an-entity-names-the-property-that-identifies-it

Conversation

@ShocOne

@ShocOne ShocOne commented Aug 25, 2026

Copy link
Copy Markdown
Member

An API whose item path says {id} while its response spells the same identifier aid left the id attribute bound to an accessor no model has. The binding was pruned as addressing — correctly, by a premise that is false here:

Pruning removes their bindings correctly: no model carries them, because they address the object rather than describe it.joinTreeKeeping

The model does carry it, under another name. Nothing populated data.ID, so Read called ById("") and the settling read could never find the object.

Affected account_group, user, role, alert_suppression_window and templates_sharing_setting.

Why this needs an observation rather than a rule

The correspondence is stated nowhere in the document, and no naming rule finds it:

  • the audit's own identifierOf does not match aid — it isn't id, doesn't end _id, doesn't end Id
  • among the model's accessors, both GetAid and GetOrgId end in "id", so "the one ending in id" is ambiguous

It is learned instead by matching the id the run already extracted against the response body's own properties — evidence, not spelling. The run learns an id from a Location header or a self link as readily as from a body key, so neither name has to match the other.

The term

identifierProperty / x-tfpfgen-identifier-property, on the read operation. Both approved by the repository owner and recorded in docs/glossary.md.

Asserted only where the two disagree — an entity whose response spells it id needs no correction, and emitting one would state what the document already says.

Chain

Layer Change
observe kind + value validation
run/evidence identifyingProperty matches the learned id against the body; generalises idField, which previously recognised only the literal id key
infer emits the observation when it disagrees with id
revise/compile annotates the read operation; refuses a property the read response doesn't declare
specmodel parses the extension
derive ensureID takes that name over the path parameter's

Proven on the live document

With the correction in place, account_group — which previously emitted no data.ID assignment at all — now closes the loop:

created, err := client.AccountGroups().Post(ctx, body, nil)
data.ID = convert.APIToFrameworkString(created.GetAid())   // from the create
...
data.ID = convert.APIToFrameworkString(remote.GetAid())    // and from the read

make check green at 90.9%; the tree regenerates and passes postcheck.

🤖 Generated with Claude Code

An API whose item path says {id} while its response spells the same
identifier "aid" left the id attribute bound to an accessor no model has.
The binding was pruned as addressing — correctly, by a premise that is false
here: the model does carry it, under another name — and nothing populated
data.ID, so the settling read addressed the object by an empty string.

The correspondence is stated nowhere in the document, and no naming rule
finds it: the audit's own identifier rule does not match "aid" either, and
among the model's accessors both GetAid and GetOrgId end in "id". It is
learned instead by matching the id the run already extracted against the
response body's own properties, which is evidence rather than spelling. The
run learns an id from a Location header or a self link as readily as from a
body key, so neither name has to match the other.

The observation kind is identifierProperty, the extension key
x-tfpfgen-identifier-property on the read operation, both approved by the
repository owner and recorded in the glossary. It is asserted only where the
two disagree: an entity whose response spells it "id" needs no correction.

The same match generalises idField, which previously recognised only the
literal "id" key and is what excludes an identifier from the per-field
observations.

Proven against the live ThousandEyes document: with the correction in place
account_group derives its id as "aid", populates it from both the create
response and the read, and the entity that emitted no assignment at all now
closes the create-read-state loop.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ShocOne
ShocOne merged commit 76eca00 into main Aug 25, 2026
2 checks passed
@ShocOne
ShocOne deleted the feat/an-entity-names-the-property-that-identifies-it branch August 25, 2026 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant