Shrink the authored surface: TypeSpec as single source of truth, hand-write only what conformance requires
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 1.3k
- Forks
- 127
- Avg merge
- 9h 23m
- Merged PRs (30d)
- 38
Description
🚀 Feature Request
Prerequisites
- I have checked the latest documentation and this feature doesn't exist
- I have searched for similar feature requests and found none
- I have linked to related issues or discussions in the description (if any exist)
Type of Improvement
Developer Experience
Guiding principle
The TypeSpec spec is the single source of truth. Everything that can be mechanically and predictably derived from the spec should be emitted by the Typra emitter, not hand-ported per runtime. The only code we author by hand is the irreducible minimum required to conform to the vectors and samples — the spec (via @vector/@sample conformance) is what enforces correctness. If a body of code is structurally identical across runtimes and derivable from the schema/seam definitions, it is a bug that we author it 7×.
Current state (measured 2026-08-27, all 7 runtimes)
Classified every non-build source file as generated (carries the Code generated by Typra emitter marker) vs authored; tests separated.
| Runtime | Generated | Authored src | Authored tests | Authored src % |
|---|---|---|---|---|
| go | 77,446 | 6,007 | 1,490 | 7.2% |
| csharp | 65,738 | 10,823 | 11,262 | 14.1% |
| python | 46,269 | 9,445 | 11,302 | 17.0% |
| typescript | 32,550 | 9,422 | 10,247 | 22.4% |
| swift | 21,514 | 7,752 | 8,404 | 26.5% |
| java | 30,796 | 14,831 | 10,874 | 32.5% |
| rust | 49,435 | 26,979 | 10,654 | 35.3% |
Generated ≈ 324k lines vs authored-non-test 85k (~21% of production source). Go is the target shape (7%); Rust is the outlier (35%, 27k authored). The spread itself is the signal — the same runtime concept costs 7% in Go and 35% in Rust, which means most of the delta is mechanical code that should be emitted uniformly.
Where the 85k authored source lives (cross-cutting categories, each duplicated ~7×)
| Category | Authored lines | Mechanization verdict |
|---|---|---|
| core runtime (loader / dispatch / discovery) | 28,829 | Partly — dispatch/discovery already emitted; residue is loader I/O + migration table |
| provider glue (openai / anthropic / foundry) | 22,418 | Largely — wire DTOs + field-mapping are schema; only transport glue is irreducible |
| engine / pipeline (agent loop, turn engine, ctx packing) | 16,616 | Keep — genuine orchestration logic |
| jinja-subset (template engine port) | 6,993 | Yes, but not via TypeSpec — algorithm; single-source + transpile/vendor |
| harness / reference impls | 3,871 | Partly |
| tracing | 3,387 | Yes — structurally identical plumbing |
| seam / vector adapter doubles | 3,145+ | Yes — already schema-derivable |
Proposed Solution
Drive the authored surface down to an irreducible floor by moving each mechanical category into the emitter. Work items, ranked by leverage × predictability:
Tier 1 — pure schema, fits the existing emitter, do first
- Emit the seam/vector adapter doubles. Go
seam_providers.go(1,390), C#VectorProviders.cs, Rustvector_adapters.rs, JavaVectorProviders.javaare mechanically derivable from the seam interface +@dispatchvariant set — proven by hand-writing the Go + Rust versions during the 2.0.2 cycle. Emitting these also eliminates the recurring "fill the doubles by hand after every regen" thrash. Use the existing hand-written Go/Rust doubles as the golden reference for the template. - Emit provider wire DTOs + response field-mapping. A generated wire layer already exists (140 files, e.g.
AnthropicWireMessage), yet every provider re-hand-authors its own: Rustwire.rs1,092 +processor.rs1,338, JavaWire.java573, TSwire.ts549, C#WireFormat.cs323. OpenAI/Anthropic request/response schemas are pure data — emit them and the deterministic field-mapping, leaving only the thin HTTP/SDK call authored.
Tier 2 — structural, needs a tiny spec/data source
3. Emit tracing plumbing (3.4k, 5 runtimes) — identical span/tracer scaffolding.
4. Data-drive the loader legacy-migration table — the v1→v2 rename map is data, currently hand-coded in each migration.*.
Tier 3 — mechanize outside TypeSpec
5. De-duplicate jinja-subset (7k, 7×) — biggest pure duplication, but it's an algorithm, not a schema. Single source-of-truth + transpile, or vendor a real engine.
Irreducible authored floor (the target end-state): executor transport glue, engine/pipeline orchestration, and loader frontmatter/${env}/${file} resolution. Everything else above should be emitted.
Specific flags
- Rust is the priority runtime — at 27k it's 3–4× the leanest. Its provider stack (wire 1,092 + processor 1,338 + executor 893 ≈ 3.3k) and engine+pipeline (~5.4k) are heavier than every peer; it's likely carrying reference-impl weight that should be emitted or trimmed to match the others' generated coverage.
- Emitter-side changes land in the Typra repo (
sethjuarez/typra); the prompty side is regen + gap-fill until vectors/samples stay green. Each Tier-1/2 item should ship red-first with a fixture, consistent with the 2.0.x workflow, and ideally gated invalidate:fixturesso regressions fail Typra CI (as therust.dispatch-regression-compilegate already does).
Definition of done
- Authored-src % converges toward the Go baseline (~single digits) across all runtimes.
- No hand-written seam/vector adapter doubles, provider wire DTOs, or tracing plumbing remain — all emitted.
- The only hand-authored production code is executor transport glue, engine/pipeline orchestration, and loader resolution.
- All 7 runtimes stay green on vectors + samples throughout (spec-enforced conformance).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in the Typra emitter and compare the existing Go seam_providers.go and Rust vector_adapters.rs implementations, which are identified as golden references. Review the provider wire files and the validate:fixtures workflow, including the rust.dispatch-regression-compile gate. Done means the selected mechanical code is emitted, runtime vectors and samples remain green, and authored seam/vector doubles or provider wire DTOs no longer remain for that scope.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, go, java, python, rust, swift, typescript
- Domain
- build-system, developer-experience, testing-qa, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 34/100