Skip to content

feat(core): emit JSON Schema artifacts for the on-disk .basou/ formats - #42

Merged
takashi-matsuyama merged 1 commit into
mainfrom
feat/json-schema-artifacts
Jun 4, 2026
Merged

takashi-matsuyama merged 1 commit into
mainfrom
feat/json-schema-artifacts

Conversation

@takashi-matsuyama

Copy link
Copy Markdown
Member

Summary

@basou/core now ships JSON Schema artifacts for every on-disk .basou/ document, generated from the canonical Zod schemas (zod v4's built-in z.toJSONSchema) so they cannot drift from validation. Non-JavaScript / cross-language tooling and editors can now validate .basou/ files directly. This is the schema-reference artifact unblocked by the @basou/sdk v0.2 keystone (per the operator's own plan: deferred until a programmatic consumer existed).

One schema per document — manifest, session, event (a oneOf over the event type), task, approval, status, task-index, session-import — each a draft 2020-12 document with a stable $id (https://basou.dev/schemas/0.1.0/<name>.schema.json), published under the package's ./schemas/* export (e.g. @basou/core/schemas/session.schema.json) and listed in files.

Design (operator-confirmed)

  • Zod is the single source of truth; JSON Schema is generated + drift-guarded (not hand-authored).
  • 8 document schemas (full on-disk set + import transport).
  • Prefixed-id fields carry a faithful ULID pattern via .meta() on the shared id factory — metadata only, validation behavior unchanged (the .refine still gates acceptance). Verified to accept all 79 real local session ids and reject malformed ones.
  • $id uses basou.dev (a stable identifier; need not resolve).

Correctness (from adversarial review)

Artifacts are generated in io: "input" mode, so they describe what a consumer authors on disk, not Zod's parsed output:

  • a field with a .default() (e.g. events_log) stays optional, not required;
  • a non-strict object allows additive fields (no additionalProperties: false), while the .strict() event variants (e.g. adapter_output) keep additionalProperties: false.

Without this, the artifacts would falsely reject valid on-disk files — the opposite of their purpose.

Generation & guards

  • pnpm --filter @basou/core gen:schemas builds, then regenerates the committed packages/core/schemas/*.json from buildJsonSchemas().
  • A drift-guard test asserts every committed file matches the Zod source byte-for-byte (a schema change without regeneration fails CI).
  • An ajv draft-2020-12 round-trip test validates a representative document per schema, plus the input-mode cases and that the ULID pattern rejects a malformed id (this is what would have caught the input-vs-output bug).
  • The generated schemas/ dir is excluded from biome (a generated artifact, like dist).

Compatibility

Additive: new ./schemas/* export, gen:schemas script, and ajv/ajv-formats devDependencies. No @basou/core runtime-API or on-disk-format change. Branches from main (which now carries #40 + #41).

Test plan

  • pnpm -r build && pnpm typecheck && pnpm test && pnpm lint all green (core 732 + sdk 17 + cli 417; lint clean apart from pre-existing unrelated warnings).
  • Regeneration is deterministic (re-running gen:schemas yields no diff).
  • ajv round-trip confirms each emitted schema compiles and accepts real documents.

🤖 Generated with Claude Code

`@basou/core` now ships JSON Schema artifacts for every on-disk `.basou/`
document, generated from the canonical Zod schemas (zod v4's built-in
`z.toJSONSchema`) so they cannot drift from validation. Non-JavaScript /
cross-language tooling and editors can now validate `.basou/` files directly,
without reimplementing the format.

One schema per document: manifest, session, event (a `oneOf` over the event
type), task, approval, status, task-index, and session-import. Each is a draft
2020-12 document with a stable `$id`
(`https://basou.dev/schemas/0.1.0/<name>.schema.json`), published under the
package's `./schemas/*` export (e.g. `@basou/core/schemas/session.schema.json`)
and listed in `files`.

The artifacts describe what a consumer AUTHORS on disk: generated in
`io: "input"` mode so a field with a `.default()` (e.g. `events_log`) stays
optional rather than required, and a non-strict object allows additive fields;
only the `.strict()` event variants (e.g. `adapter_output`) keep
`additionalProperties: false`. Prefixed-id fields carry a faithful ULID
`pattern` via schema metadata on the shared id factory (validation behavior is
unchanged; the existing `.refine` still gates acceptance). Other
refinement-only constraints are not expressible in JSON Schema and are omitted.

Generation and guards:
- `pnpm --filter @basou/core gen:schemas` builds, then regenerates the
  committed `packages/core/schemas/*.json` from `buildJsonSchemas()`.
- A drift-guard test asserts every committed file still matches the Zod source
  byte-for-byte, so a schema change without regeneration fails CI.
- An ajv (draft 2020-12) round-trip test validates a representative document
  per schema, plus the input-mode cases (defaulted fields may be omitted; a
  non-strict event accepts an additive field) and that the ULID pattern
  rejects a malformed id.
- The generated `schemas/` dir is excluded from biome (a generated artifact,
  like `dist`), so the formatter does not fight the generator's output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@takashi-matsuyama
takashi-matsuyama merged commit 7802da4 into main Jun 4, 2026
7 checks passed
@takashi-matsuyama
takashi-matsuyama deleted the feat/json-schema-artifacts branch June 4, 2026 14:45
takashi-matsuyama added a commit that referenced this pull request Jun 4, 2026
…s) (#43)

Promote the Unreleased section to 0.6.0 and bump all four package
manifests (core / cli / sdk / basou) to 0.6.0 in lockstep.

Highlights since 0.5.0:
- billing-grade work-measurement v2: Codex active time from real
  per-turn intervals, plus a machine_active_time_ms model-compute
  measure (#40).
- @basou/sdk v0.2: a runtime, read-only programmatic API over
  @basou/core's readers for reading .basou/ provenance (#41).
- @basou/core JSON Schema artifacts for the on-disk formats, generated
  from the Zod schemas and shipped under ./schemas/* (#42).

Also: document the four-package lockstep bump in CONTRIBUTING, and
record the 0.6.0 pre-publish dry-run tarball contents in the release
checklist (core now ships its schemas/, cli ships two entry points).

This commit only prepares the release; tagging v0.6.0 and the OIDC
publish remain maintainer actions.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant