Repository navigation
fix(core): refuse a generated body whose evidence is missing or not its own - #94
Merged
csdev19 merged 2 commits intoOct 25, 2026
Conversation
Failing tests for NIW2-333: a missing evidence or body key, a body whose hash is not the evidence's, and malformed evidence must all be refused without touching the stored response. A literal null body stays valid. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ed or not its own apply_generated_body took body and evidence as z.unknown(), which Zod treats as optional, and the writer skips undefined patch values. A request without the evidence key wrote a new body beside the old generation; one without the body key replaced only the generation; and nothing checked that bodyHash(body) matched evidence.bodyHash, so a hostile or buggy agent could mark any hand-written body as laqi-vouched. Project.applyGeneratedBody now rejects, before touching the file, an undefined body, evidence that is not GenerationEvidence, and a body whose hash is not evidence.bodyHash. The HTTP and MCP schemas require both keys. A literal null body is still a body. Refs NIW2-333 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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.
What changed and why
apply_generated_bodydocuments that a body and its generation evidence are "one fact, written together", but nothing enforced it. The HTTP and MCP schemas declared both asz.unknown(), which Zod treats as optional, and the writer skipsundefinedpatch values. Three failures followed:bodyHash), so the next apply reported a spurious "body-modified".confirmunset: the request passed the vouching check and replaced onlygeneration, so the evidence claimed to describe a body it never saw.bodyHash(body) === generation.bodyHash, so an agent could mark any hand-written body as laqi-vouched.Now
Project.applyGeneratedBodyrefuses, before touching the file, anundefinedbody, evidence that is notGenerationEvidence, and a body whose hash is notevidence.bodyHash.confirmwaives none of these. The HTTP route and the MCP tool also require both keys, so a bad request fails with a 400 / MCP error at the edge. A literalnullbody is still a body and is stored asnull.The editor already always sends both keys, so it is untouched. NIW2-314 (annotations, elicitation, backups) and NIW2-309 are not included.
How it was verified
Tests were committed first and failed (7 in core/HTTP, 3 in MCP stdio), then the fix turned them green.
bun run test packages/core packages/server packages/mcp/src/stdio.test.tsbun run verifysteps (lint, format check, build, check-types, check-types:scripts, test), run twice in a row: 118 files, 1618 tests passing both times.bun run verifyitself stops in this worker's checkout atoxfmt --checkon.claude/skills/.gc-skill-ownership.json, a Gas City file excluded from git. It is not part of this change and CI does not see it, so I ran the same steps with that one file left out.How to test it yourself
bun install && bun run test packages/core/src/project.test.ts packages/server/src/control-plane-app.test.ts packages/mcp/src/stdio.test.tsnpx laqi, thengenerate_dataandupdate_endpointover MCP, or the panel's Generate button):apply_generated_bodywith a preview'sbodybut nogeneration: it is refused andlaqi/api.jsonis unchanged.generationbut a differentbody: the error namesbodyHashand the file is unchanged.Refs NIW2-333
Run: Gas City session ni-wisp-sxa8swf, bead la-550, Mac mini
🤖 Generated with Claude Code