Skip to content

Commit aec8402

Browse files
dmealingclaude
andcommitted
merge: Documentation Provider — universal common-attrs substrate across 4 ports
Lands the Documentation Provider: 7 universal doc common attrs (description / title / notes / deprecated / replacedBy / seeAlso / aliases) registered via a new `commonAttrs` registry hook on every metatype, across TS / C# / Java / Python, plus doc-gen consumption: - TS: JSDoc above entity types, Drizzle columns, Zod schemas; Postgres COMMENT ON TABLE/COLUMN in migrate-ts; Mermaid ER diagram (docs/model.md) via mermaidErDiagram() generator. - C#: XML doc + [Obsolete] on entity classes / properties / DbSet properties; Postgres COMMENT ON in PostgresSchema DDL. - Java: substrate-only — constants + SPI-registered provider class with deferred wiring (TODO(java-h3b)) pending an open-policy validation pass. - Python: full substrate — register_common_attrs hook + validation merge + ERR_PROVIDER_ATTR_CONFLICT + doc module + conformance adapter integration. D5 contract: @notes is internal-only and NEVER emitted to user-facing doc-gen surfaces. Enforced by negative-emission tests in every output- emitting port. 4 new cross-language conformance fixtures (doc-common-attrs-{basic, multiline,on-all-types,stringarray-shapes}) pin the contract; TS and Python pass all 4 green, C# passes 3 + lists on-all-types pending its source-v2 port. CLAUDE.md updated with the cross-language vocabularies entry. Spec status flipped to Implemented. Per-unit + aggregate code-reviewer + code-simplifier gates passed. Spec: docs/superpowers/specs/2026-05-24-documentation-provider-design.md Plan: docs/superpowers/plans/2026-05-24-documentation-provider.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2 parents 53b2d5d + 44bbcb9 commit aec8402

74 files changed

Lines changed: 3356 additions & 52 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ Equal weight. Three ship per-language today; the fourth is committed for 7.0.0:
1717

1818
## Status
1919

20-
TypeScript reference implementation is **published to npm at `0.5.0`** (11 `@metaobjectsdev/*` packages on the `latest` tag; `cli` at `0.5.1`) — Projects D–G shipped end-to-end with 2124+ tests passing. Java port is in progress: H3a (loader restructure) shipped 2026-05-19; H3b (conformance harness) is active. **C# is a first-class full-stack target.** Loader + conformance shipped (loader, canonical serializer, and a `dotnet test` conformance runner over the full shared corpus; metadata layer fully caught up — empty expected-failures ledger, incl. `template.*` + `origin.collection`). The FR-004 tier ships: the **render engine (`MetaObjects.Render`)** renders the shared `fixtures/render-conformance` corpus byte-identical to TS, plus payload-VO codegen and `verify`. **The EF Core + ASP.NET codegen tier ships** (`MetaObjects.Codegen` + the `meta` CLI: `verify`/`gen`/`migrate`): entities, `AppDbContext` (DbSets, projection `.ToView`, `@storage` owned types via `OwnsOne`), CRUD minimal-API routes, and Postgres DDL (`CREATE TABLE` with PK/NOT NULL/UNIQUE/FK + `@storage` columns; `CREATE VIEW` for projections incl. aggregate/passthrough-`@via`/collection origins). Remaining tiers — introspection-driven incremental migration (`migrate` is full-CREATE today) and the runtime-metadata pillar — are being built out (no part of MetaObjects is out of scope for C#). Python is planned post-H3.
20+
TypeScript reference implementation is **published to npm at `0.5.0`** (11 `@metaobjectsdev/*` packages on the `latest` tag; `cli` at `0.5.1`) — Projects D–G shipped end-to-end with 2124+ tests passing. Java port is in progress: H3a (loader restructure) shipped 2026-05-19; H3b (conformance harness) is active. **C# is a first-class full-stack target.** Loader + conformance shipped (loader, canonical serializer, and a `dotnet test` conformance runner over the full shared corpus; metadata layer largely caught up — known-gap list now tracks the `source.rdb` source-v2 paradigm cluster + `doc-common-attrs-on-all-types`, all blocked on the source-v2 port). The FR-004 tier ships: the **render engine (`MetaObjects.Render`)** renders the shared `fixtures/render-conformance` corpus byte-identical to TS, plus payload-VO codegen and `verify`. **The EF Core + ASP.NET codegen tier ships** (`MetaObjects.Codegen` + the `meta` CLI: `verify`/`gen`/`migrate`): entities, `AppDbContext` (DbSets, projection `.ToView`, `@storage` owned types via `OwnsOne`), CRUD minimal-API routes, and Postgres DDL (`CREATE TABLE` with PK/NOT NULL/UNIQUE/FK + `@storage` columns; `CREATE VIEW` for projections incl. aggregate/passthrough-`@via`/collection origins). Remaining tiers — introspection-driven incremental migration (`migrate` is full-CREATE today) and the runtime-metadata pillar — are being built out (no part of MetaObjects is out of scope for C#). Python is planned post-H3.
2121

