You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 999269c
Browse filesBrowse the repository at this point in the historyBrowse files
docs(agent-context): harden skills for ADR-0039 own-accessor discipline (#137)
Teach the agent-context skills that own*() accessors break extends
inheritance and must not be the default — resolving/effective accessors
are the default everywhere.
- codegen skill: prominent rule + per-port own↔resolving mapping table +
the Python(attr=own)/TS(attr=resolves) naming inversion; own is only for
emitting a generated subclass's own members (ownFields).
- authoring skill: brief reinforcement for adopters writing custom
generators/providers — extends-inherited properties are real; consume
via resolving accessors, never own*().
- audit skill: new axis G2 active check (correctness defect, not advisory)
flagging own-only reads of effective properties / own-only member
iteration in generators + runtime paths, with the sanctioned
subclass-emit / own-serializer / @dbColumnType exceptions; plus a drift
signature entry.
Regenerated the agent-context conformance goldens; conformance (4/4),
drift (4/4), and capability-grounding (5/5) gates all green.
Claude-Session: https://claude.ai/code/session_01GF9xLEQZaPus5Y6opk398n
Co-authored-by: Doug Mealing <noreply@anthropic.com>
5.**Runtime schema patching** (`ALTER TABLE … ADD COLUMN IF NOT EXISTS`, `_ensure_schema()`) — N schema owners.
174
202
6.**N declarations of one shape** — same entity as Drizzle table + Zod schema + Pydantic model + hand dataclass; target is 1 + N generated.
203
+
7.**`own*()` accessor read of an effective property** (ADR-0039) — `ownAttr` / `ownFields` / `own_children` / bare Python `attr(` / `getMetaAttr(name, false)` / native `IsArray` used to read a value or iterate members outside the sanctioned subclass-emit / own-serializer / `@dbColumnType` cases → silently drops `extends`-inherited values. A **correctness defect** (axis G2), not advisory.
Copy file name to clipboardExpand all lines: fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.claude/skills/metaobjects-audit/SKILL.md
+30-1Lines changed: 30 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -69,7 +69,35 @@ code behind a grep hit; a "duplicate" validator's *divergence* is the finding.
69
69
(ADR-0019); runtime reflection to resolve a type from FQN vs generated static imports /
5.**Runtime schema patching** (`ALTER TABLE … ADD COLUMN IF NOT EXISTS`, `_ensure_schema()`) — N schema owners.
174
202
6.**N declarations of one shape** — same entity as Drizzle table + Zod schema + Pydantic model + hand dataclass; target is 1 + N generated.
203
+
7.**`own*()` accessor read of an effective property** (ADR-0039) — `ownAttr` / `ownFields` / `own_children` / bare Python `attr(` / `getMetaAttr(name, false)` / native `IsArray` used to read a value or iterate members outside the sanctioned subclass-emit / own-serializer / `@dbColumnType` cases → silently drops `extends`-inherited values. A **correctness defect** (axis G2), not advisory.
Copy file name to clipboardExpand all lines: fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.claude/skills/metaobjects-authoring/SKILL.md
+10Lines changed: 10 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -540,6 +540,16 @@ Resolution facts:
540
540
541
541
`abstract`and `extends` are **structural keys** (bare, no `@`).
542
542
543
+
**Extends-inherited properties are real — consume metadata through the resolving
544
+
accessors (ADR-0039).** If you write a custom generator or a metamodel provider that
545
+
reads this metadata, a concrete field/entity's inherited attributes and members live
546
+
on the parent it `extends`, not on the node itself (extends is a super-*reference*, not
547
+
a flatten). Always read a property or iterate a member set via the **resolving/effective**
548
+
accessor (TS `attr()`/`children()`/`fields()`, Python `attrs().get()`), **never an
549
+
`own*()`accessor** — an own-only read silently drops everything inherited via `extends`
550
+
and corrupts the generated code. See the `metaobjects-codegen` skill for the full
551
+
per-port mapping.
552
+
543
553
**`overlay` is a different concept.** `extends:` is an IS-A relationship between
544
554
two distinct nodes. `overlay: true` re-opens the *same* named node to amend it
545
555
across files (same `package` + same `name` → merged; last-writer-wins on attr
Copy file name to clipboardExpand all lines: fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.claude/skills/metaobjects-codegen/SKILL.md
+38Lines changed: 38 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -132,6 +132,44 @@ the `generators` array in `metaobjects.config.ts` next to the built-ins — it r
132
132
the same pass, writes under the same target rules, and carries the `@generated`
133
133
header so it round-trips like any other.
134
134
135
+
### Never read metadata through an `own*()` accessor (ADR-0039) — top bug source
136
+
137
+
When writing OR reviewing a generator, **read every field/node property and iterate
138
+
every member set through the resolving/effective accessor — never the `own*()` form.**
139
+
`extends` is a **super-reference, not a flatten**: a concrete field/entity that
140
+
`extends` an abstract parent keeps its inherited attributes and members physically on
141
+
the parent, reachable only through the *resolving* accessor. An `own*()` read of an
5.**Runtime schema patching** (`ALTER TABLE … ADD COLUMN IF NOT EXISTS`, `_ensure_schema()`) — N schema owners.
174
202
6.**N declarations of one shape** — same entity as Drizzle table + Zod schema + Pydantic model + hand dataclass; target is 1 + N generated.
203
+
7.**`own*()` accessor read of an effective property** (ADR-0039) — `ownAttr` / `ownFields` / `own_children` / bare Python `attr(` / `getMetaAttr(name, false)` / native `IsArray` used to read a value or iterate members outside the sanctioned subclass-emit / own-serializer / `@dbColumnType` cases → silently drops `extends`-inherited values. A **correctness defect** (axis G2), not advisory.
0 commit comments