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
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ jobs:
run: cargo clippy --locked --manifest-path internal/oxc_reference/Cargo.toml --all-targets -- -D warnings
- name: Test internal OXC reference consumer
run: cargo test --locked --manifest-path internal/oxc_reference/Cargo.toml
- name: Gate Go versus Rust semantic conformance
run: ./internal/oxc_reference/run-conformance.sh --output go-rust-conformance.json
- name: Upload Go versus Rust conformance report
- name: Run controlled Go versus Rust primitive/literal rollout
run: ./internal/oxc_reference/run-rollout.sh --output primitive-literal-rollout.json
- name: Upload primitive/literal rollout report
if: ${{ always() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: go-rust-semantic-conformance
path: go-rust-conformance.json
name: primitive-literal-go-rust-rollout
path: primitive-literal-rollout.json

build:
runs-on: ubuntu-latest
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ plus response-local symbol, alias, and declaration provenance. An isolated
Rust/OXC consumer exercises that contract as a reference and migration harness;
TypeScript 7's Go checker remains the semantic oracle.

The current [migration decision](docs/adr/0019-compute-primitive-literals-independently-in-rust.md)
and [measured evidence](docs/evidence/ts7-oxc-spike-2026-08-17.json) approve no
Rust semantic replacement. An independent Rust/OXC primitive/literal producer
now runs under exact differential comparison while Go remains the production
fallback and semantic authority. The
The current [migration decision](docs/adr/0020-keep-primitive-literals-shadow-only-after-dual-run.md)
and [controlled rollout evidence](docs/evidence/primitive-literal-rollout-2026-08-17.json)
approve no Rust semantic replacement. An independent Rust/OXC primitive/literal
producer now runs under exact differential comparison while Go remains the
production fallback and semantic authority. The
compatibility boundary and current exclusions are tracked in the
[migration contract](docs/porting/migration-contract.md), and durable
implementation choices are recorded in [ADRs](docs/adr/README.md).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# ADR-0020: Keep primitive/literal production shadow-only after the controlled dual-run

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

## Context

ADR-0019 established an independent Rust/OXC primitive/literal producer and an
exact differential gate against the TypeScript 7 Go checker. The expanded
corpus proves a useful semantic slice, but passing that gate alone does not show
that the category can be served, rolled back, or compared under a
production-equivalent runtime and memory boundary.

Issue #47 requires a controlled dual-run over the same checked-out corpus,
compiler revision, request, capabilities, and budgets. The evidence must retain
semantic, transport, mapping, unsupported, and budget classifications while
also recording runtime, memory, and output size without turning noisy host
measurements into deterministic compatibility fields.

## Decision

`./internal/oxc_reference/run-rollout.sh --output <path>` builds the real Go
`tsfacts` command and the release Rust reference binary, then executes two
complete ordered dual-runs. Each run sends the same manifest-derived requests
to the pinned TypeScript compiler and independent Rust producer. Only the
comparator receives both outputs.

The embedded conformance report is deterministic and must be byte-identical
between the two runs. It records the repository and TypeScript revisions,
request schema, project, ordered capabilities, budgets, selections, all five
roots, response-local identity, structured payloads, diagnostics,
completeness, recovery, truncation, unsupported states, mapping, and classified
differences. Unexplained semantic, transport, or mapping differences fail the
command.

Runtime and output sizes are retained as two ordered measurement samples.
Artifact sizes and the controller's peak or current resident memory are
recorded with their measurement method and scope. These measurements are
characterization data: the Go lane includes a one-shot process and JSON Lines
transport, while Rust runs in-process, and controller RSS excludes the Go child
process. The measured fields are therefore not part of the byte-stability gate
and do not establish a performance advantage.

The primitive/literal category is **not ready for a later authority decision**.
Rust remains shadow-only. Go remains both the serving semantic authority and
the production fallback. There is no authority switch, TS7 producer protocol
change, external consumer behavior change, or Palamedes change.

## Remaining blockers

- Four explicitly classified selections remain outside the supported Rust
slice.
- Three recovery selections retain the expected OXC parser/mapping gap.
- Rust is not integrated into the serving path, so production fallback,
rollback, and shadow observation at that boundary have not been exercised.
- Runtime and output-size samples do not yet use one production-equivalent
process or library boundary for both implementations.
- The evidence does not isolate peak resident memory for the Go child process,
so per-producer memory parity is not established.

A later authority proposal must close or explicitly re-scope these blockers,
rerun the supported platform matrix, preserve Go fallback, and create a new ADR
that authorizes the category-specific switch. This record does not authorize
that proposal.

## Consequences

- CI now retains one structured rollout artifact containing deterministic
conformance, coverage, compatibility, mapping, runtime, memory, and output
size evidence.
- Host-dependent measurements remain reproducible through a documented command
without weakening the exact semantic gate.
- A green rollout job means that shadow comparison is healthy. It does not mean
the category is production-ready or approved to replace Go.

## References

- [RFC 0001](../../rfcs/0001-semantic-facts-kernel.md)
- [ADR-0019](0019-compute-primitive-literals-independently-in-rust.md)
- [Checked rollout evidence](../evidence/primitive-literal-rollout-2026-08-17.json)
- [Issue #47](https://github.com/swernerx/typescript-semantic-kernel/issues/47)
10 changes: 7 additions & 3 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ decision is recorded in a successor ADR that links to the record it replaces.
| [0017](0017-project-primitive-literal-candidates-from-go-graph-identity.md) | Superseded | Project primitive/literal candidates from Go graph identity |
| [0018](0018-gate-rust-semantics-against-the-go-oracle.md) | Superseded | Gate Rust semantics against the Go oracle |
| [0019](0019-compute-primitive-literals-independently-in-rust.md) | Accepted | Compute primitive/literal candidates independently in Rust |
| [0020](0020-keep-primitive-literals-shadow-only-after-dual-run.md) | Accepted | Keep primitive/literal production shadow-only after the controlled dual-run |

## Current migration decision

Expand All @@ -40,6 +41,9 @@ advantage.
[ADR-0019](0019-compute-primitive-literals-independently-in-rust.md) runs an
independent Rust/OXC primitive/literal producer over the tagged shared corpus
and enforces exact structured agreement in shadow CI. It owns its type graph
and receives no Go semantic graph input. Passing the gate still leaves
primitive/literal construction Go-authoritative in production; no semantic
category is currently approved for replacement.
and receives no Go semantic graph input.
[ADR-0020](0020-keep-primitive-literals-shadow-only-after-dual-run.md) records
the controlled rollout evidence and the remaining unsupported, recovery,
production-integration, measurement-boundary, and memory blockers.
Primitive/literal construction remains Go-authoritative in production; no
semantic category is currently approved for replacement.
19 changes: 19 additions & 0 deletions docs/evidence/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,22 @@ answer from source and OXC semantics without receiving the Go graph. It passes
an exact shadow differential gate but is not an approved production
replacement. The TypeScript 7 Go checker remains authoritative and available
as the production fallback.

The checked
[`primitive-literal-rollout-2026-08-17.json`](primitive-literal-rollout-2026-08-17.json)
record is generated by:

```sh
./internal/oxc_reference/run-rollout.sh \
--output docs/evidence/primitive-literal-rollout-2026-08-17.json
```

It embeds the exact primitive/literal conformance report and requires that
stable report to be byte-identical across two complete dual-runs. Runtime,
resident memory, artifact size, and producer-output size are retained in a
separate measurement section because those values or their comparison boundary
vary by host. The report is a shadow rollout artifact, not an authority switch
or a general benchmark.

[ADR-0020](../adr/0020-keep-primitive-literals-shadow-only-after-dual-run.md)
records why the category is not ready for a later authority decision.
Loading