feat(spike): prove Effect v4 canonical schema and adapters end-to-end (Entry + Event) - #7
Draft
obvious-autobuild[bot] wants to merge 1 commit into
Draft
obvious-autobuild[bot] wants to merge 1 commit into
obvious-autobuild[bot] wants to merge 1 commit into
Conversation
Bounded compatibility spike in spikes/effect-compat/ on effect@4.0.0-rc.115, convex@1.46.0, openai@7.17.0: - Canonical executable Entry + Event schema with fully inferred TS types (six categories, DateFromMillis codec, bounded confidence, optional quantity). - JSON Schema derivation via Schema.toJsonSchemaDocument (draft-2020-12), verified with real imports; effect/JSONSchema is gone in v4 and toStandardJSONSchemaV1 yields no document on this pin. - Effect schema -> Convex validators adapter (single sanctioned bridge) with encode -> convexToJson -> jsonToConvex -> decode round-trip deep-equality tests and loud failure on unsupported representations. - LLM extraction contract: captureId + attempt envelope with stale-result suppression and idempotent-completion requirements; strict schema decode; OpenAI provider behind OPENAI_API_KEY, fully mocked in tests. - Entry publication visibility (draft|published) kept separate from audience permissions (household/relationship-scoped) as independent dimensions. - FINDINGS.md with pinned versions, verified behaviors, and gotchas; 37/37 vitest tests passing, tsc --noEmit strict clean. Co-authored-by: Gilbert Polanco <gilbertpolanco42@gmail.com>
Merged
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The monorepo's domain layer is bet on schema-first contracts, but nobody had proven that Effect v4 (rc line) can actually carry the canonical journal schema across all three boundaries it must survive: inferred TypeScript types, derived JSON Schema (for LLM function calling), and Convex validators (persistence). This spike proves that chain end-to-end on ONE canonical schema — Entry + Event — with every claim test-verified and every version pinned, so the scaffold's
packages/domaincan integrate against evidence instead of guesses.What
All under
spikes/effect-compat/(bounded scope — no scaffold files touched):src/schema.ts) oneffect@4.0.0-rc.115: six event categories (potty|meal|sleep|mood|milestone|school),DateFromMillistimestamp codec, bounded confidence (isBetween(0,1)), optional quantitative payload, author attribution, taggedEntry+Eventstructs. All TS types inferred viaSchema.Schema.Type— zero hand-written interfaces.src/json-schema.ts):Schema.toJsonSchemaDocumentproduces a real draft-2020-12 document (category enum, integer timestamps, bounded confidence — verified by running it). Two negative results recorded with evidence:effect/JSONSchemano longer exists in v4, andtoStandardJSONSchemaV1yields no document on this pin.src/convex-adapter.ts): walks the publicSchemaRepresentationtree and emitsconvex/valuesvalidators for the encoded wire form. Round-trip proven:encode → convexToJson → jsonToConvex → decodedeep-equal, Dates restored, absent optionals survive. Unsupported shapes (tuples, index signatures) fail loudly withUnsupportedRepresentationError— never silently. Gotcha recorded for the scaffold owner: Convex 1.46 marks optionality asisOptional: 'required'|'optional'on the validator itself; truthiness checks on that string silently break optionality.src/llm/contract.ts+openai.ts): transcript in → typed events out, always decoded through the canonical schema (strict fail-fast with the failing index). Typed errors only (ProviderFailure/MalformedModelOutput/EventsFailedSchema). Results carry acaptureId+ monotonically increasingattemptenvelope: client interruption does NOT cancel a running server extraction — the backend completes it idempotently, and stale attempts are suppressed (only the latest attempt per capture applies). OpenAI sits behindOPENAI_API_KEYbehind a structural client so tests are fully mocked and offline.Entry.visibility: 'draft'|'published'is per-entry publication state only; WHO may see a shared entry is resolved from household/relationship grants and is deliberately not modeled on the entry — no fused status enum, no audience field. Pinned by tests.Verification:
bunx tsc --noEmitstrict-clean;bunx vitest run→ 37/37 passing across 4 suites. Full details, pinned versions, and non-goals inFINDINGS.md.How to Review
FINDINGS.md— it is the deliverable's summary of what was proven vs. explicitly not proven (live OpenAI calls, tuple/index-signature support, Convex deployment are all out of scope).packages/domain. This PR is for the record — do not merge; findings feed the scaffold PR.scripts/probe-*.mjsare the exploratory probes kept as evidence of the version-behavior checks (not production code).Test Evidence
Local: strict typecheck clean;
bunx vitest run37/37 passing (schema semantics, JSON Schema derivation, adapter structure + Convex round-trips, mocked LLM contract incl. env-key gating). Suite runs fully offline — no network, no API key.Human author: Gilbert Polanco (gilbertpolanco42@gmail.com)
🔗 Obvious Project · 🧵 Obvious Thread