@nekostack/schema 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +19 -128
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -8,10 +8,9 @@
8
8
  |---|---|
9
9
  | **Build tier** | Foundation primitive — build first |
10
10
  | **Depends on** | (none — foundational). External: TypeScript (dev/build). Peer: Zod (for runtime validation; not required at IR level). |
11
- | **Used by** | `api`, `cli`, `codex`, `auth`, `form`, `config`, `events`, `telemetry`, `validator`, `id`, `entitlements`, `lint` (rule authoring), and effectively everything else |
11
+ | **Used by** | `@nekostack/cli` (published); `api`, `form`, `auth`, `config`, `events`, `telemetry`, and others (planned) |
12
12
  | **Status** | **v1.0 — released.** Canonical IR + Zod / JSON Schema / OpenAPI / TypeScript generators + runtime validation. 1,294 tests; public surface frozen. |
13
13
  | **Released** | [`schema-v1.0.0`](./CHANGELOG.md) — API frozen. Reserved-but-unbuilt IR capacity (unions, lazy/recursive refs, transforms, dates) lands in post-1.0 minors. |
14
- | **Sellable?** | Not as the package itself. It's the **technical substrate** for a future registry/governance product. Schema-as-a-service requires registry + diffing + history + governance + CI integration on top — see [Product potential](#product-potential). |
15
14
 
16
15
  ## Why this exists
17
16
 
@@ -22,9 +21,8 @@ Every non-trivial app defines the same data shape in multiple places: TypeScript
22
21
  Building this rather than adopting Zod is justified because:
23
22
 
24
23
  1. **Zod is one output target, not the source.** A Zod-as-source architecture forces every non-Zod consumer to glue through adapters that drift.
25
- 2. **You learn schema-system internals end-to-end** — IR design, generator architecture, type-level TypeScript, JSON Schema semantics, OpenAPI 3.1 nuances, semantic-loss management.
26
- 3. **Outputs target NekoStack's specific consumers** — the Zod output knows about NekoStack's normalized `Issue` shape; the OpenAPI output knows how NekoStack APIs version themselves.
27
- 4. **No vendor coupling.** Zod 4 introduces a breaking change? The generator emits Zod 3 syntax until you choose to migrate.
24
+ 2. **Outputs target NekoStack's specific consumers** — the Zod output knows about NekoStack's normalized `Issue` shape; the OpenAPI output knows how NekoStack APIs version themselves.
25
+ 3. **No vendor coupling.** Zod 4 introduces a breaking change? The generator emits Zod 3 syntax until you choose to migrate.
28
26
 
29
27
  ## Scope
30
28
 
@@ -50,7 +48,7 @@ Building this rather than adopting Zod is justified because:
50
48
 
51
49
  ## Boundary
52
50
 
53
- > See [`BOUNDARIES.md`](../../BOUNDARIES.md) §7 for the full capability map.
51
+ > See BOUNDARIES.md §7 in the NekoStack repository for the full capability map.
54
52
 
55
53
  ### Owns
56
54
  - Canonical IR (`SchemaNode` AST)
@@ -407,36 +405,14 @@ The package can *generate* Zod without *requiring* Zod at runtime; consumers wan
407
405
 
408
406
  ---
409
407
 
410
- ## Competitors and adjacent tools
411
-
412
- | Tool | What they do well | Where they fall short for us |
413
- |---|---|---|
414
- | **Zod** | Excellent runtime validator, great TS inference, large ecosystem; ~all NekoStack consumers will run *generated* Zod at runtime. | Zod-as-source forces every non-Zod consumer through adapters that drift. We emit Zod as one output target; we don't make Zod the source format. |
415
- | **TypeBox** | JSON-Schema-first, fast, multi-target. | DSL is verbose and less TS-native; closer in spirit to our approach but with different priorities. |
416
- | **Effect-Schema** | Extremely powerful, principled, multi-output. | Steep learning curve, deep Effect ecosystem coupling, overkill for solo dev. |
417
- | **io-ts** | Mature, principled. | Verbose, weaker TS inference than Zod, declining ecosystem. |
418
- | **Valibot** | Tree-shakeable Zod alternative. | Same single-output limitation as Zod. |
419
- | **JSON Schema (raw)** | Universal interchange format. | Hand-written JSON is hostile to author and review. |
420
- | **TypeBox + zod-from-json-schema** | Multi-tool stack. | Toolchain becomes the spec — fragile, hard to evolve consistently. |
421
-
422
- The right framing — corrected from the original audit critique:
423
-
424
- > NekoStack is not "better Zod." It is a **schema IR + generator system** that emits Zod as one target alongside JSON Schema, OpenAPI, and TypeScript. The unique value is multi-output semantic consistency, not DSL ergonomics.
425
-
426
408
  ## How this fits the NekoStack
427
409
 
428
410
  **Depends on:** Nothing within NekoStack. This is foundational — every other package may depend on it.
429
411
 
