Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve

### Added

- **Type-family parity projection design**: Named
`js-sdl-type-family-vs-rust-l1-type-family.v0` as the next fair parity
projection for schema-extension and non-table GraphQL facts before admitting
those fixtures to the default sentinel corpus.
- **Rust IR fixture contract note**: Moved the core-rs IR contract and fixture
backlog card into the active `0013` design packet, naming the v0.0.6 fixture
classes, canonical byte rules, diagnostics contract, and repo evidence.
Expand Down
10 changes: 6 additions & 4 deletions docs/BEARING.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,19 @@ rejection, alias conflicts in both registration orders, and the Rust IR
fixture contract now housed under the active `0013` packet. Invalid SDL
diagnostics now expose stable `WesleyError::diagnostic()` codes and parser
line/column spans where available, while semantic lowering spans remain
explicitly absent.
explicitly absent. The next non-table projection is now named as
`js-sdl-type-family-vs-rust-l1-type-family.v0` so schema-extension fixtures do
not enter default parity on table evidence alone.

The next pulls are:

1. Expand the fixture-module zoo only where it adds new boundary evidence:
target dispatch already rejects missing modules, invalid product/database
target names, duplicate names, and aliases that collide before or after the
owning target loads.
2. Define the next parity projection before broadening `pnpm parity:ir` beyond
table-compatible SDL. Schema extensions and non-table L1 facts need a fair
projection before they become JS/Rust parity evidence.
2. Implement the named type-family projection and admit
`schema-extensions-schema.graphql` only after
`js-sdl-type-family-vs-rust-l1-type-family.v0` passes.
3. Capture a Rust core performance baseline over the canonical corpus after
the fixture and projection boundaries are named.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
title: Type-family parity projection
legend: SOURCE
packet: 0013-rust-ir-parity-sentinel
status: active
release: v0.0.6
---

# Type-family parity projection

## Why Now

`schema-extensions-schema.graphql` already passes the current
`js-table-vs-rust-table.v0` projection when run as an explicit fixture. That is
useful, but narrow: it proves the folded table facts agree and says nothing
about the scalar, interface, union, enum, or input-object facts that made the
fixture worth adding to the Rust L1 corpus.

The legacy JS `GraphQLAdapter.parseSDL` table IR intentionally drops those
non-table facts. Widening the current table projection and declaring victory
would therefore be false evidence.

## Hill

Wesley names a second parity projection before admitting schema-extension and
non-table fixtures to the default parity sentinel corpus.

That projection compares GraphQL type-family structure fairly:

- JS side: canonical SDL structure from the GraphQL AST after extension
folding
- Rust side: projected Rust L1 type-family facts

The projection must not depend on product, database, runtime, or generated-code
semantics.

## Projection Name

Use:

```text
js-sdl-type-family-vs-rust-l1-type-family.v0
```

This name is intentionally explicit. The JS side is not the legacy table IR; it
is a canonical SDL structural projection produced in JS from the parsed SDL.
The Rust side is L1 IR projected into the same structural shape.

## First Fixture

The first default-corpus candidate is:

```text
test/fixtures/ir-parity/schema-extensions-schema.graphql
```

Current observed behavior:

- `pnpm parity:ir --fixture test/fixtures/ir-parity/schema-extensions-schema.graphql`
passes under `js-table-vs-rust-table.v0`
- that pass covers only the `users` and `teams` table facts
- legacy table IR reports empty `enums`, `scalars`, and `relationships`
- Rust L1 retains `DateTime`, `Named`, `Node`, `Timestamped`, `SearchResult`,
`Status`, and `UserFilter`

Therefore, admitting this fixture to the default parity corpus requires the new
type-family projection, not just adding it to the current table fixture list.

## Included Facts

The v0 projection includes these generic GraphQL facts:

- scalar type names and directives
- object type names
- object implemented interfaces
- object field names, type references, default values, and directives
- interface names
- interface implemented interfaces
- interface field names, type references, default values, and directives
- union names and member type names
- enum names and enum value names
- input object names
- input field names, type references, default values, and directives

The projection includes only facts that both sides can derive from SDL and Rust
L1 without target-specific interpretation.

## Excluded Facts

The v0 projection excludes:

- table-specific compatibility facts already covered by
`js-table-vs-rust-table.v0`
- generated relationship records
- operation catalogs and runtime optic facts
- directive location validation
- product, database, scheduler, transport, replication, and deployment
semantics
- invalid SDL diagnostics
- performance measurements

These exclusions keep the projection structural. Other release slices own those
contracts.

## Normalization Rules

