diff --git a/.changeset/spec-prompts-real-exports-9545.md b/.changeset/spec-prompts-real-exports-9545.md new file mode 100644 index 0000000000..7c8ff5df1a --- /dev/null +++ b/.changeset/spec-prompts-real-exports-9545.md @@ -0,0 +1,32 @@ +--- +'@objectstack/spec': patch +--- + +Published agent-authoring prompts now reference real exports. + +`prompts/create-new-project.md`, `prompts/implement-objectql.md` and +`prompts/implement-objectos.md` told agents to import five symbols that +`@objectstack/spec` does not export. Four failed loudly. The fifth did not: +`import { Object } from '@objectstack/spec/data'` does not resolve, so the +annotation in `export const AccountObject: Object = { ... }` bound to the +**JavaScript global** `Object` instead — metadata authored from that prompt +type-checked against a type that constrains nothing. + +- Object definitions now use the house authoring convention measured in the + example apps, `ObjectSchema.create({ ... })`, which genuinely validates. + Correcting it exposed that the prompt's own example set `enable.audit` / + `enable.workflow`, neither of which exists; they are now `trackHistory` / + `files`, the pair the schema's own docstring uses. +- `implement-objectql.md` keeps the real `Field` and `QuerySchema` imports and + derives the object metadata type as `z.infer`, matching + both `prompts/instructions.md` ("interfaces must be inferred from Zod") and + spec's own `src/contracts/schema-driver.ts`. +- `ManifestSchema` becomes `ObjectStackDefinitionSchema` from the package root: + the prompt's subject is `objectstack.config.ts`, which is neither of the + `/system` manifests. +- `IdentitySchema` / `PolicySchema` have no bare referent; Rule #2 now names + `RLSUserContextSchema` and `RowLevelSecurityPolicySchema` from + `@objectstack/spec/security`. +- The three non-existent "Key Files to Watch" paths + (`system/{manifest,identity,events}.zod.ts`) now point at `stack.zod.ts`, + `security/rls.zod.ts` and `kernel/events.zod.ts`. diff --git a/packages/spec/prompts/create-new-project.md b/packages/spec/prompts/create-new-project.md index e252f8a926..f9f50fc764 100644 --- a/packages/spec/prompts/create-new-project.md +++ b/packages/spec/prompts/create-new-project.md @@ -38,9 +38,9 @@ my-app/ # Implementation Rules -1. **Strict Typing:** Always explicit types. +1. **Strict Typing:** Always define metadata through its schema, never as a bare literal. * BAD: `const MyObject = { ... }` - * GOOD: `export const MyObject: Object = { ... }` + * GOOD: `export const MyObject = ObjectSchema.create({ ... })` 2. **Naming Conventions:** * **File Names:** `snake_case` or `domain.feature.ts` (e.g., `account.object.ts`). @@ -49,14 +49,14 @@ my-app/ 3. **Code Pattern (Object Definition):** ```typescript - import { Object } from '@objectstack/spec/data'; + import { ObjectSchema } from '@objectstack/spec/data'; - export const AccountObject: Object = { + export const AccountObject = ObjectSchema.create({ name: 'account', label: 'Corporate Account', enable: { - audit: true, - workflow: true + trackHistory: true, + files: true }, fields: { name: { type: 'text', label: 'Account Name', required: true }, @@ -66,7 +66,7 @@ my-app/ }, owner: { type: 'lookup', reference: 'user' } } - }; + }); ``` 4. **Code Pattern (App Config):** diff --git a/packages/spec/prompts/implement-objectos.md b/packages/spec/prompts/implement-objectos.md index 271ab60e20..7790bf2679 100644 --- a/packages/spec/prompts/implement-objectos.md +++ b/packages/spec/prompts/implement-objectos.md @@ -12,18 +12,29 @@ Your source of truth is `node_modules/@objectstack/spec`. ### Rule #1: Manifest Driven Boot The system MUST boot by loading and validating the `objectstack.config.ts`. +That file's authoring surface is `defineStack`, and its schema is +`ObjectStackDefinitionSchema` on the package root — not one of the `/system` +manifests (`AppManifestSchema` installs an app into a running stack; +`DeployManifestSchema` describes a deploy bundle). ```typescript -import { ManifestSchema } from '@objectstack/spec/system'; +import { ObjectStackDefinitionSchema } from '@objectstack/spec'; // The kernel starts here -const config = ManifestSchema.parse(loadedConfig); +const config = ObjectStackDefinitionSchema.parse(loadedConfig); ``` ### Rule #2: Security First (Identity & Policy) -All request handlers must validate against `IdentitySchema`. -No operation proceeds without checking `PolicySchema`. +All request handlers must validate the caller's security context against +`RLSUserContextSchema`. No operation proceeds without evaluating the applicable +`RowLevelSecurityPolicySchema` rules against that context. ```typescript -import { IdentitySchema, PolicySchema } from '@objectstack/spec/system'; +import { + RLSUserContextSchema, + RowLevelSecurityPolicySchema, +} from '@objectstack/spec/security'; ``` +There is no bare `Identity` or `Policy` schema: identity is the per-request RLS +user context, and policy is per-object and per-operation. Broader posture lives +in the qualified schemas (`TenantSecurityPolicySchema`, `PermissionSetSchema`). ### Rule #3: API Gateway Contract The HTTP/Gateway layer must perform strict request/response validation using `api/contract.zod.ts` and `api/endpoint.zod.ts`. @@ -36,13 +47,13 @@ Do not invent event formats. Use the standard CloudEvents-compatible structure. ## 3. Workflow -1. **Define Configuration**: Start by mapping `ManifestSchema` to your runtime config. -2. **Initialize Identity**: Implement the Auth Provider using `IdentitySchema`. +1. **Define Configuration**: Start by mapping `ObjectStackDefinitionSchema` to your runtime config. +2. **Initialize Identity**: Implement the Auth Provider so it produces a context that satisfies `RLSUserContextSchema`. 3. **Setup Gateway**: Configure routes based on `ApiRoutesSchema` (from `api/discovery.zod.ts`). ## 4. Key Files to Watch -- `system/manifest.zod.ts`: The "Kernel Configuration". -- `system/identity.zod.ts`: The "Security Context". -- `system/events.zod.ts`: The "System Bus". +- `stack.zod.ts`: The "Kernel Configuration" (`ObjectStackDefinitionSchema`, `defineStack`). +- `security/rls.zod.ts`: The "Security Context" (`RLSUserContextSchema`, `RowLevelSecurityPolicySchema`). +- `kernel/events.zod.ts`: The "System Bus" (`EventSchema`; the `kernel/events/*` sub-modules are internal — import from the published `@objectstack/spec/kernel` entrypoint). - `api/contract.zod.ts`: The "Wire Protocol". diff --git a/packages/spec/prompts/implement-objectql.md b/packages/spec/prompts/implement-objectql.md index 73a3d247f7..ffe33a4302 100644 --- a/packages/spec/prompts/implement-objectql.md +++ b/packages/spec/prompts/implement-objectql.md @@ -11,10 +11,16 @@ Your source of truth is `node_modules/@objectstack/spec`. ## 2. Implementation Rules ### Rule #1: Never Redefine Types -Do not create your own interfaces for `Object`, `Field`, or `Query`. -ALWAYS import them: +Do not create your own interfaces for object metadata, `Field`, or `Query`. +ALWAYS import them, and derive any type you need from the schema: ```typescript -import { type Object, ObjectSchema } from '@objectstack/spec/data'; +import { z } from 'zod'; +import { ObjectSchema, type Field, QuerySchema } from '@objectstack/spec/data'; + +// The object metadata type is NOT exported under the name `Object` — that would +// shadow the JS global and silently type-check against it. Derive it instead: +type ObjectMetadata = z.infer; +type Query = z.infer; ``` ### Rule #2: Schema-First Validation diff --git a/scripts/published-readme-exports.baseline.json b/scripts/published-readme-exports.baseline.json index 18d4c57db1..669f4b8a50 100644 --- a/scripts/published-readme-exports.baseline.json +++ b/scripts/published-readme-exports.baseline.json @@ -66,26 +66,6 @@ { "id": "@objectstack/spec|packages/spec/README.md|import|@objectstack/spec/ai|MCPServerConfigSchema", "why": "@objectstack/spec/ai exports `MCPServerRefSchema`; there is no `MCPServerConfigSchema`. This is the protocol package's own front page." - }, - { - "id": "@objectstack/spec|packages/spec/prompts/create-new-project.md|import|@objectstack/spec/data|Object", - "why": "@objectstack/spec/data exports `ObjectSchema`. `Object` resolves to the JS global instead of failing loudly — the worst shape for a published AGENT-AUTHORING prompt." - }, - { - "id": "@objectstack/spec|packages/spec/prompts/implement-objectos.md|import|@objectstack/spec/system|ManifestSchema", - "why": "@objectstack/spec/system exports `AppManifestSchema` and `DeployManifestSchema`; there is no bare `ManifestSchema`. Published agent-authoring prompt." - }, - { - "id": "@objectstack/spec|packages/spec/prompts/implement-objectos.md|import|@objectstack/spec/system|IdentitySchema", - "why": "@objectstack/spec/system exports `Identity`; there is no `IdentitySchema`. Published agent-authoring prompt." - }, - { - "id": "@objectstack/spec|packages/spec/prompts/implement-objectos.md|import|@objectstack/spec/system|PolicySchema", - "why": "@objectstack/spec/system has no bare `PolicySchema` — only qualified ones (`KeyRotationPolicySchema`, `IncidentResponsePolicySchema`, `DataClassificationPolicySchema`, …). Published agent-authoring prompt." - }, - { - "id": "@objectstack/spec|packages/spec/prompts/implement-objectql.md|import|@objectstack/spec/data|Object", - "why": "Same fabrication as create-new-project.md: `ObjectSchema` is the real export." } ] }