430
- **Used by:**
431
- - `@nekostack/api` — generates OpenAPI components.
432
- - `@nekostack/form` — drives form rendering + validation.
433
- - `@nekostack/cli` validates command-line inputs.
434
- - `@nekostack/codex` — validates entity shape definitions.
435
- - `@nekostack/auth` — typifies token claims + `AccessDecision` shapes.
436
- - `@nekostack/config` — boot-time env + runtime config validation.
437
- - `@nekostack/events` — event payload shapes.
438
- - `@nekostack/telemetry` — typed event catalog shapes.
439
- - Effectively everything that crosses a system boundary.
412
+ **Published packages that consume schema:**
413
+ - `@nekostack/cli` — schema validation, codegen, and diff commands.
414
+
415
+ **Planned:** `@nekostack/api`, `@nekostack/form`, `@nekostack/auth`, `@nekostack/config`, `@nekostack/events`, `@nekostack/telemetry`, and others in the NekoStack ecosystem all plan to consume this package as their data-shape substrate.
440
416
 
441
417
  ## Design philosophy
442
418
 
@@ -500,56 +476,12 @@ export type User = s.infer<typeof User>;
500
476
 
501
477
  ## Roadmap
502
478
 
503
- Revised after the design-audit pass. Migrations pushed from v0.5 to v0.8+ because the migration problem is much bigger than the original scope acknowledged.
504
-
505
- ### v0.1Core IR + builders
506
- - `SchemaNode` IR + serialization.
507
- - Primitive builders (string / number / boolean / literal / enum).
508
- - Object builder (strict default), array builder, named schemas with `.id()` / `.version()` / `.describe()`.
509
- - Metadata: id, version, description, deprecated flag.
510
- - Basic `Issue` shape, normalized codes.
511
- - TypeScript type inference (`s.infer<T>`).
512
- - Builder unit tests + type inference tests.
513
-
514
- ### v0.2 — TypeScript + Zod generation
515
- - TS generator (`.d.ts` output).
516
- - Zod generator (Zod 3.x target initially).
517
- - Deterministic header.
518
- - Snapshot tests for generator output.
519
- - Zod-execution tests (generated validator runs and matches fixtures).
520
-
521
- ### v0.3 — JSON Schema generation
522
- - JSON Schema draft 2020-12 output.
523
- - `$id` / `$defs` / `$ref` per identity rules.
524
- - Portable constraint mapping (min/max/regex/format/etc.).
525
- - Semantic-loss metadata for runtime-only refinements (`x-nekostack-runtime-refinement`).
526
- - JSON Schema test-suite conformance.
527
-
528
- ### v0.4 — OpenAPI 3.1 generation
529
- - OpenAPI 3.1 component schemas.
530
- - Integration fixtures for `@nekostack/api`.
531
- - Nullable / required mapping per the Absence Semantics table.
532
- - Round-trip tests with `@redocly/openapi-core`.
533
-
534
- ### v0.5 — Composition
535
- - `extend`, `pick`, `omit`, `partial`, `required`.
536
- - Conflict-safe `merge` with explicit `override`.
537
- - Composition tests covering conflict cases.
538
-
539
- ### v0.6 — Runtime validation
540
- - `validate(schema, input)` returning `Result<T, Issue[]>`.
541
- - Unknown-key handling (strict / stripUnknown / passthrough).
542
- - Zod-backed execution (runtime delegates to generated Zod).
543
- - Issue normalization (raw Zod issues → NekoStack `Issue` codes).
544
- - Semantic-parity tests: same fixture validated against Neko runtime, generated Zod, JSON Schema validator, OpenAPI-compatible schema — expected failures match.
545
-
546
- ### v0.7 — Registry-lite
547
- - Local schema registry (lookup by id + version).
548
- - Schema diffing between two versions.
549
- - Breaking-change detection per the matrix below.
550
- - `neko schema check` (freshness) and `neko schema diff` (changes).
551
-
552
- **Breaking-change matrix** (v0.7 implementation target):
479
+ v1.0 is the stable, API-frozen baseline. Post-v1.0 work:
480
+
481
+ - **Reserved IR capacity** `s.union()`, `s.lazy()` (recursive), `s.transform()`, and full date typing are in the IR type system; generator support for the full surface lands in post-v1.0 minors.
482
+ - **Registry-lite** — local schema registry, schema diffing between versions, and breaking-change detection (`neko schema diff`).
483
+
484
+ **Breaking-change matrix** (registry-lite target):
553
485
 
554
486
  | Change | Compatibility |
555
487
  |---|---|
@@ -566,21 +498,9 @@ Revised after the design-audit pass. Migrations pushed from v0.5 to v0.8+ becaus
566
498
  | Rename field | **breaking** in all directions unless explicitly aliased |
567
499
  | Add discriminated-union branch | non-breaking for consumers using fallback; breaking otherwise |
568
500
 