2222
The 7.0.0 line is specced: FR-003 brings the Java OMDB persistence engine, metadata-driven schema migration, and dynamic projections onto current core; FR-004 builds the fourth pillar (cross-language prompt construction) on top of FR-003's projections. Both are design-stage plan-of-record (`docs/superpowers/specs/2026-05-22-fr-003-*` and `*-fr-004-*`), not yet implemented.
2323

24-
Cross-language conformance fixtures live at `fixtures/conformance/` (45 fixtures + a `CAPABILITIES.json` manifest). See `spec/roadmap.md` for current + planned work.
24+
Cross-language conformance fixtures live at `fixtures/conformance/` (85 fixtures + a `CAPABILITIES.json` manifest). See `spec/roadmap.md` for current + planned work.
2525

2626
## Public repository hygiene
2727

@@ -396,6 +396,7 @@ Preserve the following contracts exactly across all language ports:
396396
- Schema attrs: `@schema` on `source[dbTable]` and `source[dbView]` (DB schema name; Postgres default `public`, SQLite rejects non-default values)
397397
- Storage attrs: `@storage` on `field.object` (with `@objectRef`) — values `flattened` / `jsonb` / `subdocument`. Unifies "owned types" (flattened storage) and "structured JSONB" (jsonb storage). Defaults to single-jsonb-column when absent (back-compat).
398398
- Enum: `field.enum` is a first-class field subtype (peer of `currency`), string-backed. Required `@values` string-array attr (member symbols). Members must be a non-empty set, each matching `^[A-Za-z_][A-Za-z0-9_]*$`, no duplicates — every port's loader enforces this (own-only) emitting `ERR_BAD_ATTR_VALUE` (missing `@values``ERR_MISSING_REQUIRED_ATTR`). Reuse via abstract `field.enum` + `extends`. Codegen: TS union + `z.enum`, C# `enum` + EF `HasConversion<string>()`, DB `varchar` + `CHECK`. Int-backed values, display labels, and native PG enum are deferred (see `docs/superpowers/specs/2026-05-23-enum-datatype-design.md`).
399+
- Documentation common attrs (any node): `description`, `title`, `notes`, `deprecated`, `replacedBy`, `seeAlso`, `aliases`. Registered via the cross-language `commonAttrs` registry hook (`registerCommonAttrs` / `RegisterCommonAttrs` / `register_common_attrs`; Java provider currently substrate-only, wiring deferred to H3b). `notes` is the internal-only rationale slot — never emitted to user-facing doc-gen (JSDoc / XML-doc / Postgres `COMMENT ON` / Mermaid prose). TS doc-gen ships all three tiers; C# ships XML-doc + COMMENT ON. See `docs/superpowers/specs/2026-05-24-documentation-provider-design.md`.
399400

400401
**Wire format:**
401402
- Currency: integer minor units on the wire always. Float arithmetic for money is forbidden.

docs/superpowers/specs/2026-05-24-documentation-provider-design.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Design: Documentation provider — universal doc common attrs + cross-language doc-gen
22

33
**Date:** 2026-05-24
4-
**Status:** Approved (design)
4+
**Status:** Implemented across TS, C#, Java (substrate; wiring deferred to H3b), Python (2026-05-24)
55
**Author:** Doug Mealing (with Claude)
66

