Fixture
evaluation/v1
provider: fixture
model: fixture-v1
1. A sanitized change produces a specific finding
The off-by-one case changes pagination in synthetic src/pagination.py. The fixture provider replays a deterministic response; the engine validates locations against the supplied diff and emits a review result with per-file coverage (legacy evidence policy on this corpus).
review-sensei --provider fixture \
--fixture-response evaluation/v1/responses/off-by-one.json \
--diff evaluation/v1/diffs/off-by-one.patch \
--model fixture-v1 \
--no-learning-proposals \
--output /tmp/review-sensei-off-by-one.json
The written document is a superset of the corpus baseline below: a run also emits the additive outcome fields review_status, coverage, and finding_lifecycles, so it is not byte-identical to the expected fixture. Compare the deterministic review content instead:
jq -S '{summary,comments,provider,model,learning_proposals,evidence_policy}' \
/tmp/review-sensei-off-by-one.json > /tmp/actual.json
jq -S . evaluation/v1/expected/off-by-one.review.json > /tmp/expected.json
diff /tmp/actual.json /tmp/expected.json
The authoritative check is the corpus evaluator, which normalizes derived metadata (finding_lifecycles, a complete review_status, and default coverage) before comparing against the expected fixture:
python -m review_sensei evaluate --mode fixture --corpus evaluation/v1/corpus.json
--no-learning-proposals is what keeps learning_proposals empty here; omit it and proposals from the fixture response are retained, as in section 3. Expected review content (schema: review-result):
{
"summary": "The pagination change introduces an off-by-one error for page numbers greater than one.",
"comments": [
{
"path": "src/pagination.py",
"line": 3,
"body": "The start index is correct, but the slice end should be start plus page_size.",
"severity": "bug",
"category": "correctness"
}
],
"provider": "fixture",
"model": "fixture-v1",
"learning_proposals": [],
"evidence_policy": "legacy"
}
Illustration
conversation reply
not a live PR
2. Authorized @sensei follow-up in thread
When conversation controls are enabled, an authorized @sensei mention in an existing review thread can receive a bounded, thread-aware reply. The processing reaction clears when the validated reply is published. This example is illustrative only — it does not link to a public comment thread.
ReviewSensei bot · src/pagination.py:3
The start index is correct, but the slice end should be start plus page_size.
maintainer · reply
@sensei would this also affect total_pages when page_size is zero?
ReviewSensei bot · bounded reply
total_pages is unchanged by this diff. The finding targets the slice end on line 3 only. A zero page_size is a separate guard concern not introduced here.
Validated reply payload shape (schema: conversation-reply):
{
"body": "`total_pages` is unchanged by this diff. The finding targets the slice end on line 3 only. A zero `page_size` is a separate guard concern not introduced here."
}
Conversation publication is a separate control from analysis. See getting started for the control matrix.
Illustration
finding lifecycle
learning proposal
3. Finding disposition and learning are separate
Stable finding identities track disposition across review runs (new, still-present, fixed, outdated, uncertain). Resolving a GitHub thread or merging without a code change does not automatically mark a finding fixed. A later model omitting a concern is not proof the defect is gone.
Learning follows a separate lifecycle: proposed in the review result → draft learning PR → maintainer approval on the trusted base → future selection for matching paths. Approving a learning does not close a finding or imply the underlying code was corrected.
Finding lifecycle metadata (schema: review-result, illustrative fields):
"finding_lifecycles": [
{
"fingerprint": "7c3b2a1f…b4a3",
"state": "still-present"
}
]
Approved learning entry (schema: learning-entry, after maintainer merge — illustrative):
{
"id": "pagination-slice-end",
"status": "active",
"scope": ["src/pagination.py"]
}
Inspect approved learnings offline (zero-write):
review-sensei learnings diagnose \
--learning-root /path/to/trusted-base-checkout \
--json
Illustration
partial review
approval withheld
4. Partial / budget-limited review retains findings and blocks approval
When per-file coverage is present, budget-exhausted and other incomplete outcomes are explicit. Valid findings from reviewed paths are retained, but automatic approval is withheld when coverage is partial or fully_reviewed is false. There is no fabricated confidence score — only outcome fields.
{
"review_status": "partial",
"coverage": {
"fully_reviewed": false,
"files": [
{"path": "src/pagination.py", "outcome": "reviewed"},
{"path": "src/runner.py", "outcome": "budget-exhausted", "reason": "provider-call-budget"}
]
}
}
Preview bounded coverage and zero-write plan output (no provider calls):
review-sensei plan \
--diff evaluation/v1/diffs/off-by-one.patch \
--repository owner/repo \
--pull-request 42 \
--json
review-sensei doctor --json
Approval blockers for this shape include coverage-partial and review-partial when publication and approval controls are enabled; incomplete enumeration raises coverage-incomplete / review-incomplete instead. These identifiers are defined in public contracts — treat that document, not this page, as their source of truth. Coverage blockers are independent of the blocking-finding finalizer, which separately withholds approval while unresolved blocking findings exist. See security & data flow for what approval does and does not guarantee.
Feature ↔ source mapping
- Fixture evaluation corpus —
evaluation/v1/ (CC0-1.0 synthetic)
- Review result schema —
src/review_sensei/schemas/review-result.schema.json
- Coverage manifest — ADR 0044; default opt-in for large-change orchestration
- Finding lifecycles — incremental reviews (#83); derived metadata on re-runs
- Learning lifecycle — proposals in review result; approval via trusted-base PR
- Bounded diagnostics —
doctor and plan subcommands (zero provider/GitHub writes)