569
- `neko schema diff <a> <b>` prints the change list with these annotations. CI in consuming projects can fail on any `breaking` change without a deliberate `--accept-breaking` flag.
570
-
571
- ### v0.8+Migrations
572
- - Migration registry with version graph.
573
- - Forward migrations between versioned schemas.
574
- - Pre/post migration validation.
575
- - Migration provenance and audit.
576
- - Failure behavior + downgrade policy.
577
- - Fixture tests per version pair.
578
-
579
- ### v1.0 — Stable API
580
- - Full documentation site.
581
- - Migration guide from Zod-as-source.
582
- - Performance benchmarks vs Zod and TypeBox.
583
- - Companion spec docs (deferred from v0.x): full Issue code catalog, generated-artifact policy details, testing strategy.
501
+ - **Schema migrations** forward migration registry, version graph, migration provenance + audit.
502
+ - **Generator plugin contract** — stable contract for third-party generators (Prisma DDL, GraphQL SDL, etc.).
503
+ - **Performance benchmarks** vs Zod and TypeBox.
584
504
 
585
505
  ## Testing strategy
586
506
 
@@ -602,30 +522,9 @@ Revised after the design-audit pass. Migrations pushed from v0.5 to v0.8+ becaus
602
522
 
603
523
  Semantic parity is the load-bearing test category. Where the four outputs cannot match (runtime-only refinements being the prime case), the test asserts the *expected gap*, not equality.
604
524
 
605
- ## Product potential
606
-
607
- **Internal use:** Mandatory. The whole stack rests on this.
608
-
609
- **Open-source release:** Strong candidate. The multi-output semantic-consistency angle is genuinely undersupplied. MIT-licensed release with good docs could attract real users — particularly TS teams running multi-language stacks (TS frontend + Python backend, or generating SDKs for non-TS consumers).
610
-
611
- **Commercial product (corrected from the original brief):** `@nekostack/schema` is **not the commercial product by itself**. It is the technical substrate for a future registry/governance product. A schema package becomes commercially interesting only when paired with:
612
-
613
- - Hosted schema registry with version history
614
- - Cross-version diffing + breaking-change detection
615
- - SDK / codegen integration (à la Speakeasy / Stainless, but one layer earlier)
616
- - Schema governance + team permissions
617
- - CI integration (PR-level schema-change review)
618
- - Changelog generation
619
- - Compliance export
620
- - Migration tracking
621
-
622
- That commercial product would be a separate offering (e.g., `@nekostack/schema-cloud` or NekoSystems' enterprise tier consuming this) — built on top of this primitive. Not a near-term focus, but the path is real.
623
-
624
- **Estimated effort to v1.0:** 6–12 weeks of focused work; more realistically 4–8 months at solo-dev cadence. Revised up from the original 4–8 / 3–6 because the IR + semantic-loss + identity + parity-test work added scope.
625
-
626
525
  ## Locked Design Decisions (v1.0 Freeze)
627
526
 
628
- These decisions were explicitly closed to harden the public API surface for v1.0. They are not up for debate.
527
+ These are stable API contracts guaranteed not to change in v1.x.
629
528
 
630
529
  - **No Async Refinements.** `refineAsync` is explicitly rejected. Validation must remain a pure, synchronous, CPU-bound operation. If a check requires I/O (e.g., querying a database to see if a username is taken), it is **Business Logic**, not **Shape Validation**, and belongs in a Controller or Service.
631
530
  - **Recursive Schema Cycles (`A → B → A`).** `s.lazy()` MUST take a string ID representing the target schema (e.g., `s.lazy("com.nekostack.User")`). The compiler does not attempt to resolve this during definition. It is resolved safely at runtime by querying the `schemaRegistry`. If the ID doesn't exist, it throws `recursive_reference_unresolved`.
@@ -645,12 +544,4 @@ Items here should graduate into the Implementation contracts section once decide
645
544
 
646
545
  ## Status
647
546
 
648
- - **Current:** Foundation underway. **Released through schema-v0.8.0** (~7.4k LOC, 1.3k tests).
649
- - **Owner:** Cody (solo dev project).
650
- - **Priority tier:** Foundation primitive.
651
- - **Estimated learning return:** Very high. Schema-system design, type-level TypeScript, code-gen architecture, JSON Schema semantics, OpenAPI 3.1 internals, semantic-loss management, deterministic output discipline — all in one project.
652
- - **Source thinking:**
653
- - Initial audit: [`references/schema/design-audit-2026-05.md`](../../references/schema/design-audit-2026-05.md) — drove the IR / semantic-loss / identity / strict-by-default / migration-deferral additions.
654
- - Follow-up audit: [`references/schema/design-audit-2026-05-followup.md`](../../references/schema/design-audit-2026-05-followup.md) — drove the Transform input/output split, Union policy, validate-vs-parse, coercion policy, IR hash, breaking-change matrix, and the Still-open section.
655
-
656
- Future significant design changes should generate a similar audit document and link from here. The pattern is: audit → revise → preserve source thinking → label open decisions → repeat as design matures.
547
+ v1.0 public API frozen. 1,294 tests passing. See the [CHANGELOG](./CHANGELOG.md) for release history.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nekostack/schema",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "private": false,
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",