77
## Problem
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "User",
8+
"@aliases": [
9+
"Account",
10+
"Member"
11+
],
12+
"@description": "A registered account holder.",
13+
"@title": "User",
14+
"children": [
15+
{
16+
"field.long": {
17+
"name": "id"
18+
}
19+
},
20+
{
21+
"field.string": {
22+
"name": "email",
23+
"@aliases": [
24+
"emailAddress",
25+
"userEmail"
26+
],
27+
"@deprecated": "Use contactEmail instead.",
28+
"@description": "User's primary email address.",
29+
"@replacedBy": "User.contactEmail",
30+
"@seeAlso": [
31+
"https://acme.com/docs/email"
32+
],
33+
"@title": "Email"
34+
}
35+
},
36+
{
37+
"field.string": {
38+
"name": "contactEmail",
39+
"@description": "Replacement contact email."
40+
}
41+
},
42+
{
43+
"identity.primary": {
44+
"@fields": [
45+
"id"
46+
]
47+
}
48+
}
49+
]
50+
}
51+
}
52+
]
53+
}
54+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "User",
8+
"@description": "A registered account holder.",
9+
"@title": "User",
10+
"@aliases": ["Account", "Member"],
11+
"children": [
12+
{
13+
"field.long": {
14+
"name": "id"
15+
}
16+
},
17+
{
18+
"field.string": {
19+
"name": "email",
20+
"@description": "User's primary email address.",
21+
"@title": "Email",
22+
"@deprecated": "Use contactEmail instead.",
23+
"@replacedBy": "User.contactEmail",
24+
"@seeAlso": ["https://acme.com/docs/email"],
25+
"@aliases": ["emailAddress", "userEmail"]
26+
}
27+
},
28+
{
29+
"field.string": {
30+
"name": "contactEmail",
31+
"@description": "Replacement contact email."
32+
}
33+
},
34+
{
35+
"identity.primary": {
36+
"@fields": "id"
37+
}
38+
}
39+
]
40+
}
41+
}
42+
]
43+
}
44+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
["metaobjects-core-types", "metaobjects-documentation"]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Order",
8+
"@description": "An order placed by a User.\n\nLifecycle: DRAFT → PUBLISHED → ARCHIVED.\nMultiple lines preserved via canonical serialization.",
9+
"@notes": "Internal rationale:\n- We chose status as an enum because external integrations require canonical states.\n- Don't surface this in API docs.",
10+
"children": [
11+
{
12+
"field.long": {
13+
"name": "id"
14+
}
15+
},
16+
{
17+
"identity.primary": {
18+
"@fields": [
19+
"id"
20+
]
21+
}
22+
}
23+
]
24+
}
25+
}
26+
]
27+
}
28+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Order",
8+
"@description": "An order placed by a User.\n\nLifecycle: DRAFT → PUBLISHED → ARCHIVED.\nMultiple lines preserved via canonical serialization.",
9+
"@notes": "Internal rationale:\n- We chose status as an enum because external integrations require canonical states.\n- Don't surface this in API docs.",
10+
"children": [
11+
{
12+
"field.long": {
13+
"name": "id"
14+
}
15+
},
16+
{
17+
"identity.primary": {
18+
"@fields": "id"
19+
}
20+
}
21+
]
22+
}
23+
}
24+
]
25+
}
26+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
["metaobjects-core-types", "metaobjects-documentation"]
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Subscriber",
8+
"@description": "Entity-level doc.",
9+
"children": [
10+
{
11+
"source.rdb": {
12+
"@description": "Source-level doc.",
13+
"@kind": "table",
14+
"@table": "subscribers"
15+
}
16+
},
17+
{
18+
"field.long": {
19+
"name": "id"
20+
}
21+
},
22+
{
23+
"field.string": {
24+
"name": "email",
25+
"@description": "Field-level doc.",
26+
"children": [
27+
{
28+
"validator.required": {
29+
"@description": "Validator-level doc."
30+
}
31+
}
32+
]
33+
}
34+
},
35+
{
36+
"identity.primary": {
37+
"@description": "Identity-level doc.",
38+
"@fields": [
39+
"id"
40+
]
41+
}
42+
}
43+
]
44+
}
45+
}
46+
]
47+
}
48+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme",
4+
"children": [
5+
{
6+
"object.entity": {
7+
"name": "Subscriber",
8+
"@description": "Entity-level doc.",
9+
"children": [
10+
{
11+
"source.rdb": {
12+
"@kind": "table",
13+
"@table": "subscribers",
14+
"@description": "Source-level doc."
15+
}
16+
},
17+
{
18+
"field.long": {
19+
"name": "id"
20+
}
21+
},
22+
{
23+
"field.string": {
24+
"name": "email",
25+
"@description": "Field-level doc.",
26+
"children": [
27+
{
28+
"validator.required": {
29+
"@description": "Validator-level doc."
30+
}
31+
}
32+
]
33+
}
34+
},
35+
{
36+
"identity.primary": {
37+
"@fields": "id",
38+
"@description": "Identity-level doc."
39+
}
40+
}
41+
]
42+
}
43+
}
44+
]
45+
}
46+
}

0 commit comments

Comments
 (0)