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
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# ADR-0017: Project primitive/literal candidates from Go graph identity

- Status: accepted
- Date: 2026-08-17
- Deciders: TypeScript Semantic Kernel maintainers
- Supersedes: —
- Superseded by: —

## Context

ADR-0016 selected primitive and literal type construction as the first
independent Rust semantic candidate, while keeping TypeScript 7's Go checker as
the semantic oracle. The existing OXC reference consumer already attaches all
five TypeFacts roots to arena-local `NodeId`s and inspects the shared,
response-local graph without copying its identity.

A candidate record must be useful for later Go-versus-Rust comparison without
mistaking equal display text for semantic equivalence. It also cannot erase an
unavailable view, producer truncation, unsupported entity, checker error, or
literal-union edge.

## Decision

The internal OXC consumer emits a versioned Rust-owned primitive/literal
candidate from each attached TypeFacts record as part of graph inspection. The
candidate consumes the existing schema-v1 Go-produced graph; it does not add a
producer capability or protocol record.

Each candidate contains:

- the portable occurrence and fact completeness/recovery/truncation status;
- actual, contextual, widened, apparent, and declared roots in fixed view
order, retaining their view state and effective response-local TypeID;
- one deterministic record per reachable response-local TypeID;
- structured primitive, literal, null-like, and union semantics, including the
literal kind/value and ordered union member TypeIDs; and
- the source entity state/issues plus an explicit Rust candidate state and
machine-readable reasons for truncated, unsupported, or error cases.

Candidate type records are ordered by response-local TypeID and repeated roots
share one record. Display text is not part of the Rust semantic record. The
first candidate covers boolean, string, number, and bigint primitives;
boolean, string, number, and bigint literal values; null, undefined, and void;
and unions over those records.

The candidate version is internal to the reference consumer. TypeScript 7's Go
checker remains authoritative for type construction and all TypeFacts roots.
This decision neither changes the TS7 producer protocol nor satisfies
ADR-0016's replacement gate.

## Consequences

- Future differential work can compare structured kinds, literal values,
member identity, roots, and states rather than display strings.
- OXC attachment remains the ownership seam: no Rust or OXC type enters the Go
producer protocol.
- Shared canonical fixtures can be decoded and round-tripped by Go while the
Rust consumer verifies its candidate projection through the same graph.
- Unsupported and truncated observations stay useful evidence instead of
being coerced into a supported primitive/literal record.
- Replacement readiness still requires an independent producer and the exact
structured differential threshold in ADR-0016.

## References

