Skip to content

Commit fd96a84

Browse files
fix(spec-docs): one shared def renders one optionality face on every reference page (#21478)
Fixes #21466 Clause-②: no ## What was wrong A generated reference page gave two optionality answers for one shared def. The card measured it on PR #21463's regeneration of `content/docs/references/ui/component.mdx`: `ObjectGridProps.grouping.fields[]` rendered `order?` / `collapsed?`, and `data[provider='api'].read` / `.write` rendered `method?`, while the same defs on the `ObjectKanbanProps`, `ObjectGanttProps`, `ObjectMapProps` and `ObjectTreeProps` rows rendered them required. ## Mechanism: measured, and it is not evaluation order The card's working hypothesis was an evaluation-order dependence: a memoised conversion, a `.shape` getter or a def cache decided by whichever caller came first. Measured, there is none: - **Two-order harness.** The five props schemas go through the generator's own `projectPublishedJsonSchema` and its output-to-input fallback, under 2 import orders (`ui/view.zod` first or `ui/component.zod` first) times 2 emission orders (grid first or grid last), with `OS_EAGER_SCHEMAS=1` as `gen:schema` runs. All four orders print byte-identical output, with 1 distinct output per tree. That holds on `main` at `6210f8870a`, on #21463's head `38159d1362`, and on this branch's final head. - **What actually flips is the document's io mode.** On #21463's head, `ui/ObjectGridProps.json` is the one props schema emitted "(input shape)". Its output projection throws "Transforms cannot be represented in JSON Schema", because one newly typed member carries a transform. So `build-schemas.ts` falls back to `io: 'input'` for the whole document. Input mode leaves `.default()` members out of `required`, output mode lists them, and both keep `default`. - **The renderer leaked that mode.** The Type column's `{ … }` shape summary marked a key optional from `required` alone (`scripts/lib/format-type.ts`). The Required column already read `default` (`renderRequiredCell`, #8703's rule). Before this change, #8703's rule covered only one of the two places a page states optionality. Corpus reading on `main` `6210f8870a`, with the old renderer: 1398 exports project in both io modes. When each section is rendered from both projections, 215 of them differ, over 483 lines. Each of the 483 lines differs only by this marker. ## Fix There is one predicate now, `isAuthorOmittable(prop, required)` in `format-type.ts`: `default` decides, and `required` breaks the tie. Both optionality positions read it: the shape summary's `key?:` marker and `renderRequiredCell`, whose output is unchanged byte for byte. What does not change: - No emitted JSON Schema. Under #8703's design, the published files keep describing the post-parse shape. - No `packages/spec/src/**` change. - No per-row patch, and no hand edit of a generated page. Afterwards the same corpus measurement reads 0 of 1398 differing (0 lines) on `6210f8870a`, and 0 of 1392 on the final head `d5d88f55a5`. The population is smaller on the final head because `ObjectGridProps` is input-only there and `main`'s agent.lifecycle retirement removed some exports. ## Regenerated pages (the second pin) `check:generated --fix` on the base changed 459 rows on 86 pages. Each changed row only adds `?` to defaulted members (932 markers in total). No row removes one, and no other byte moved. `main` was merged in twice, and each time the colliding generated page was regenerated on the merged tree rather than text-merged: - The first merge brought #21463 and regenerated `component.mdx`. - The second brought `main` at `0b8239111f` (the agent.lifecycle retirement plus one non-docs commit) and regenerated `agent.mdx`. `automation/state-machine.mdx` stays deleted, as `main` has it. Against `main` at `0b8239111f` (and identically against `6e33b67912`), the references delta is 453 rows on 85 pages, 925 markers added. With every `?:` normalised to `:`, each of the 85 pages is byte-identical to main's copy. No row removes a marker. On the final `component.mdx`: - `method?:` appears 8 times and `method:` 0 times; `collapsed?:` 3 times and `collapsed:` 0 times. - The grid's and the kanban's `grouping.fields` rows are byte-identical. - The four `data[provider='api']` `read` rows are byte-identical, and so are the four `write` rows. The same JSON from #21463's head, rendered with the old renderer, gives the card's exact rows (`order?` on the grid and `order` on the kanban). Rendered with this branch's renderer, every shared-def row is identical. ## Pin `packages/spec/scripts/schema-section.test.ts` has a new block, "one shared def renders one face, whichever io mode its document took". Two parent rows share a grouping def and a `{ url, method }` def through the generator's own projection. One parent projects in output mode; the other projects only in input mode, because it has a transform member. - Two precondition cases prove the fixture really is one output-mode and one input-mode document, and that their `required` arrays disagree. So the identical rendering comes from the renderer, not the fixture. - The render case requires the shared defs' rows to be byte-identical and on the input face. - A fourth case pins the marker on hand-written nodes. Reverse verification used the committed fix at `3a62f4a391`. The mutation went through `scripts/ablation-replace.mjs`: anchor count 1 to 0, blob changed. The restore was proven: blob equals HEAD and `git diff HEAD` is empty. Putting back the old `required`-only marker turns 2 of 137 cases red: the render case and the hand-written summary case. The two precondition cases stay green, as designed. The subject resolves to source through a relative import, so no `dist/` leg applies. ## Gates At the final head `d5d88f55a5`, after the second merge: - `pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2`: 602 files, 17769 passed, 1 todo. - `check:generated` ("All 15 generated artifacts are up to date"), `check:docs` and `check:nul-bytes`: exit 0. At `ce1d8ceaf8`, before the second merge, which brought only main's commits and one regenerated page: - `pnpm --filter @objectstack/spec typecheck` (the build program, `tsconfig.scripts.json` and the test program): exit 0. The three touched TS files are in the `tsconfig.scripts.json` program (checked with `--listFilesOnly`). - `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran`: 88 derived, 88 run, 0 NOT-MEASURED, 0 UNRUN, every one exit 0. That includes `check:generated`, `check:docs` and `check:nul-bytes`. This full union was not re-run at `d5d88f55a5`. - Lint was narrowed to the 3 touched TS files: `eslint --no-inline-config --format json` reads 3 files, 0 errors, 0 warnings. The `.mdx` pages match no lint `files` glob in `eslint.config.mjs`. That config enables no type-aware linting (no `parserOptions.project`), so this diff cannot move a verdict on an untouched file. The repo-wide `pnpm lint` is left to CI. ## Changeset `skip-changeset`, measured: - `@objectstack/spec`'s `files[]` is `dist`, `json-schema`, `liveness`, `prompts`, `llms.txt`, `README.md`, `src/**/*.zod.ts`, `CHANGELOG.md`, `api-surface` and `spec-changes.json`. - This diff touches only `packages/spec/scripts/**` and `content/docs/references/**`. The docs site, `apps/docs`, is private. - After a build, `isAuthorOmittable` and `carriesDefault` match 0 files under those paths. The positive control, `lazySchema`, matches 240. - `check:generated` moved no published artifact. ## Acceptance notes - The two-order harness and the corpus io-face measurement were one-time readings from scratch scripts and are not committed. The committed pin is the two-parent-row block above. - Open edge, with no instances today: the predicate reads a member's own `default`. A member spelled as a bare `$ref` to a defaulted def would carry `default` only on the def, not on the property node. The corpus reads 0 such members (0 differing lines in either column after the change). Carrier: none. - The io fallback is per document by design: one transform anywhere moves the whole document to the input projection. After this change that no longer shows on the page. It does still decide which JSON Schema face `json-schema/` publishes for that document, and that is out of this card's scope. --- _Generated by [Claude Code](https://claude.ai/code/session_01UtnxvdiN376GF3sgXwAw4d)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5555047 commit fd96a84

88 files changed

Lines changed: 618 additions & 457 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.

‎content/docs/references/ai/agent.mdx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const result = AIModelConfigSchema.parse(data);
4848
| **avatar** | `string` | optional | |
4949
| **role** | `string` | ✅ | The persona/role (e.g. "Senior Support Engineer") |
5050
| **instructions** | `string` | ✅ | System Prompt / Prime Directives |
51-
| **model** | `{ provider: Enum<'openai' \| 'azure_openai' \| 'anthropic' \| 'local'>; model: string; temperature: number; maxTokens?: number; … }` | optional | |
51+
| **model** | `{ provider?: Enum<'openai' \| 'azure_openai' \| 'anthropic' \| 'local'>; model: string; temperature?: number; maxTokens?: number; … }` | optional | |
5252
| **lifecycle** | `never` | optional | [REMOVED] `agent.lifecycle` was removed in @objectstack/spec 17.7.0 (ADR-0049 enforce-or-remove) — no runtime ever read it: no agent moved through a declared state and no transition was ever refused. Delete the key. A phase of a conversation is a skill with its own `instructions` and `tools`, selected by its `triggerConditions` (ADR-0064); multi-step process orchestration is a Flow (ADR-0019); a record's status transitions are a `state_machine` validation rule on the object (ADR-0020). Run `os migrate meta --from 17` to list the mechanical edits for existing sources; apply them by hand. |
5353
| **surface** | `Enum<'ask' \| 'build'>` | optional (default: `"ask"`) | Product surface this agent binds ('ask' \| 'build') — ADR-0063 §1 |
5454
| **skills** | `string[]` | optional | Skill names to attach (Agent→Skill→Tool architecture) |
@@ -57,10 +57,10 @@ const result = AIModelConfigSchema.parse(data);
5757
| **active** | `boolean` | optional (default: `true`) | |
5858
| **access** | `string[]` | optional | Who can chat with this agent |
5959
| **permissions** | `string[]` | optional | Required permission-set capabilities |
60-
| **planning** | `{ maxIterations: integer }` | optional | Autonomous reasoning and planning configuration |
60+
| **planning** | `{ maxIterations?: integer }` | optional | Autonomous reasoning and planning configuration |
6161
| **memory** | `{ longTerm?: object; reflectionInterval?: integer }` | optional | Agent memory (long-term notes recalled before each conversation and written by periodic reflection), enforced by the cloud AI runtime; the open framework edition does not run agents. |
6262
| **guardrails** | `{ maxTokensPerInvocation?: integer; maxExecutionTimeSec?: integer; blockedTopics?: string[] }` | optional | Safety guardrails for the agent (token budget, time limit, blocked topics), enforced per user turn by the cloud AI runtime; the open framework edition does not run agents. |
63-
| **structuredOutput** | `{ format: Enum<'json_object' \| 'json_schema'>; schema?: Record<string, any>; strict: boolean; retryOnValidationFailure: boolean; … }` | optional | Structured output contract for the agent's final answer (JSON format, schema, retries, fallback format, transform steps), enforced on every final answer by the cloud AI runtime; the open framework edition does not run agents. |
63+
| **structuredOutput** | `{ format: Enum<'json_object' \| 'json_schema'>; schema?: Record<string, any>; strict?: boolean; retryOnValidationFailure?: boolean; … }` | optional | Structured output contract for the agent's final answer (JSON format, schema, retries, fallback format, transform steps), enforced on every final answer by the cloud AI runtime; the open framework edition does not run agents. |
6464
| **protection** | `{ lock: Enum<'none' \| 'no-overlay' \| 'no-delete' \| 'full'>; reason: string; docsUrl?: string }` | optional | Package author protection block — lock policy for this agent. |
6565
| **_lock** | `Enum<'none' \| 'no-overlay' \| 'no-delete' \| 'full'>` | optional | Item-level lock — controls overlay & delete (ADR-0010). |
6666
| **_lockReason** | `string` | optional | Human-readable reason shown when a write is refused by _lock. |
@@ -90,7 +90,7 @@ const result = AIModelConfigSchema.parse(data);
9090

9191
| Property | Type | Required | Description |
9292
| :--- | :--- | :--- | :--- |
93-
| **longTerm** | `{ enabled: boolean; maxEntries?: integer }` | optional | Long-term memory: distilled notes kept per user and agent and recalled before each conversation |
93+
| **longTerm** | `{ enabled?: boolean; maxEntries?: integer }` | optional | Long-term memory: distilled notes kept per user and agent and recalled before each conversation |
9494
| **reflectionInterval** | `integer` | optional | Reflect every N delivered interactions: each reflection writes one distilled note to long-term memory. Required when longTerm.enabled is true, and refused without it |
9595

9696
### Nested Shape: `Agent.guardrails`

‎content/docs/references/ai/conversation.mdx‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ const result = CodeContentSchema.parse(data);
9494
| **id** | `string` | ✅ | Unique message ID |
9595
| **timestamp** | `string` | ✅ | ISO 8601 timestamp |
9696
| **role** | `Enum<'system' \| 'user' \| 'assistant' \| 'function' \| 'tool'>` | ✅ | |
97-
| **content** | `({ type: 'text'; text: string; metadata?: Record<string, any> } \| { type: 'image'; imageUrl: string; detail: Enum<'low' \| 'high' \| 'auto'>; metadata?: Record<string, any> } \| { type: 'file'; fileUrl: string; mimeType: string; fileName?: string; … } \| { type: 'code'; text: string; language: string; metadata?: Record<string, any> })[]` | ✅ | Message content (multimodal array) |
97+
| **content** | `({ type: 'text'; text: string; metadata?: Record<string, any> } \| { type: 'image'; imageUrl: string; detail?: Enum<'low' \| 'high' \| 'auto'>; metadata?: Record<string, any> } \| { type: 'file'; fileUrl: string; mimeType: string; fileName?: string; … } \| { type: 'code'; text: string; language?: string; metadata?: Record<string, any> })[]` | ✅ | Message content (multimodal array) |
9898
| **functionCall** | `{ name: string; arguments: string; result?: string }` | optional | Legacy function call |
99-
| **toolCalls** | `{ id: string; type: Enum<'function'>; function: object }[]` | optional | Tool calls |
99+
| **toolCalls** | `{ id: string; type?: Enum<'function'>; function: object }[]` | optional | Tool calls |
100100
| **toolCallId** | `string` | optional | Tool call ID this message responds to |
101101
| **name** | `string` | optional | Name of the function/user |
102102
| **tokens** | `{ promptTokens: integer; completionTokens: integer; totalTokens: integer }` | optional | Token usage for this message |
@@ -179,9 +179,9 @@ const result = CodeContentSchema.parse(data);
179179
| **name** | `string` | optional | Session name/title |
180180
| **context** | `{ sessionId: string; userId?: string; agentId?: string; object?: string; … }` | ✅ | |
181181
| **modelId** | `string` | optional | AI model ID |
182-
| **tokenBudget** | `{ maxTokens: integer; maxPromptTokens?: integer; maxCompletionTokens?: integer; reserveTokens: integer; … }` | ✅ | |
182+
| **tokenBudget** | `{ maxTokens: integer; maxPromptTokens?: integer; maxCompletionTokens?: integer; reserveTokens?: integer; … }` | ✅ | |
183183
| **messages** | `{ id: string; timestamp: string; role: Enum<'system' \| 'user' \| 'assistant' \| 'function' \| 'tool'>; content: (object \| … +3 more)[]; … }[]` | optional (default: `[]`) | |
184-
| **tokens** | `{ promptTokens: integer; completionTokens: integer; totalTokens: integer; budgetLimit: integer; … }` | optional | |
184+
| **tokens** | `{ promptTokens?: integer; completionTokens?: integer; totalTokens?: integer; budgetLimit: integer; … }` | optional | |
185185
| **totalTokens** | `{ promptTokens: integer; completionTokens: integer; totalTokens: integer }` | optional | Total tokens across all messages |
186186
| **totalCost** | `number` | optional | Total cost for this session in USD |
187187
| **status** | `Enum<'active' \| 'paused' \| 'completed' \| 'archived'>` | optional (default: `"active"`) | |
@@ -228,9 +228,9 @@ const result = CodeContentSchema.parse(data);
228228
| **id** | `string` | ✅ | Unique message ID |
229229
| **timestamp** | `string` | ✅ | ISO 8601 timestamp |
230230
| **role** | `Enum<'system' \| 'user' \| 'assistant' \| 'function' \| 'tool'>` | ✅ | |
231-
| **content** | `({ type: 'text'; text: string; metadata?: Record<string, any> } \| { type: 'image'; imageUrl: string; detail: Enum<'low' \| 'high' \| 'auto'>; metadata?: Record<string, any> } \| { type: 'file'; fileUrl: string; mimeType: string; fileName?: string; … } \| { type: 'code'; text: string; language: string; metadata?: Record<string, any> })[]` | ✅ | Message content (multimodal array) |
231+
| **content** | `({ type: 'text'; text: string; metadata?: Record<string, any> } \| { type: 'image'; imageUrl: string; detail?: Enum<'low' \| 'high' \| 'auto'>; metadata?: Record<string, any> } \| { type: 'file'; fileUrl: string; mimeType: string; fileName?: string; … } \| { type: 'code'; text: string; language?: string; metadata?: Record<string, any> })[]` | ✅ | Message content (multimodal array) |
232232
| **functionCall** | `{ name: string; arguments: string; result?: string }` | optional | Legacy function call |
233-
| **toolCalls** | `{ id: string; type: Enum<'function'>; function: object }[]` | optional | Tool calls |
233+
| **toolCalls** | `{ id: string; type?: Enum<'function'>; function: object }[]` | optional | Tool calls |
234234
| **toolCallId** | `string` | optional | Tool call ID this message responds to |
235235
| **name** | `string` | optional | Name of the function/user |
236236
| **tokens** | `{ promptTokens: integer; completionTokens: integer; totalTokens: integer }` | optional | Token usage for this message |

‎content/docs/references/ai/model-registry.mdx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ const result = ModelCapabilitySchema.parse(data);
5454
| **name** | `string` | ✅ | Model display name |
5555
| **version** | `string` | ✅ | Model version (e.g., "gpt-4-turbo-2024-04-09") |
5656
| **provider** | `Enum<'openai' \| 'azure_openai' \| 'anthropic' \| 'google' \| 'cohere' \| 'huggingface' \| 'local' \| 'custom'>` | ✅ | |
57-
| **capabilities** | `{ textGeneration: boolean; textEmbedding: boolean; imageGeneration: boolean; imageUnderstanding: boolean; … }` | ✅ | |
57+
| **capabilities** | `{ textGeneration?: boolean; textEmbedding?: boolean; imageGeneration?: boolean; imageUnderstanding?: boolean; … }` | ✅ | |
5858
| **limits** | `{ maxTokens: integer; contextWindow: integer; maxOutputTokens?: integer; rateLimit?: object }` | ✅ | |
59-
| **pricing** | `{ currency: string; inputCostPer1kTokens?: number; outputCostPer1kTokens?: number; embeddingCostPer1kTokens?: number }` | optional | |
59+
| **pricing** | `{ currency?: string; inputCostPer1kTokens?: number; outputCostPer1kTokens?: number; embeddingCostPer1kTokens?: number }` | optional | |
6060
| **endpoint** | `string` | optional | Custom API endpoint |
6161
| **apiKey** | `string` | optional | API key (Warning: Prefer secretRef) |
6262
| **secretRef** | `string` | optional | Reference to stored secret (e.g. system:openai_api_key) |
@@ -202,7 +202,7 @@ const result = ModelCapabilitySchema.parse(data);
202202
| **status** | `Enum<'active' \| 'deprecated' \| 'experimental' \| 'disabled'>` | optional (default: `"active"`) | |
203203
| **priority** | `integer` | optional (default: `0`) | Priority for model selection |
204204
| **fallbackModels** | `string[]` | optional | Fallback model IDs |
205-
| **healthCheck** | `{ enabled: boolean; intervalSeconds: integer; lastChecked?: string; status: Enum<'healthy' \| 'unhealthy' \| 'unknown'> }` | optional | |
205+
| **healthCheck** | `{ enabled?: boolean; intervalSeconds?: integer; lastChecked?: string; status?: Enum<'healthy' \| 'unhealthy' \| 'unknown'> }` | optional | |
206206

207207
### Nested Shape: `ModelRegistryEntry.model`
208208

@@ -212,9 +212,9 @@ const result = ModelCapabilitySchema.parse(data);
212212
| **name** | `string` | ✅ | Model display name |
213213
| **version** | `string` | ✅ | Model version (e.g., "gpt-4-turbo-2024-04-09") |
214214
| **provider** | `Enum<'openai' \| 'azure_openai' \| 'anthropic' \| 'google' \| 'cohere' \| 'huggingface' \| 'local' \| 'custom'>` | ✅ | |
215-
| **capabilities** | `{ textGeneration: boolean; textEmbedding: boolean; imageGeneration: boolean; imageUnderstanding: boolean; … }` | ✅ | |
215+
| **capabilities** | `{ textGeneration?: boolean; textEmbedding?: boolean; imageGeneration?: boolean; imageUnderstanding?: boolean; … }` | ✅ | |
216216
| **limits** | `{ maxTokens: integer; contextWindow: integer; maxOutputTokens?: integer; rateLimit?: object }` | ✅ | |
217-
| **pricing** | `{ currency: string; inputCostPer1kTokens?: number; outputCostPer1kTokens?: number; embeddingCostPer1kTokens?: number }` | optional | |
217+
| **pricing** | `{ currency?: string; inputCostPer1kTokens?: number; outputCostPer1kTokens?: number; embeddingCostPer1kTokens?: number }` | optional | |
218218
| **endpoint** | `string` | optional | Custom API endpoint |
219219
| **apiKey** | `string` | optional | API key (Warning: Prefer secretRef) |
220220
| **secretRef** | `string` | optional | Reference to stored secret (e.g. system:openai_api_key) |

‎content/docs/references/ai/solution-blueprint.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const result = BlueprintAppSchema.parse(data);
4545
| **name** | `string` | ✅ | App machine name (snake_case) |
4646
| **label** | `string` | optional | App display label |
4747
| **icon** | `string` | optional | Lucide icon for the App Launcher |
48-
| **nav** | `{ type: Enum<'object' \| 'dashboard'>; target: string; label?: string; icon?: string; … }[]` | optional | Navigation entries; omit to auto-surface every created object and dashboard |
48+
| **nav** | `{ type?: Enum<'object' \| 'dashboard'>; target: string; label?: string; icon?: string; … }[]` | optional | Navigation entries; omit to auto-surface every created object and dashboard |
4949

5050
### Nested Shape: `BlueprintApp.nav[number]`
5151

@@ -298,7 +298,7 @@ const result = BlueprintAppSchema.parse(data);
298298
| **assumptions** | `string[]` | optional (default: `[]`) | Design assumptions made from the underspecified goal |
299299
| **questions** | `string[]` | optional | At most 1-2 structure-deciding questions to confirm before building |
300300
| **objects** | `{ name: string; label?: string; description?: string; fields: object[]; … }[]` | ✅ | Objects (tables) to create |
301-
| **views** | `{ object: string; name: string; label?: string; type: Enum<'list' \| 'form' \| 'kanban' \| 'calendar' \| 'gallery' \| 'gantt'>; … }[]` | optional | Views to create |
301+
| **views** | `{ object: string; name: string; label?: string; type?: Enum<'list' \| 'form' \| 'kanban' \| 'calendar' \| 'gallery' \| 'gantt'>; … }[]` | optional | Views to create |
302302
| **dashboards** | `{ name: string; label?: string; widgets?: object[] }[]` | optional | Dashboards to create |
303303
| **app** | `{ name: string; label?: string; icon?: string; nav?: object[] }` | optional | The navigation shell (app) that surfaces the created objects/dashboards to end users |
304304
| **seedData** | `{ object: string; records: Record<string, any>[] }[]` | optional | Suggested seed data (reported, not auto-applied in Phase C) |
@@ -340,7 +340,7 @@ const result = BlueprintAppSchema.parse(data);
340340
| **name** | `string` | ✅ | App machine name (snake_case) |
341341
| **label** | `string` | optional | App display label |
342342
| **icon** | `string` | optional | Lucide icon for the App Launcher |
343-
| **nav** | `{ type: Enum<'object' \| 'dashboard'>; target: string; label?: string; icon?: string; … }[]` | optional | Navigation entries; omit to auto-surface every created object and dashboard |
343+
| **nav** | `{ type?: Enum<'object' \| 'dashboard'>; target: string; label?: string; icon?: string; … }[]` | optional | Navigation entries; omit to auto-surface every created object and dashboard |
344344

345345
### Nested Shape: `SolutionBlueprint.seedData[number]`
346346

‎content/docs/references/api/auth-endpoints.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ This schema accepts one of the following structures:
156156
| Property | Type | Required | Description |
157157
| :--- | :--- | :--- | :--- |
158158
| **emailPassword** | `{ enabled: boolean; disableSignUp?: boolean; requireEmailVerification?: boolean }` | ✅ | Email/password authentication config |
159-
| **socialProviders** | `{ id: string; name: string; enabled: boolean; type: Enum<'social' \| 'oidc'> }[]` | ✅ | Available social/OAuth providers |
160-
| **features** | `{ twoFactor: boolean; organization: boolean; ssoEnforced?: boolean; phoneNumber?: boolean; … }` | ✅ | Enabled authentication features |
159+
| **socialProviders** | `{ id: string; name: string; enabled: boolean; type?: Enum<'social' \| 'oidc'> }[]` | ✅ | Available social/OAuth providers |
160+
| **features** | `{ twoFactor?: boolean; organization?: boolean; ssoEnforced?: boolean; phoneNumber?: boolean; … }` | ✅ | Enabled authentication features |
161161

162162
### Nested Shape: `GetAuthConfigResponse.emailPassword`
163163

‎content/docs/references/api/auth.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ const result = AuthProvider.parse(data);
150150
| Property | Type | Required | Description |
151151
| :--- | :--- | :--- | :--- |
152152
| **session** | `{ id: string; expiresAt: string; token?: string; ipAddress?: string; … }` | ✅ | Active Session Info |
153-
| **user** | `{ id: string; email: string; emailVerified: boolean; name: string; … }` | ✅ | Current User Details |
153+
| **user** | `{ id: string; email: string; emailVerified?: boolean; name: string; … }` | ✅ | Current User Details |
154154
| **token** | `string` | optional | Bearer token if not using cookies |
155155

156156

@@ -187,7 +187,7 @@ const result = AuthProvider.parse(data);
187187
| **success** | `boolean` | ✅ | Operation success status |
188188
| **error** | `{ code: Enum<'VALIDATION_ERROR' \| 'INVALID_FIELD' \| 'MISSING_REQUIRED_FIELD' \| …>; declaredCode?: string; message: string; userMessage?: string; … }` | optional | Error details if success is false |
189189
| **meta** | `{ timestamp: string; duration?: integer; requestId?: string; traceId?: string }` | optional | Response metadata |
190-
| **data** | `{ id: string; email: string; emailVerified: boolean; name: string; … }` | ✅ | |
190+
| **data** | `{ id: string; email: string; emailVerified?: boolean; name: string; … }` | ✅ | |
191191

192192
### Nested Shape: `UserProfileResponse.error`
193193

0 commit comments

Comments
 (0)