Problem
engine/sniff.go yaml-decodes the input and knows exactly two keys (openapi, swagger). Of the five planned compilers, three consume non-YAML inputs — TypeSpec source, GraphQL SDL, .proto — for which yaml.Unmarshal fails and Sniff returns a decode error rather than "unrecognized format". Each new compiler therefore requires editing the engine's sniffing internals, and the knowledge of "what my input looks like" lives in the wrong layer: a compiler self-describes Formats() but not how to recognize them. Changing the Compiler interface is cheap with one implementation and expensive with six.
Proposed direction
Add a detection seam that travels with the compiler — either Detect(path string, data []byte) (SourceFormat, bool) on the Compiler interface or a sniffer registered alongside it in the Registry — and have the engine iterate registered detectors in deterministic order, keeping the current YAML probe as the OpenAPI compiler's detector. Extension-based hints (.proto, .graphql, .tsp) then live with their formats. Size: S–M.
Related but separable: today's sniff also full-parses the whole document to read two top-level keys (a third full parse of the input; 231 ms on a 3.5 MB spec). Whichever shape the seam takes, prefer a bounded prefix decode with full-parse fallback, so detection cost stops scaling with document size.
Acceptance
Problem
engine/sniff.goyaml-decodes the input and knows exactly two keys (openapi,swagger). Of the five planned compilers, three consume non-YAML inputs — TypeSpec source, GraphQL SDL,.proto— for whichyaml.Unmarshalfails andSniffreturns a decode error rather than "unrecognized format". Each new compiler therefore requires editing the engine's sniffing internals, and the knowledge of "what my input looks like" lives in the wrong layer: a compiler self-describesFormats()but not how to recognize them. Changing theCompilerinterface is cheap with one implementation and expensive with six.Proposed direction
Add a detection seam that travels with the compiler — either
Detect(path string, data []byte) (SourceFormat, bool)on theCompilerinterface or a sniffer registered alongside it in theRegistry— and have the engine iterate registered detectors in deterministic order, keeping the current YAML probe as the OpenAPI compiler's detector. Extension-based hints (.proto,.graphql,.tsp) then live with their formats. Size: S–M.Related but separable: today's sniff also full-parses the whole document to read two top-level keys (a third full parse of the input; 231 ms on a 3.5 MB spec). Whichever shape the seam takes, prefer a bounded prefix decode with full-parse fallback, so detection cost stops scaling with document size.
Acceptance