&ND v2

+++document/meta
schemaVersion = "1"
id = "aeon-v1-parameterized-object-node-claims"
title = "Parameterized Object and Node Claims"
description = "Accepted informative design note recording the rationale and boundaries for parameterized object<T> and node<T> claims in AEON v1."
family = "aeon"
group = "Design Notes"
standing = "official"
lifecycle = "published"
normativity = "informative"
license = "CC-BY-4.0"
path = "specification/aeon-v1-documentation/parameterized-object-node-claims"
order = 80
publish = true
keywords = ["AEON", "object<T>", "node<T>", "generic claims", "design note", "container validation"]
related = ["aeon-core-v1-value-types", "aeon-core-v1-structure-syntax", "aeon-core-v1-compliance", "aeos-v1"]
+++


# Parameterized Object and Node Claims [# parameterized-object-and-node-claims]

The normative requirements live in the AEON v1 Value Types Reference, AEON v1 Structure Syntax Reference, AEON v1 Core
Compliance, and related appendices. This note records the rationale and boundaries.


## Purpose [# purpose]

AEON already supports parameterized container claims for lists and tuples:

~~~$ aeon
values:list<number> = [1, 2, 3]
point:tuple<number, number> = (144.9631, -37.8136)
~~~$

These claims are preserved by Core and enforced by schema, profile, convention, or consumer validation. Consolidated
AEON v1 extends the same surface to [$ object<T>] and [$ node<T>].


## [$ object<T>] [# object-t]

[$ object<T>] describes an object whose member values are expected to satisfy the given type claim.

~~~$ aeon
scores:object<number> = {
  alice:number = 10
  bob:number = 12
}
~~~$

Core preserves [$ object<number>] and validates only that the bound value is an object. It does not enforce member
values.


## [$ node<T>] [# node-t]

[$ node<T>] has two context-sensitive readings.

On ordinary bindings, it claims that the bound node value belongs to a profile, domain, or materialization target:

~~~$ aeon
doc:node<html> = <html(<head>, <body>)>
child:node<node> = <tag>
~~~$

Binding-side [$ node<T>] is deliberately narrower than node-head [$ node<T>].
The argument may be [$ node] itself or a custom profile/domain/materialization target such as [$ html].
Reserved non-[$ node] value datatypes are invalid on ordinary bindings:

~~~$ aeon
tag:node<string> = <tag>
~~~$

On node heads, it claims the expected type of that node's direct children:

~~~$ aeon
title:node = <title:node<string>("Hello world")>
~~~$

Core preserves the claim in both positions. It rejects reserved non-[$ node] binding-side arguments and does not
validate node-head children against [$ T].


## Non-Goals [# non-goals]

This does not introduce arbitrary generic reserved datatypes.

Invalid Core v1 examples remain invalid:

~~~$ aeon
number<cm> = 3
string<markdown> = "body"
<tag:pair<string, number>("x", 1)>
~~~$

The structural generic family described by this note is:

~~~$ text
list<T>
tuple<T...>
object<T>
node<T>
~~~$

Other limited parameterized reserved datatypes, such as absence and non-finite domain claims, are defined by the
value-types draft when present. They are outside this note's object/node scope.


## Validation [# validation]

Validation belongs above Core.

For example, AEOS can express object member intent with selectors:

~~~$ json
[
  { "path": "$.scores", "constraints": { "type": "ObjectNode", "datatype": "object<number>" } },
  { "selector": "$.scores.*", "constraints": { "type": "NumberLiteral" } }
]
~~~$

Node child intent can be expressed with SANSA selectors:

~~~$ json
[
  { "selector": "$.title.*", "constraints": { "type": "StringLiteral" } }
]
~~~$