- [RFC 0001](../../rfcs/0001-semantic-facts-kernel.md)
- [ADR-0015](0015-attach-semantic-facts-without-expanding-graph-identity.md)
- [ADR-0016](0016-port-occurrence-attachment-before-semantic-categories.md)
- [Issue #40](https://github.com/swernerx/typescript-semantic-kernel/issues/40)
12 changes: 7 additions & 5 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ decision is recorded in a successor ADR that links to the record it replaces.
| [0014](0014-isolate-the-oxc-reference-consumer.md) | Accepted | Isolate the OXC reference consumer |
| [0015](0015-attach-semantic-facts-without-expanding-graph-identity.md) | Accepted | Attach semantic facts without expanding graph identity |
| [0016](0016-port-occurrence-attachment-before-semantic-categories.md) | Accepted | Port occurrence attachment before semantic categories |
| [0017](0017-project-primitive-literal-candidates-from-go-graph-identity.md) | Accepted | Project primitive/literal candidates from Go graph identity |

## Current migration decision

Expand All @@ -34,8 +35,9 @@ Rust/OXC consumer remains a reference and migration harness; the evidence does
not establish compiler equivalence, production readiness, or a performance
advantage.

[ADR-0016](0016-port-occurrence-attachment-before-semantic-categories.md)
identifies primitive/literal Rust type-record construction as the next semantic
candidate. It remains Go-authoritative until independent Rust output passes the
documented replacement gates; no semantic category is currently approved for
replacement.
[ADR-0017](0017-project-primitive-literal-candidates-from-go-graph-identity.md)
records the first Rust-owned primitive/literal candidate over the Go-produced
graph. It makes structured comparison possible but is not an independent
producer. Primitive/literal construction remains Go-authoritative until a
future Rust producer passes ADR-0016's replacement gates; no semantic category
is currently approved for replacement.
8 changes: 5 additions & 3 deletions docs/evidence/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ count is zero.
The checked record supports the migration decision in
[ADR-0016](../adr/0016-port-occurrence-attachment-before-semantic-categories.md):
occurrence identity and attachment plumbing may be ported behind the Go oracle.
Primitive/literal Rust type-record construction is the next semantic candidate,
not an approved replacement. The TypeScript 7 Go checker remains authoritative
until independent Rust output passes the differential compatibility gates.
[ADR-0017](../adr/0017-project-primitive-literal-candidates-from-go-graph-identity.md)
subsequently adds a structured primitive/literal Rust candidate over that
Go-produced graph. It is not an approved replacement or an independent
producer. The TypeScript 7 Go checker remains authoritative until independent
Rust output passes the differential compatibility gates.
14 changes: 8 additions & 6 deletions docs/porting/migration-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,14 @@ source remains Go-only because the current OXC parse fails; its facts are
reported as consumer differences rather than omitted.

ADR-0016 selects occurrence identity and attachment plumbing as the first safe
mechanical port. Primitive/literal type construction is the first proposed
semantic implementation candidate, but no semantic category may replace Go
until independent Rust output matches the normalized structured oracle with no
completeness/state downgrade or new unsupported form. Project loading,
resolution, binding, symbols, inference, contextual/widened types, overloads,
generic instantiation, narrowing, and recovery remain Go-authoritative.
mechanical port. ADR-0017 adds the first Rust-owned primitive/literal candidate
record over the Go-produced graph so future comparisons can use structured
kinds, literal values, union edges, roots, and states. It is not an independent
producer, and no semantic category may replace Go until independent Rust output
matches the normalized structured oracle with no completeness/state downgrade
or new unsupported form. Project loading, resolution, binding, symbols,
inference, contextual/widened types, overloads, generic instantiation,
narrowing, and recovery remain Go-authoritative.

## Gate ladder

Expand Down
17 changes: 14 additions & 3 deletions internal/oxc_reference/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ diagnostics remain visible. Depth, node, and edge budgets are consumer-local
guards and do not rewrite or reinterpret producer records. See
[ADR-0015](../../docs/adr/0015-attach-semantic-facts-without-expanding-graph-identity.md).

Each inspection also contains the internal version-1 primitive/literal Rust
candidate documented by
[ADR-0017](../../docs/adr/0017-project-primitive-literal-candidates-from-go-graph-identity.md).
It records the occurrence, fact status, all five roots, structured primitive or
literal values, ordered union member TypeIDs, and explicit candidate/source
states. Candidate records intentionally omit display text. The shared
`primitive-literal-candidate` canonical fixture is round-tripped by Go and
attached, inspected, and asserted here through OXC.

## Migration boundary

Keep parser-specific traversal and allow-listed span/kind projection in this
Expand All @@ -89,9 +98,11 @@ negotiation in Go. The intended migration sequence is:
explicit and met.

Occurrence identity and attachment plumbing is the first approved mechanical
port category. Primitive/literal record construction is only the next proposed
semantic candidate; all semantic answers remain Go-authoritative until an
independent Rust producer passes ADR-0016's differential gate.
port category. The primitive/literal projection is the first implemented
semantic candidate record, but it consumes Go-produced graph facts and does
not constitute an independent producer. All semantic answers remain
Go-authoritative until an independent Rust producer passes ADR-0016's
differential gate.

Adding a projection does not transfer semantic authority. New parser-boundary
normalizations require a shared fixture and the versioned portable contract.
Loading