Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions agent-context/skills/metaobjects-audit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,28 @@ such, surfaced in the roadmap, but **non-failing** (the code works; the form is
- `@dbColumnType: uuid` where a native UUID type is actually wanted → **`field.uuid`**
(a distinct native type is a subtype, not a physical override). Keep `@dbColumnType:
uuid` ONLY for the deliberate string-over-uuid-column case.
- `@dbColumnType: timestamp_with_tz` (ADR-0036 Wave 2) → **drop it.** `field.timestamp` is
instant / timezone-aware **by default** now; the `timestamp_with_tz` column-type override
is **retired**. Timezone-awareness lives in `field.timestamp` + the `@localTime` opt-out.
- A bare `field.timestamp` that is **semantically a wall-clock value** (a store-open time, a
birthday-with-time, a recurring local schedule) → recommend **`@localTime: true`** (naive
`timestamp without time zone`), or confirm it is genuinely meant to be an instant. Default
`field.timestamp` is an instant; only flag when the field's meaning is clearly wall-clock.

**Custom-provider vocabulary (adopters who register their own types/attrs):** check
new/custom vocab against the ADR-0037 procedure (advisory) — e.g. *a custom subtype
that differs from an existing one only by a property should be an attribute, not a
subtype*; a string-shape validation (email/url) is an attribute (native type unchanged),
not a subtype. Recommend re-shaping against the ordered test.

**TODO — Wave-2/3 checks to add when the conventions merge (NOT yet active — these
tokens are pending ADR-0036 Wave 2/3 and not yet registered; do NOT flag adopters for
**TODO — Wave-3 checks to add when the conventions merge (NOT yet active — these
tokens are pending ADR-0036 Wave 3 and not yet registered; do NOT flag adopters for
them until merged):**

- `@dbColumnType: timestamp_with_tz` → **drop it** (timezone-aware is the
`field.timestamp` default) — *pending Wave 2/3*.
- A bare wall-clock `field.timestamp` meaning naive/local time → flag for the
forthcoming `@localTime` zone-flag attribute — *pending Wave 2/3, not yet active*.
- An author-supplied regex validating email / url shape → flag for the forthcoming
`@format` string-format attribute — *pending Wave 2/3, not yet active*.
`@format` string-format attribute — *pending Wave 3, not yet active*.
- A same-pair relationship needing a stable navigation name → flag for the forthcoming
`@relationName` attribute — *pending Wave 3, not yet active*.

---

Expand Down
20 changes: 17 additions & 3 deletions agent-context/skills/metaobjects-authoring/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ name package extends abstract overlay isArray children value
| `field.double` | float | |
| `field.boolean` | true/false | |
| `field.date` | calendar date | ISO 8601 `YYYY-MM-DD` on the wire |
| `field.timestamp` | instant | ISO 8601 with timezone on the wire |
| `field.timestamp` | instant (tz-aware) | ISO 8601 with timezone on the wire; `@localTime: true` for a naive wall-clock value |
| `field.decimal` | exact decimal | `@precision` / `@scale`; lossless money/quantity |
| `field.currency` | integer minor units | see Currency below |
| `field.enum` | string member | `@values` required; see Enum below |
Expand Down Expand Up @@ -183,13 +183,27 @@ Canonical form for common needs — reach for these before inventing anything:
| IDs / unique keys | `field.uuid` | native UUID; use `@dbColumnType: uuid` only to force a string-typed value over a uuid column on purpose |
| Money | `field.currency` | integer minor units; never a float |
| Closed set of symbols | `field.enum` | `@values` required |
| Instant / timestamp | `field.timestamp` | ISO 8601 with timezone on the wire |
| Instant / event time (created/updated) | `field.timestamp` | instant / tz-aware by default (Postgres `timestamptz`; native `Instant`/`DateTimeOffset`/aware `datetime`) |
| Naive wall-clock value (store-open time, birthday-with-time) | `field.timestamp` + `@localTime: true` | `timestamp without time zone` — opt out of zone-awareness only for a genuine wall-clock value |
| A list of anything | `isArray: true` | on the base subtype (e.g. `field.string` + `isArray`) — there is **no** array `@dbColumnType` (retired) |
| Long / unbounded text | bare `field.string` | add `@maxLength` only when you want `varchar(N)` |
| Nested structured value | `field.object` | `@objectRef` + `@storage` |
| Open JSON bag (no fixed shape) | `field.string` + `@dbColumnType: jsonb` | logical type stays string; column is jsonb |

<!-- TODO(ADR-0036 Wave 2/3): add @localTime / @format / @relationName guidance when merged -->
**Timestamps — instant by default, `@localTime` for naive wall-clock (ADR-0036 Wave 2).**
`field.timestamp` is **instant / timezone-aware by default** (Postgres `timestamptz`;
native `Instant` / `DateTimeOffset` / aware `datetime`) — use it for created/updated/event
times. Add **`@localTime: true`** only for a genuine naive wall-clock value (a store-open
time, a birthday-with-time, a recurring local schedule) → `timestamp without time zone`.
Never use `@dbColumnType: timestamp_with_tz` — it is **retired**; timezone-awareness now
lives in `field.timestamp` (instant by default) + the `@localTime` naive opt-out.

```json
{ "field.timestamp": { "name": "createdAt", "@required": true } }
{ "field.timestamp": { "name": "opensAt", "@localTime": true } }
```

<!-- TODO(ADR-0036 Wave 3): add @format (string-shape email/url) / @relationName guidance when merged -->

**Extending the metamodel (custom providers):** the same ordered test governs new
vocabulary you register. A would-be subtype that differs from an existing one only
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,28 @@ such, surfaced in the roadmap, but **non-failing** (the code works; the form is
- `@dbColumnType: uuid` where a native UUID type is actually wanted → **`field.uuid`**
(a distinct native type is a subtype, not a physical override). Keep `@dbColumnType:
uuid` ONLY for the deliberate string-over-uuid-column case.
- `@dbColumnType: timestamp_with_tz` (ADR-0036 Wave 2) → **drop it.** `field.timestamp` is
instant / timezone-aware **by default** now; the `timestamp_with_tz` column-type override
is **retired**. Timezone-awareness lives in `field.timestamp` + the `@localTime` opt-out.
- A bare `field.timestamp` that is **semantically a wall-clock value** (a store-open time, a
birthday-with-time, a recurring local schedule) → recommend **`@localTime: true`** (naive
`timestamp without time zone`), or confirm it is genuinely meant to be an instant. Default
`field.timestamp` is an instant; only flag when the field's meaning is clearly wall-clock.

**Custom-provider vocabulary (adopters who register their own types/attrs):** check
new/custom vocab against the ADR-0037 procedure (advisory) — e.g. *a custom subtype
that differs from an existing one only by a property should be an attribute, not a
subtype*; a string-shape validation (email/url) is an attribute (native type unchanged),
not a subtype. Recommend re-shaping against the ordered test.

**TODO — Wave-2/3 checks to add when the conventions merge (NOT yet active — these
tokens are pending ADR-0036 Wave 2/3 and not yet registered; do NOT flag adopters for
**TODO — Wave-3 checks to add when the conventions merge (NOT yet active — these
tokens are pending ADR-0036 Wave 3 and not yet registered; do NOT flag adopters for
them until merged):**

- `@dbColumnType: timestamp_with_tz` → **drop it** (timezone-aware is the
`field.timestamp` default) — *pending Wave 2/3*.
- A bare wall-clock `field.timestamp` meaning naive/local time → flag for the
forthcoming `@localTime` zone-flag attribute — *pending Wave 2/3, not yet active*.
- An author-supplied regex validating email / url shape → flag for the forthcoming
`@format` string-format attribute — *pending Wave 2/3, not yet active*.
`@format` string-format attribute — *pending Wave 3, not yet active*.
- A same-pair relationship needing a stable navigation name → flag for the forthcoming
`@relationName` attribute — *pending Wave 3, not yet active*.

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ name package extends abstract overlay isArray children value
| `field.double` | float | |
| `field.boolean` | true/false | |
| `field.date` | calendar date | ISO 8601 `YYYY-MM-DD` on the wire |
| `field.timestamp` | instant | ISO 8601 with timezone on the wire |
| `field.timestamp` | instant (tz-aware) | ISO 8601 with timezone on the wire; `@localTime: true` for a naive wall-clock value |
| `field.decimal` | exact decimal | `@precision` / `@scale`; lossless money/quantity |
| `field.currency` | integer minor units | see Currency below |
| `field.enum` | string member | `@values` required; see Enum below |
Expand Down Expand Up @@ -183,13 +183,27 @@ Canonical form for common needs — reach for these before inventing anything:
| IDs / unique keys | `field.uuid` | native UUID; use `@dbColumnType: uuid` only to force a string-typed value over a uuid column on purpose |
| Money | `field.currency` | integer minor units; never a float |
| Closed set of symbols | `field.enum` | `@values` required |
| Instant / timestamp | `field.timestamp` | ISO 8601 with timezone on the wire |
| Instant / event time (created/updated) | `field.timestamp` | instant / tz-aware by default (Postgres `timestamptz`; native `Instant`/`DateTimeOffset`/aware `datetime`) |
| Naive wall-clock value (store-open time, birthday-with-time) | `field.timestamp` + `@localTime: true` | `timestamp without time zone` — opt out of zone-awareness only for a genuine wall-clock value |
| A list of anything | `isArray: true` | on the base subtype (e.g. `field.string` + `isArray`) — there is **no** array `@dbColumnType` (retired) |
| Long / unbounded text | bare `field.string` | add `@maxLength` only when you want `varchar(N)` |
| Nested structured value | `field.object` | `@objectRef` + `@storage` |
| Open JSON bag (no fixed shape) | `field.string` + `@dbColumnType: jsonb` | logical type stays string; column is jsonb |

<!-- TODO(ADR-0036 Wave 2/3): add @localTime / @format / @relationName guidance when merged -->
**Timestamps — instant by default, `@localTime` for naive wall-clock (ADR-0036 Wave 2).**
`field.timestamp` is **instant / timezone-aware by default** (Postgres `timestamptz`;
native `Instant` / `DateTimeOffset` / aware `datetime`) — use it for created/updated/event
times. Add **`@localTime: true`** only for a genuine naive wall-clock value (a store-open
time, a birthday-with-time, a recurring local schedule) → `timestamp without time zone`.
Never use `@dbColumnType: timestamp_with_tz` — it is **retired**; timezone-awareness now
lives in `field.timestamp` (instant by default) + the `@localTime` naive opt-out.

```json
{ "field.timestamp": { "name": "createdAt", "@required": true } }
{ "field.timestamp": { "name": "opensAt", "@localTime": true } }
```

<!-- TODO(ADR-0036 Wave 3): add @format (string-shape email/url) / @relationName guidance when merged -->

**Extending the metamodel (custom providers):** the same ordered test governs new
vocabulary you register. A would-be subtype that differs from an existing one only
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,28 @@ such, surfaced in the roadmap, but **non-failing** (the code works; the form is
- `@dbColumnType: uuid` where a native UUID type is actually wanted → **`field.uuid`**
(a distinct native type is a subtype, not a physical override). Keep `@dbColumnType:
uuid` ONLY for the deliberate string-over-uuid-column case.
- `@dbColumnType: timestamp_with_tz` (ADR-0036 Wave 2) → **drop it.** `field.timestamp` is
instant / timezone-aware **by default** now; the `timestamp_with_tz` column-type override
is **retired**. Timezone-awareness lives in `field.timestamp` + the `@localTime` opt-out.
- A bare `field.timestamp` that is **semantically a wall-clock value** (a store-open time, a
birthday-with-time, a recurring local schedule) → recommend **`@localTime: true`** (naive
`timestamp without time zone`), or confirm it is genuinely meant to be an instant. Default
`field.timestamp` is an instant; only flag when the field's meaning is clearly wall-clock.

**Custom-provider vocabulary (adopters who register their own types/attrs):** check
new/custom vocab against the ADR-0037 procedure (advisory) — e.g. *a custom subtype
that differs from an existing one only by a property should be an attribute, not a
subtype*; a string-shape validation (email/url) is an attribute (native type unchanged),
not a subtype. Recommend re-shaping against the ordered test.

**TODO — Wave-2/3 checks to add when the conventions merge (NOT yet active — these
tokens are pending ADR-0036 Wave 2/3 and not yet registered; do NOT flag adopters for
**TODO — Wave-3 checks to add when the conventions merge (NOT yet active — these
tokens are pending ADR-0036 Wave 3 and not yet registered; do NOT flag adopters for
them until merged):**

- `@dbColumnType: timestamp_with_tz` → **drop it** (timezone-aware is the
`field.timestamp` default) — *pending Wave 2/3*.
- A bare wall-clock `field.timestamp` meaning naive/local time → flag for the
forthcoming `@localTime` zone-flag attribute — *pending Wave 2/3, not yet active*.
- An author-supplied regex validating email / url shape → flag for the forthcoming
`@format` string-format attribute — *pending Wave 2/3, not yet active*.
`@format` string-format attribute — *pending Wave 3, not yet active*.
- A same-pair relationship needing a stable navigation name → flag for the forthcoming
`@relationName` attribute — *pending Wave 3, not yet active*.

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ name package extends abstract overlay isArray children value
| `field.double` | float | |
| `field.boolean` | true/false | |
| `field.date` | calendar date | ISO 8601 `YYYY-MM-DD` on the wire |
| `field.timestamp` | instant | ISO 8601 with timezone on the wire |
| `field.timestamp` | instant (tz-aware) | ISO 8601 with timezone on the wire; `@localTime: true` for a naive wall-clock value |
| `field.decimal` | exact decimal | `@precision` / `@scale`; lossless money/quantity |
| `field.currency` | integer minor units | see Currency below |
| `field.enum` | string member | `@values` required; see Enum below |
Expand Down Expand Up @@ -183,13 +183,27 @@ Canonical form for common needs — reach for these before inventing anything:
| IDs / unique keys | `field.uuid` | native UUID; use `@dbColumnType: uuid` only to force a string-typed value over a uuid column on purpose |
| Money | `field.currency` | integer minor units; never a float |
| Closed set of symbols | `field.enum` | `@values` required |
| Instant / timestamp | `field.timestamp` | ISO 8601 with timezone on the wire |
| Instant / event time (created/updated) | `field.timestamp` | instant / tz-aware by default (Postgres `timestamptz`; native `Instant`/`DateTimeOffset`/aware `datetime`) |
| Naive wall-clock value (store-open time, birthday-with-time) | `field.timestamp` + `@localTime: true` | `timestamp without time zone` — opt out of zone-awareness only for a genuine wall-clock value |
| A list of anything | `isArray: true` | on the base subtype (e.g. `field.string` + `isArray`) — there is **no** array `@dbColumnType` (retired) |
| Long / unbounded text | bare `field.string` | add `@maxLength` only when you want `varchar(N)` |
| Nested structured value | `field.object` | `@objectRef` + `@storage` |
| Open JSON bag (no fixed shape) | `field.string` + `@dbColumnType: jsonb` | logical type stays string; column is jsonb |

<!-- TODO(ADR-0036 Wave 2/3): add @localTime / @format / @relationName guidance when merged -->
**Timestamps — instant by default, `@localTime` for naive wall-clock (ADR-0036 Wave 2).**
`field.timestamp` is **instant / timezone-aware by default** (Postgres `timestamptz`;
native `Instant` / `DateTimeOffset` / aware `datetime`) — use it for created/updated/event
times. Add **`@localTime: true`** only for a genuine naive wall-clock value (a store-open
time, a birthday-with-time, a recurring local schedule) → `timestamp without time zone`.
Never use `@dbColumnType: timestamp_with_tz` — it is **retired**; timezone-awareness now
lives in `field.timestamp` (instant by default) + the `@localTime` naive opt-out.

```json
{ "field.timestamp": { "name": "createdAt", "@required": true } }
{ "field.timestamp": { "name": "opensAt", "@localTime": true } }
```

<!-- TODO(ADR-0036 Wave 3): add @format (string-shape email/url) / @relationName guidance when merged -->

**Extending the metamodel (custom providers):** the same ordered test governs new
vocabulary you register. A would-be subtype that differs from an existing one only
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,28 @@ such, surfaced in the roadmap, but **non-failing** (the code works; the form is
- `@dbColumnType: uuid` where a native UUID type is actually wanted → **`field.uuid`**
(a distinct native type is a subtype, not a physical override). Keep `@dbColumnType:
uuid` ONLY for the deliberate string-over-uuid-column case.
- `@dbColumnType: timestamp_with_tz` (ADR-0036 Wave 2) → **drop it.** `field.timestamp` is
instant / timezone-aware **by default** now; the `timestamp_with_tz` column-type override
is **retired**. Timezone-awareness lives in `field.timestamp` + the `@localTime` opt-out.
- A bare `field.timestamp` that is **semantically a wall-clock value** (a store-open time, a
birthday-with-time, a recurring local schedule) → recommend **`@localTime: true`** (naive
`timestamp without time zone`), or confirm it is genuinely meant to be an instant. Default
`field.timestamp` is an instant; only flag when the field's meaning is clearly wall-clock.

**Custom-provider vocabulary (adopters who register their own types/attrs):** check
new/custom vocab against the ADR-0037 procedure (advisory) — e.g. *a custom subtype
that differs from an existing one only by a property should be an attribute, not a
subtype*; a string-shape validation (email/url) is an attribute (native type unchanged),
not a subtype. Recommend re-shaping against the ordered test.

**TODO — Wave-2/3 checks to add when the conventions merge (NOT yet active — these
tokens are pending ADR-0036 Wave 2/3 and not yet registered; do NOT flag adopters for
**TODO — Wave-3 checks to add when the conventions merge (NOT yet active — these
tokens are pending ADR-0036 Wave 3 and not yet registered; do NOT flag adopters for
them until merged):**

- `@dbColumnType: timestamp_with_tz` → **drop it** (timezone-aware is the
`field.timestamp` default) — *pending Wave 2/3*.
- A bare wall-clock `field.timestamp` meaning naive/local time → flag for the
forthcoming `@localTime` zone-flag attribute — *pending Wave 2/3, not yet active*.
- An author-supplied regex validating email / url shape → flag for the forthcoming
`@format` string-format attribute — *pending Wave 2/3, not yet active*.
`@format` string-format attribute — *pending Wave 3, not yet active*.
- A same-pair relationship needing a stable navigation name → flag for the forthcoming
`@relationName` attribute — *pending Wave 3, not yet active*.

---

Expand Down
Loading
Loading