Spike-X-prime ran 2026-05-22 against INHERIT v2 LinkML schemas (probate/trusts/wills/assets/transfer; 26 classes / 3945 LOC). Outcome: outcome-VALIDATED-WITH-NOTE.
Why: Q15 SDK choice cost-correction (A-273) made Speakeasy financially unattractive (£11.4K/yr Phase-1 → £28.5K/yr Phase-1.5+). A-274 commissioned this spike to test whether a free-stack composition (openapi-generator + Zod + gen-pydantic-v2 + custom Arazzo + custom MCP + oasdiff + Schemathesis) can deliver Q15-equivalent capabilities at acceptable custom-glue cost. It can — 4 PASS / 2 PARTIAL / 1 substrate-deferred / 0 FAIL across 7 criteria.
How to apply: When INHERIT-v2 SDK substrate decisions surface, prefer free-stack pipeline over Speakeasy. The prototypes at /tmp/spike-x-prime/criterion-{e,f,g}/ are ready to graduate to code-inheritkit/src/spike-prime/. Total prototype LOC: 334 (Arazzo validator Python) + 429 (Arazzo→MCP mapper TS) = 763 — well under per-criterion budgets (≤500 + ≤800 = ≤1300).
Known limitations to track (each has a documented workaround):
- (a’) openapi-generator skips pass-body role classes (WitnessRole, ExecutorRole, TestatorRole) as “free-form objects”. openapi-zod-client emits
z.object({}).partial(). Workaround: emit explicitallOf:[Role]in JSON Schema OR use LinkML’s gen-typescript direct path (~50-100 LOC envelope tweak). - (c’) mergeimports semantics N/A at current substrate — modules only import
linkml:types. Cross-module FK is by-annotation. Reactivation trigger = when 9-module schema introduces formalimports:declarations. - (d’) JSON Schema dialect URI inconsistency — LinkML 1.10.0 declares
$schema: draft/2019-09/schemabut uses$defs(2020-12 keyword). My OpenAPI envelope explicitly declares 2020-12 dialect to compensate. Cosmetic. - (g’) Schemathesis surface PARTIAL — v4.19.0 parses INHERIT v2 OpenAPI cleanly (exit 0) but full property-based runs need a running server + OpenAPI examples. Workaround: FastAPI/Express wrapper around generated SDK + sample-data generator (~150 LOC + 1 sprint integration).
- (f’) MCP round-trip via InMemoryTransport — production-ready stdio MCP server with auth+audit+retry needs ~400-500 LOC additional engineering.
Decision Matrix #10 fires: recommend Q15 lock SDK-generator-line update from Speakeasy to free-stack composition; draft A-NNN amendment in closure-bundle for Rich approval; Spike-X (Speakeasy) marked SUPERSEDED (no need to run unless free-stack hits unforeseen production blocker during Phase-1 Sprint 1).
Empirical determinism evidence: 80 byte-identical outputs across 6 toolchain variants × N=5 trials each (gen-pydantic 25, openapi-generator 20, openapi-zod-client 20, mergeimports A 5, mergeimports B 5, Arazzo validator 5).
Companion: stainless-acquired-by-anthropic-2026-05-18 (parallel Stainless FOSS path closed by Anthropic acquisition). gsd-installer-preserves-user-baseline-since-1-41 (unrelated; tool-set housekeeping context).
Cross-references:
- T-file:
~/off-github/library/projects/inherit/T-spike-free-stack-fidelity-X-2026-05-22.md - Closure-bundle:
/tmp/spike-x-prime/closure-bundle.md(proposed A-NNN amendment row + BUILD-PLAN annotation drafted) - Prototype code:
/tmp/spike-x-prime/criterion-{e,f,g}/ - A-273 cost-correction parent + A-274 commissioning amendment + A-275 Stainless invalidation:
inherit-v2-architecture-state.mdv4.66+ §15