Skip to content

fix(spec): gen:schema io:'input' fallback + disappearance ratchet — restore PageTabsProps (#2978)#3012

Merged
os-zhuang merged 3 commits into
mainfrom
claude/gen-schema-pagetabsprops-drop-g3bp4k
Jul 16, 2026
Merged

fix(spec): gen:schema io:'input' fallback + disappearance ratchet — restore PageTabsProps (#2978)#3012
os-zhuang merged 3 commits into
mainfrom
claude/gen-schema-pagetabsprops-drop-g3bp4k

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #2978.

Problem

#2967 added an ExpressionInputSchema field (items[].visibleWhen) to PageTabsProps. That schema contains a .transform (string shorthand → {dialect, source} envelope), which zod's toJSONSchema cannot represent in the default output mode, so build-schemas.ts silently skipped it. json-schema/ui/PageTabsProps.json disappeared, and the next full gen:docs run would have deleted the published PageTabsProps section from content/docs/references/ui/component.mdx.

It turned out to be a whole class, not a one-off: 150 schemas (ObjectSchema, FieldSchema, FlowSchema, PageSchema, ActionSchema, …) were already transform-blocked and absent from json-schema/ — delivered but not declared.

Fix (packages/spec/scripts/build-schemas.ts)

  1. io: 'input' fallback — when output-mode conversion fails on a transform, retry with io: 'input'. These JSON Schemas describe what authors write, and the input side of a transform pipe is plain data, so it is representable. For PageTabsProps.visibleWhen this emits the correct authoring shape: anyOf: [string (CEL shorthand), expression envelope]. Rescued schemas carry an x-io: "input" marker (author-time shape: parse-time transforms/defaults not applied). Result: 1849 schemas generated (150 as input shape); only 18 truly unrepresentable ones (function/Date/BigInt/custom) remain skipped.

  2. Disappearance ratchetjson-schema/ is a gitignored build artifact, so a new committed packages/spec/json-schema.manifest.json records every schema key ever emitted (mirrors the spec-liveness ratchet pattern). A key present in the manifest but not emitted by a build now fails gen:schema loudly with remediation steps; deliberate retirements must remove the key in the same PR. New schemas are auto-appended (commit the manifest change). Silent skip is now reserved for types that have never been representable — exactly the boundary gen:schema silently drops PageTabsProps since #2967 — references regen would delete real docs #2978 asked for.

  3. build-docs.ts pipe escaping — rescued schemas surfaced descriptions containing literal |, which split GFM table cells (the type column already escaped pipes; the description column didn't). Descriptions in property tables are now escaped.

Docs regen (content/docs/references/)

Full gen:docs over the fixed output (the regen that was unsafe before this fix):

  • PageTabsProps keeps its section — the regression the issue predicted is gone;
  • the 150 rescued contracts gain reference sections (4 new pages: automation/control-flow, integration/connector-auth, integration/mapping, shared/mapping);
  • previously-broken table rows with raw pipes are re-emitted escaped.

Verification

  • pnpm --filter @objectstack/spec gen:schemaGenerated: 1849 (150 as input shape), json-schema/ui/PageTabsProps.json present with anyOf authoring shape for visibleWhen;
  • ratchet tested: adding a ghost key to the manifest fails the build with exit 1 and a pointed error message; re-runs are idempotent (no manifest churn);
  • pnpm --filter @objectstack/spec gen:openapi unaffected;
  • pnpm docs:build compiles all regenerated MDX.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Fn6qMKtJeVbs2KzouWDHhB


Generated by Claude Code

claude added 2 commits July 16, 2026 04:42
…hemas (#2978)

PageTabsProps vanished from json-schema/ when #2967 added an
ExpressionInputSchema (.transform) field — zod's toJSONSchema cannot
represent transforms in the default output mode, and build-schemas.ts
silently skipped it, so the next gen:docs run would have deleted the
published PageTabsProps reference section.

Two-part fix:

1. io:'input' fallback — when output-mode conversion fails on a
   transform, retry with io:'input'. These JSON Schemas describe what
   authors WRITE, and the input side of a transform pipe is plain data,
   so it is representable (for PageTabsProps.visibleWhen it emits the
   correct `anyOf: [string, expression envelope]` authoring shape).
   Rescued schemas are marked `x-io: "input"`. This restores
   PageTabsProps and 149 other transform-blocked public contracts
   (ObjectSchema, FieldSchema, FlowSchema, PageSchema, ActionSchema, …);
   only 18 truly unrepresentable schemas (function/Date/BigInt/custom)
   remain skipped.

2. Disappearance ratchet — json-schema/ is gitignored, so the committed
   json-schema.manifest.json records every schema key ever emitted.
   A key present in the manifest but absent from a build now fails
   gen:schema loudly with remediation steps; deliberate retirements must
   remove the key in the same PR. Silent skip remains only for types
   that have never been representable.

Also escape literal `|` in the description cell of generated property
tables (build-docs.ts) — rescued schemas surfaced descriptions with
pipes that split GFM table rows.

Closes #2978

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fn6qMKtJeVbs2KzouWDHhB
gen:docs over the post-fix json-schema/ output. PageTabsProps keeps its
section (now including the visibleWhen items shape from #2967), and the
149 schemas rescued by the io:'input' fallback gain reference sections —
previously delivered-but-undeclared contracts (Prime Directive #10).
Existing table rows with literal pipes in descriptions are re-emitted
with GFM escaping.

Verified: `pnpm docs:build` compiles all regenerated MDX.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fn6qMKtJeVbs2KzouWDHhB
@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Canceled Canceled Jul 16, 2026 5:08am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Jul 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

97 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via packages/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Comment thread packages/spec/scripts/build-docs.ts Fixed
Comment thread packages/spec/scripts/build-schemas.ts Fixed
- build-schemas.ts: read the ratchet manifest directly and treat ENOENT
  as first-run bootstrap instead of existsSync-then-read (TOCTOU).
- build-docs.ts: escape backslashes before pipes in table-cell
  descriptions — an existing `\|` would otherwise decay into an escaped
  backslash followed by a live pipe, splitting the GFM cell.

No output changes: regenerated json-schema/ and references/ are
byte-identical.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fn6qMKtJeVbs2KzouWDHhB
@os-zhuang
os-zhuang marked this pull request as ready for review July 16, 2026 04:50
@os-zhuang
os-zhuang merged commit c435e29 into main Jul 16, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/gen-schema-pagetabsprops-drop-g3bp4k branch July 16, 2026 05:09
os-zhuang pushed a commit that referenced this pull request Jul 16, 2026
Conflict resolution: content/docs/references/ui/view.mdx (auto-generated)
regenerated via gen:docs on the merged tree; api-surface.json auto-merge
verified identical to regenerated output; json-schema.manifest.json
(disappearance ratchet, #3012, new on main) picks up +ui/FormButtonConfig.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ue47V8zZ5QhcYMPiRQDA7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/xl tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gen:schema silently drops PageTabsProps since #2967 — references regen would delete real docs

3 participants