Skip to content

Commit 3105887

Browse files
committed
docs: packaging admission rule (four package kinds, five tests)
1 parent 781d0bc commit 3105887

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

‎AGENTS.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,8 @@ These are the load-bearing principles that have emerged through implementation.
390390

391391
- **Each port defaults to its own language's standard behaviour; identical cross-port output is opt-in.** Generated code writes what that language's standard serializer writes: C# decimals as JSON numbers, a value object's null member as `null`. Do not standardize the ports for the convenience of our own conformance tests. A cross-port form, such as `"wire": { "decimals": "string", "nullMembers": "omit" }`, is a project setting that adopters choose. The corpora pin it explicitly in their own config and never decide a default. 1.1.0 broke this rule by making the decimal string and null omission the only output, and 1.1.2 put it back. See [ADR-0019 Amendment 2](spec/decisions/ADR-0019-runtime-return-type-contract.md).
392392

393+
- **New packaged content must pass five tests to live in this project.** Most apps would re-derive it by hand; it is model-shaped; all five ports can carry it in their own idiom; its default needs no copyleft or commercial dependency; it ships `preview` until one external adopter runs it with the drift gate. Otherwise it stays with the adopter or in a separate project. The four package kinds and the worked example: [docs/features/libraries.md](docs/features/libraries.md), "What belongs in MetaObjects".
394+
393395
- **Pattern-derivable from metadata = codegen, never hand-code.** This is the metaobjects raison d'être. If you find yourself proposing that users hand-write something the metadata fully describes (FK references, basic CRUD, validator chains, type-safe finders, relations() blocks), stop. Codegen it. The only exception is what metadata genuinely cannot express (custom SQL views, regex patterns from outside metadata, business logic). When in doubt, generate.
394396

395397
- **Study reference implementations for subtle pipeline behavior; don't re-derive from spec.** For complex orchestration (loader, parser, super resolution, overlay/override merging, registry lifecycle), the spec describes WHAT but the implementation captures HOW — including edge cases and error handling. When porting, read existing implementations first. First-principles reasoning produces subtly wrong behavior that breaks cross-language interop.

‎docs/features/libraries.md‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,35 @@ in, implied generator not wired* and *generator wired, its library not opted in*
151151
second matters more than it looks: a generator whose anchor is absent matches nothing
152152
and emits zero files, which reads exactly like "my model has no trace entities yet".
153153

154+
## What belongs in MetaObjects: four kinds of package, five tests
155+
156+
MetaObjects ships four kinds of package. They differ in who owns the result:
157+
158+
| kind | what it is | ownership |
159+
|---|---|---|
160+
| **Vocabulary** | metamodel types and attributes | core, not ejectable: the metadata you write with it is already yours |
161+
| **Library** | `library/<name>/` with a `library.json`: metadata and requirements (`iam`, `ai`) | `meta eject <library>` (above) |
162+
| **Catalog generator** | a row in `meta gen --list` | import it as shipped, or eject it, except `template` and the package-only rows ([ADR-0034](../../spec/decisions/ADR-0034-codegen-scaffold-and-own.md), Amendment 5). A library may imply one only when it anchors on a library node (above). |
163+
| **Runtime helper** | an Apache-2.0 per-port package that generated code imports | copied by the route generator's eject, helper runtime included ([ADR-0034](../../spec/decisions/ADR-0034-codegen-scaffold-and-own.md), Amendment 3) |
164+
165+
Something new belongs in this project only if it passes **all five** tests:
166+
167+
1. Most apps would otherwise re-derive it by hand.
168+
2. It is model-shaped: derivable from declared metadata.
169+
3. It can be carried in all five ports, each in its own language's standard way.
170+
4. Its default needs no copyleft or commercial dependency.
171+
5. It ships as `preview` until one external adopter runs it with the drift gate enforced
172+
([compatibility-policy.md](../compatibility-policy.md)).
173+
174+
Anything else stays with the adopter (policy, presentation, branding, scheduling) or in a
175+
separate project.
176+
177+
**Worked example, reporting** ([reporting.md](reporting.md)). The vocabulary (dimensions,
178+
measures, segments, `object.report`) is core. The planned `reporting` library holds
179+
metadata only, so opting in adds no code. Exporting to another tool and dashboards are
180+
catalog generators, one per heavy format, so an adopter never takes a dependency they did
181+
not wire: `cube-model` ships today, a dashboard generator does not exist yet.
182+
154183
## What ships today
155184

156185
| library | what it is | stability |

0 commit comments

Comments
 (0)