- Fold `extend scalar`, `extend type`, `extend interface`, `extend union`,
`extend enum`, and `extend input` blocks into their base definitions before
projection.
- Sort projected type records by deterministic code-point order of
`kind:name`.
- Sort projected field, argument, enum value, union member, interface, and
directive arrays by deterministic code-point order because the projection
treats them as semantic fact sets.
- Preserve GraphQL nullability and list wrapper structure.
- Preserve directive argument values after each side has produced semantic
values.
- Preserve Rust L1 canonical core directive names.
- Do not use this projection to prove legacy directive alias behavior unless
the admitted fixture uses canonical directive spelling or the JS structural
projection explicitly normalizes aliases as a named lowerer rule.
- Remove top-level envelope metadata before hashing.

## Implementation Shape

The implementation should add projection selection instead of overloading the
current table projection.

Expected shape:

- keep `js-table-vs-rust-table.v0` as the default table projection
- add `js-sdl-type-family-vs-rust-l1-type-family.v0`
- allow fixtures to name their projection
- keep failure reports keyed by projection, fixture, mismatch path, legacy
hash, and Rust hash
- admit `schema-extensions-schema.graphql` to the default sentinel corpus only
after the new projection passes

The JS-side structural projection may reuse the existing canonical SDL
machinery in `packages/wesley-core/src/domain/canonicalize.mjs`, but the
projected comparison shape must be documented in code rather than relying on
raw canonical bytes alone.

## Playback Questions

1. Does the projection name make clear which lowerer/projection source is used
on each side?
2. Does the projection compare non-table type-family facts that the current
table adapter drops?
3. Does the fixture admission rule prevent `schema-extensions-schema.graphql`
from becoming default parity evidence before the new projection exists?
4. Does the implementation avoid product, database, and runtime semantics?
5. Does failure output still identify the first semantic mismatch path?

## Non-Goals

- Do not retire legacy Node lowering in this projection.
- Do not broaden Rust L1 golden regeneration.
- Do not add Nine Lives, WASM runtime policy, or module runtime behavior.
- Do not change Echo, jedit, Continuum, `git-warp`, `warp-ttd`, or
`wesley-postgres`.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ The v0.0.6 corpus must keep these classes explicit:
- **Invalid SDL**: negative diagnostics with stable codes and spans where the
lowerer can provide them.

The schema-extension admission projection is
[Type-family parity projection](./SOURCE_type-family-parity-projection.md).

## Canonical Bytes

- Canonical JSON is UTF-8, newline-free, sorted-object-key JSON.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,21 @@ the default v0 sentinel corpus. The former still carries non-table Rust L1
coverage that needs a separate projection before it is fair parity evidence;
the latter is scale coverage rather than the first compatibility sentinel.

## Next Projection

The next projection is named in
[Type-family parity projection](./SOURCE_type-family-parity-projection.md).

It defines `js-sdl-type-family-vs-rust-l1-type-family.v0` for structural
GraphQL type-family facts that the legacy JS table adapter drops: scalars,
interfaces, unions, enums, input objects, object/interface implements, and
extension-folded fields or members.

`schema-extensions-schema.graphql` may enter the default sentinel corpus only
after that projection exists and passes. Running the fixture through
`js-table-vs-rust-table.v0` is useful table evidence, but it is not non-table
type-family parity evidence.

The supporting
[core-rs IR contract and fixtures note](./SOURCE_wesley-core-rs-ir-contract-and-fixtures.md)
records the release-scoped fixture classes, canonical byte rules, diagnostic
Expand Down
3 changes: 2 additions & 1 deletion docs/design/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ Current packets:
- [`0010`](./0010-wesley-graft-mcp-boundary/wesley-graft-mcp-boundary.md): Wesley+Graft MCP boundary for legal agent optics
- [`0011`](./0011-causal-suffix-bundle-family-and-runtime-sync/causal-suffix-bundle-family-and-runtime-sync.md): Causal suffix bundle family and runtime sync
- [`0012`](./0012-product-leftover-cleanup/product-leftover-cleanup.md): Product leftover cleanup for the v0.0.5 clean-house release
- [`0013`](./0013-rust-ir-parity-sentinel/rust-ir-parity-sentinel.md): Rust IR parity sentinel for the v0.0.6 compiler-truth release
- [`0013`](./0013-rust-ir-parity-sentinel/rust-ir-parity-sentinel.md): Rust IR parity sentinel for the v0.0.6 compiler-truth release, including the
[type-family parity projection](./0013-rust-ir-parity-sentinel/SOURCE_type-family-parity-projection.md)
- [`0014`](./0014-domain-empty-core-boundary/domain-empty-core-boundary.md): Domain-empty Wesley core boundary for the v0.0.6 compiler-truth release
- [Module Contract](./wesley-module-contract.md): Generic core boundary versus external module-owned domain surfaces
- [Module Capability Contract](./wesley-module-capability-contract.md): The capability surfaces external modules should implement
Expand Down
Loading