Skip to content

feat(types): public facade policy + generator (SD-2966)#3294

Closed
caio-pizzol wants to merge 2 commits into
mainfrom
caio-pizzol/SD-2966-public-facade-design
Closed

feat(types): public facade policy + generator (SD-2966)#3294
caio-pizzol wants to merge 2 commits into
mainfrom
caio-pizzol/SD-2966-public-facade-design

Conversation

@caio-pizzol
Copy link
Copy Markdown
Contributor

@caio-pizzol caio-pizzol commented May 14, 2026

Establishes the policy framework + initial classification + RFC reconciliation for SuperDoc's public TypeScript facade. This is not the completed facade; partial subpaths are tracked in SD-3147, which blocks the strict gate (SD-3046).

No runtime or API behavior changes. Adds:

  • tests/consumer-typecheck/public-facade-policy.json - machine-readable policy. 112 symbols (79 public, 24 legacy-root, 9 internal; 38 runtime values + 74 types) classified by tier with per-symbol import path, migration target, removal posture, and evidence. Each import_paths[] entry carries classification_status (one of fully-classified / partially-classified / pending-classification / legacy-frozen / asset) so the audit knows which paths are safe to gate strictly.
  • tests/consumer-typecheck/render-facade-doc.mjs - real generator with --write and --check. validatePolicy() rejects unknown tier, kind, import_path, classification_status, source_annotation_mapping tier; missing migration_target on legacy-root; missing evidence on public; duplicate symbol entries.
  • docs/architecture/public-type-facade.md - generated review surface. Regenerate via node tests/consumer-typecheck/render-facade-doc.mjs --write.
  • docs/architecture/package-boundaries.md - one-line reconciliation of step 5 with Decision 1 so the RFC and the new policy describe superdoc/super-editor the same way (legacy public compatibility, not a supported new facade).
  • CI: drift check wired into ci-superdoc, release-superdoc, and release-stable next to the existing public-contract gates.

The drift check is the only enforcement in this PR. No strict typing gates change here; the audit will consume this policy in a separate PR (SD-3046) once SD-3147 promotes the partial subpaths to fully-classified.

Honest classification status today:

  • superdoc (root): partially-classified - most surface enumerated; some still implicit
  • superdoc/types, superdoc/ui, superdoc/headless-toolbar: partially-classified - headline types only
  • superdoc/ui/react, superdoc/headless-toolbar/react, /vue: pending-classification - 0 symbols enumerated
  • superdoc/super-editor, /converter, /docx-zipper, /file-zipper: legacy-frozen - no enumeration intended; future enforcement is no-growth snapshot
  • superdoc/style.css: asset

Strict audit is required to skip non-fully-classified paths.

Follow-ups (separate PRs):

  • SD-3147: enumerate the partial subpaths so they can be promoted to fully-classified. Blocks SD-3046.
  • Normalize source JSDoc annotations to match the policy (split multi-typedef blocks, add replaceWith / removeIn where missing).
  • Implement explicit facade files under packages/superdoc/src/public/.
  • Wire deep-type-audit.mjs to read the policy JSON and run per-tier strict gates (SD-3046).

Review focus: the rendered doc is the review surface; check docs/architecture/public-type-facade.md. Tier classifications, migration targets, and classification_status honesty are the load-bearing decisions.

Verified: `node tests/consumer-typecheck/render-facade-doc.mjs --check` passes; new validator rejects six different invalid-policy mutations; branch rebased on `origin/main`.

Establishes the policy source of truth for the public TypeScript
facade. No runtime or API behavior changes.

- tests/consumer-typecheck/public-facade-policy.json: machine-readable
  policy. 112 symbols across runtime values and types, classified by
  tier (public, beta, legacy-root, internal) with per-symbol import
  path, migration target, removal posture, and evidence.
- tests/consumer-typecheck/render-facade-doc.mjs: generator with
  --write and --check modes. Validates tier/uniqueness/evidence
  invariants before rendering.
- docs/architecture/public-type-facade.md: generated review surface
  for the policy.
- docs/architecture/package-boundaries.md: reconciles step 5 wording
  with Decision 1 (superdoc/super-editor is legacy public
  compatibility, not a supported new facade).
- CI: drift check wired into ci-superdoc, release-superdoc, and
  release-stable, identical to other public-contract gates.

Follow-ups (separate PRs):
- normalize source JSDoc annotations to match the policy
- implement explicit facade files under packages/superdoc/src/public/
- wire deep-type-audit.mjs to consume the policy JSON
@caio-pizzol caio-pizzol requested a review from a team as a code owner May 14, 2026 12:56
@linear
Copy link
Copy Markdown

linear Bot commented May 14, 2026

SD-2966

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a2d389acfc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

# tests/consumer-typecheck/public-facade-policy.json. The policy
# is the source of truth; this step fails if the committed doc
# drifts from what the renderer produces.
run: node tests/consumer-typecheck/render-facade-doc.mjs --check
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include the generated facade doc in CI path filters

When a PR changes only docs/architecture/public-type-facade.md, this drift check never runs because the detect job's superdoc filter covers tests/** and .github/workflows/ci-superdoc.yml but not docs/** or this generated file. That lets hand-edited generated docs merge without the advertised --check gate firing; add the generated doc path (or the docs architecture directory) to the filter so this step is scheduled for doc-only drift.

Useful? React with 👍 / 👎.

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Round-1 review pushback. The PR was advertising the policy as more
complete than it is, and the renderer was dropping data the JSON carried.

- Add `classification_status` to `import_paths[]` (5 states:
  fully-classified, partially-classified, pending-classification,
  legacy-frozen, asset). Mark root and the four UI/headless subpaths
  honestly; legacy compat as legacy-frozen. Strict audit (SD-3046)
  keys on `fully-classified`. Tracked: SD-3147.
- Tighten `validatePolicy`: validate `kind ∈ {runtime_value, type}`,
  `import_path` references, `tier_for_new_exports`, and
  `classification_status`. Empirically tested: 6 typo cases now reject.
- Renderer: drop `evidence` from `groupedSymbols` key (UI components
  no longer splits across two rows). Render `notes` for legacy/internal
  tiers (FlowBlock, SlashMenu, registeredHandlers, plugin keys,
  AnnotatorHelpers were silently dropped). Render `removal_posture`
  in the legacy/internal tables and the flat symbol policy.
- Scope the "machine-readable contract" line: strict gating applies
  only to fully-classified paths.
- Drop the two new `check:facade-doc*` scripts. CI uses direct `node`;
  workspace filter (`pnpm --filter consumer-typecheck`) doesn't resolve
  because the package is not in pnpm-workspace.yaml. Pre-existing
  scripts kept.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants