fix(core): guard non-Zod memory schema instead of silently casting it#279
Conversation
The remember tool's `data` shape comes from `context.memory.schema`, which arrives as `unknown` (loaded via dynamic import, validated structurally). The previous `as z.ZodTypeAny` cast was silent: a non-Zod value (absent, or a plain JSON-Schema object) was handed to `z.object()` and blew up with an opaque "expected a Zod schema" error at tool-schema use time. Guard it with an `isZodSchema` check and fall back to a permissive record instead. Also documents `runMemoryCommand`'s `@dawn-ai/cli/runtime` export as a test-only surface, not a stable public API. Addresses the advisory review feedback carried over from #257. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @blove's task in 1m 11s —— View job Code Review
Overall: looks good. The runtime guard is the right fix — as the PR description explains, narrowing Two minor findings (both inline):
Nothing blocking. The changeset classification ( |
The guard helper has no closure dependencies and load() runs per-request, so keep it module-scoped rather than recreating it each call. Addresses review feedback on #279. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @blove's task in 1m 51s —— View job Code Review
Both findings from the prior review are now resolved. Nothing blocking here. Previous finding #1 — Previous finding #2 — Guard correctness: The Test coverage: Both paths are covered — fallback for a plain JSON-Schema object, and the happy path confirming the real schema rejects wrong-typed fields. Targeted and sufficient for the change. No issues found — no correctness bugs, security problems, or type-safety gaps introduced by this PR. |
What
Follow-up addressing the advisory review feedback carried over from #257 (it merged before these were applied).
memory.ts— runtime guard instead of a silent cast. Theremembertool'sdatashape comes fromcontext.memory.schema, which arrives asunknown(loaded via dynamicimport()inloadRouteMemory, validated structurally). The old(mem.schema ?? …) as z.ZodTypeAnycast was silent — a non-Zod value (a plain JSON-Schema object, etc.) was handed straight toz.object()and blew up with an opaque "expected a Zod schema" error at tool-schema use time. Now anisZodSchemacheck guards it and falls back to the permissive record when the value isn't a real Zod type.runtime-exports.ts— documentsrunMemoryCommandas a test-only surface (supports@dawn-ai/testing's live-smoke), not a stable public API.Why a runtime guard, not the literal type-narrow the reviewer suggested
The review asked to narrow
MemoryContext.schema?: unknown→ZodTypeAny. That's cosmetic here: the value genuinely originates asunknownfrom a dynamic import, so narrowing the field just relocates theas ZodTypeAnycast to the setter (buildMemoryContext, whereLoadedRouteMemory.schemaisunknown) without adding real safety. The actual concern — an opaque runtime blowup — is a runtime problem, so the fix is a runtime guard at the use site.Tests
packages/core/test/capabilities/memory.test.ts:context.memory.schemais not a Zod type — fails before the guard (the non-Zod value reachesz.object()andsafeParsethrows "expected a Zod schema"), passes after.datashape when provided — confirms the happy path still wires the real schema through (a wrong-typed field is rejected).Validation
@dawn-ai/core190 ✓,@dawn-ai/cli278 ✓; build/typecheck green; biome clean (exit 0)patchchangeset (fixed group, stays pre-1.0)🤖 Generated with Claude Code