Feat/receipt auto approve - #485
Merged
Merged
Conversation
the atom the fidelity pivot rests on: a claim's evidence can now carry a byte-offset span [byte_start, byte_end) into the cited source's raw bytes, and receipts.verify_receipt checks the quoted text against the source bytes by string comparison alone — no llm, no judge. the quoted span is in the source at those offsets or it is not. three receipt states, kept distinct because the review gate treats them differently: VERIFIED (span decodes to exactly the quote), FORGED (span claimed but out of range / inverted / undecodable / mismatched, or the source is absent from the kb), NO_RECEIPT (no offsets to verify). byte offsets rather than char offsets because sources are stored as raw content-addressed bytes and utf-8 char indices diverge from byte indices at the first multibyte codepoint. verify_evidence loads the source from the store and delegates; a receipt whose source is missing is reported forged, never verified, so an unverifiable citation can never read as approved. purely additive — two optional evidence fields and one new module, no existing path changes behaviour yet. this is the primitive phase d's auto-approve will call.
the quote step of phase a's retrieve-then-quote loop. locate_span finds the byte offsets of a quote's first exact occurrence in a source's raw bytes, or None when the quote is not present verbatim. the match is deliberately exact and case-sensitive — no normalization, no fuzzy match — because the receipt's value is that it is checkable by string comparison, so a paraphrase must fail to locate and be dropped. receipt_for_quote composes the locator with the schema: it returns an Evidence whose byte-offset receipt is guaranteed to verify against the same bytes, or None to drop an unquotable claim — the mechanical form of "drops any claim it cannot quote." a property test ties the two halves together: anything the locator produces verifies VERIFIED.
propose_quoted_claim wires the span locator into the gated write path: given a source and the quote that supports a claim, it locates the verbatim span, stores a receipt-backed Evidence, and files a normal claim proposal citing it. when the quote is not in the source it returns None and files nothing — the mechanical form of "drops any claim it cannot quote." the write still goes through propose_claim and the review gate; what is new is that the filed claim now carries a byte-offset receipt the gate can verify by string comparison. intake is idempotent: receipt_for_quote mints a content-addressed evidence id from the span, so re-filing the same span reuses the existing Evidence instead of duplicating it. layering kept honest — proposals depends on the receipts primitive, not the reverse. receipt_for_quote's evidence_id is now optional (content-addressed default).
evaluate_claim_receipts is the function phase d's auto-approve will call: it returns approve=True only when a claim cites at least one thing and every citation is a receipt that verifies. a forged receipt, a bare source id (no byte-offset span), an unknown id, or an empty citation list all reject, with reasons naming each failure. the verdict is the conjunction of per-citation string comparisons — no llm, no judge. this completes the verification machinery for "human leaves the loop": schema -> per-evidence verify -> receipt-backed intake -> per-claim verdict. what it deliberately does NOT do yet is touch approve(); wiring the verdict into automatic approval is the phase d step, gated behind the step 0 gate-integrity and step 1 concurrency work so the auto-gate is not forgeable or race-corruptible.
phase d of the fidelity pivot: the human leaves the loop. when review.auto_approve_on_receipt is on, a claim whose byte-offset receipts all verify clears self-approval with no human — the mechanical string comparison (evaluate_claim_receipts, no llm, no judge) is the reviewer. a claim that cannot quote its source (bare source id, forged or missing receipt) does not qualify and still falls through to the human gate: the gate degrades to asking, it never rubber-stamps. off by default, so the review gate stays on until a kb opts in. _approval_block_reason gains the receipt path alongside the trusted-agent opt-out; _review_config dries the config.yaml load the block reason and the new drain share; _claim_receipts_verify wraps the verdict. auto_approve_receipts(store) drains the pending queue — approves every receipt-verified claim, leaves everything else pending — which is what makes "run vouch and it just captures knowledge, no review" real end to end: ingest a source, quote it into receipt-backed claims, auto-approve with no human, recall the knowledge (including from a reopened kb). builds on the phase-a receipt machinery (span-receipts).
phase b: the capture step with no human, so the loop runs without a hand-written quote. extract.segment_source deterministically splits an ingested source into verbatim quotable spans; extract_receipt_claims files each as a claim that quotes itself, so its byte-offset receipt verifies by construction; ingest_source runs the whole loop — store the doc, extract the claims, and (when the gate is on) auto-approve every one whose receipt verifies. new `vouch ingest FILE`: "run vouch on a doc and it captures the knowledge." with review.auto_approve_on_receipt on, verifying claims are approved with no human and are immediately recallable via vouch search / recall; without the gate they are filed pending for review. a span that is not verbatim in the source is dropped, never trusted. deterministic and llm-free by design: the receipt check is the guardrail, so the pipeline runs in the base install and under test with no external command. selection — which spans are worth a claim — is a later quality knob; today it is every substantive sentence (ingesting a 28kb doc yields ~500 claims), which proves the pipeline but is not yet compression. builds on phase d's auto_approve_receipts.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
the evidence model gained byte_start/byte_end for span receipts but schemas/evidence.schema.json was not regenerated, so the schema-check drift gate failed. regenerated with scripts/gen_schemas.py; only the evidence schema changed.
boskodev790
pushed a commit
to boskodev790/vouch
that referenced
this pull request
Jul 16, 2026
wire the session path into phase-d's receipt-gated auto-approve (vouchdev#485) so the zero-friction loop runs end to end: ask a question in one session and the answer is saved with no human; a fresh session recalls it from memory without re-reading the project files. a new claude-code Stop hook runs `vouch capture answer`. capture.last_exchange pulls the turn's (question, answer) from the transcript; the answer is ingested as a content-addressed source; extract.extract_receipt_claims files a receipt-backed claim per quotable span; and each is self-approved only where proposals.approve already allows it (review.approver_role: trusted-agent or review.auto_approve_on_receipt, whose receipts verify by construction). with neither opt-in the claims stay pending — the review gate is honoured, never bypassed, and no parallel write path is added. quiet and idempotent by design: answers below a length floor (acknowledgements) are skipped, and an answer already ingested (same bytes) is not re-captured, so the every-turn Stop hook never duplicates or floods the kb. selection stays coarse — one claim per sentence, same stance as vouchdev#485 — a later quality knob. the existing tool-activity page capture is untouched.
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
Why
What might break
VEP
Tests
make checkpasses locally (lint + mypy + pytest)CHANGELOG.mdupdated under## [Unreleased]