Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ summary: Chronological history of repository and skill changes.

# Changelog

## 2026-07-28 — Required passing validation and current-head lens evidence for a clean review verdict

- feat: require passing validation and current-head lens evidence for a clean
review verdict

## 2026-07-27 — Made database comparison output ephemeral, enforced untrusted-content boundaries, bound epic delegation, hardened command execution, populated the solution-simplicity and code-simplicity strata, enforced acceptance-gated closeout, populated the correctness stratum, recovered carved suffixes, folded owner adjudications, and ran the frozen v1 baseline

- fix: keep database comparison output ephemeral by default
(`2f13a2d6c27fda2ced66558460a72c11c4d43c26`)
- feat: enforce untrusted content boundaries
(`ff3f4b9cca9b062a7113b95ab08bd1d36331a27c`)
- docs: record the small-sample caveat the frozen protocol's step 6 requires
Expand Down
49 changes: 47 additions & 2 deletions review-suite/CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,11 @@ that merely move complexity behind another name.

## Verdict semantics

- `clean`: no `blocking` or `strong_recommendation` finding remains. Deferred
findings may be retained without failing the gate.
- `clean`: no `blocking` or `strong_recommendation` finding remains, every
packet validation entry supplied as required evidence passed, and — for an
aggregate result — every required lens has a fresh, current-head execution
(see "Lens execution evidence" below). Deferred findings may be retained
without failing the gate.
- `changes_required`: at least one actionable `blocking` or
`strong_recommendation` finding remains.
- `blocked`: essential evidence or a product or architecture decision is
Expand All @@ -118,6 +121,48 @@ fields that the caller could not establish and may preserve already-demonstrated
findings, but those findings do not convert the blocked review into a merge
verdict.

### Validation must back a `clean` verdict

A packet's `validation` array is required evidence, not optional context: a
`clean` verdict claims that evidence is trustworthy, so a result must not
declare `clean` while that same packet records a required focused or full
validation entry as `failed` or `unavailable`. Pair validation rejects any
`clean` result paired with such a packet.

- A `failed` command with a demonstrated candidate-caused failure is a gating
correctness/validation finding and yields `changes_required`, never `clean`.
- A `failed` or `unavailable` command whose attribution or result is
insufficient for a trustworthy verdict yields `blocked` with a concrete reason
and a recorded `validation_limitations` entry, never `clean`.
- Do not invent infrastructure attribution from an exit code alone, and do not
omit a failed or unavailable command from validation evidence to hide it.

### Lens execution evidence (aggregate results)

An aggregate result records `lens_executions`: one entry per required lens
(`solution_simplicity`, `correctness`, `code_simplicity`), each naming its
`lens`, `head_sha`, `comparison_base_sha`, `verdict`, and whether it was
`freshly_executed` for this exact aggregate.

For aggregate `clean`:

- all three required lenses must be present exactly once, with no missing and no
duplicate entry;
- every entry's `head_sha` and `comparison_base_sha` must equal the aggregate
result's own candidate — a stale-head or stale-base entry cannot contribute to
a new-head aggregate;
- every entry's `verdict` must be `clean`; and
- every entry must be `freshly_executed`; no old-head or reused result may count
toward a new aggregate.

Any edit, rebase, conflict resolution, or update that changes the head
invalidates every existing lens execution for that head. Restart the complete
three-lens sequence — solution simplicity, correctness, then code simplicity —
after any such head-changing fix; a partial rerun (for example, only correctness
after a correctness fix, or only code simplicity and correctness after a
code-simplicity fix) cannot produce a valid `clean` aggregate. This child
defines no selective-reuse exception across different heads.

## Simplification proposal dispositions

When an orchestrator asks correctness to assess a validated simplification
Expand Down
23 changes: 22 additions & 1 deletion review-suite/contracts/review-result.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"blocking_reasons"
],
"properties": {
"schema_version": {"const": "1.0"},
"schema_version": {"const": "1.1"},
"lens": {
"enum": [
"correctness",
Expand Down Expand Up @@ -83,6 +83,27 @@
"type": "array",
"items": {"type": "string", "minLength": 1}
},
"lens_executions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"lens",
"head_sha",
"comparison_base_sha",
"verdict",
"freshly_executed"
],
"properties": {
"lens": {"enum": ["solution_simplicity", "correctness", "code_simplicity"]},
"head_sha": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
"comparison_base_sha": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
"verdict": {"enum": ["clean", "changes_required", "blocked"]},
"freshly_executed": {"type": "boolean"}
}
}
},
"validation_limitations": {
"type": "array",
"items": {"type": "string", "minLength": 1}
Expand Down
40 changes: 25 additions & 15 deletions review-suite/fixtures/auth-regression/expected.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
{
"schema_version": "1.0",
"schema_version": "1.1",
"lens": "correctness",
"candidate": {"head_sha": "8181818181818181818181818181818181818181", "comparison_base_sha": "9191919191919191919191919191919191919191"},
"candidate": {
"head_sha": "8181818181818181818181818181818181818181",
"comparison_base_sha": "9191919191919191919191919191919191919191"
},
"verdict": "changes_required",
"findings": [{
"id": "correctness.export-authorization",
"lens": "correctness",
"severity": "blocking",
"confidence": "high",
"rule": "Non-administrators remain forbidden from exporting customer records.",
"evidence": [{"location": "export.py:2", "detail": "The candidate checks only that an actor exists, so any authenticated role can export the record."}],
"concern": "The change removes the role check at the data-export trust boundary.",
"impact": "Ordinary users can access tenant-private customer exports.",
"proposed_change": "Restore the administrator role check and cover a non-administrator denial.",
"expected_effect": "Preserve the required export authorization boundary.",
"location": "export.py:2"
}],
"findings": [
{
"id": "correctness.export-authorization",
"lens": "correctness",
"severity": "blocking",
"confidence": "high",
"rule": "Non-administrators remain forbidden from exporting customer records.",
"evidence": [
{
"location": "export.py:2",
"detail": "The candidate checks only that an actor exists, so any authenticated role can export the record."
}
],
"concern": "The change removes the role check at the data-export trust boundary.",
"impact": "Ordinary users can access tenant-private customer exports.",
"proposed_change": "Restore the administrator role check and cover a non-administrator denial.",
"expected_effect": "Preserve the required export authorization boundary.",
"location": "export.py:2"
}
],
"blocking_reasons": [],
"next_action": "Restore role-based authorization and add the missing denial test."
}
40 changes: 25 additions & 15 deletions review-suite/fixtures/behavior-bug/expected.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
{
"schema_version": "1.0",
"schema_version": "1.1",
"lens": "correctness",
"candidate": {"head_sha": "1111111111111111111111111111111111111111", "comparison_base_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
"candidate": {
"head_sha": "1111111111111111111111111111111111111111",
"comparison_base_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
},
"verdict": "changes_required",
"findings": [{
"id": "correctness.equal-balance",
"lens": "correctness",
"severity": "blocking",
"confidence": "high",
"rule": "A charge equal to the available balance succeeds.",
"evidence": [{"location": "limits.py:2", "detail": "The strict comparison rejects amount equal to balance."}],
"concern": "The new boundary condition contradicts the acceptance criterion.",
"impact": "Customers cannot spend their full available balance.",
"proposed_change": "Use a less-than-or-equal balance comparison and add the equality regression test.",
"expected_effect": "Restore the required boundary behavior without changing overdraft policy.",
"location": "limits.py:2"
}],
"findings": [
{
"id": "correctness.equal-balance",
"lens": "correctness",
"severity": "blocking",
"confidence": "high",
"rule": "A charge equal to the available balance succeeds.",
"evidence": [
{
"location": "limits.py:2",
"detail": "The strict comparison rejects amount equal to balance."
}
],
"concern": "The new boundary condition contradicts the acceptance criterion.",
"impact": "Customers cannot spend their full available balance.",
"proposed_change": "Use a less-than-or-equal balance comparison and add the equality regression test.",
"expected_effect": "Restore the required boundary behavior without changing overdraft policy.",
"location": "limits.py:2"
}
],
"blocking_reasons": [],
"next_action": "Correct the comparison and add the missed boundary test."
}
30 changes: 28 additions & 2 deletions review-suite/fixtures/clean-change/expected.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
{
"schema_version": "1.0",
"schema_version": "1.1",
"lens": "aggregate",
"candidate": {"head_sha": "5555555555555555555555555555555555555555", "comparison_base_sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"},
"candidate": {
"head_sha": "5555555555555555555555555555555555555555",
"comparison_base_sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
},
"verdict": "clean",
"findings": [],
"blocking_reasons": [],
"lens_executions": [
{
"lens": "solution_simplicity",
"head_sha": "5555555555555555555555555555555555555555",
"comparison_base_sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"verdict": "clean",
"freshly_executed": true
},
{
"lens": "correctness",
"head_sha": "5555555555555555555555555555555555555555",
"comparison_base_sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"verdict": "clean",
"freshly_executed": true
},
{
"lens": "code_simplicity",
"head_sha": "5555555555555555555555555555555555555555",
"comparison_base_sha": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"verdict": "clean",
"freshly_executed": true
}
],
"next_action": "No material review action is required."
}
7 changes: 5 additions & 2 deletions review-suite/fixtures/code-simplicity-clean/expected.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"schema_version": "1.0",
"schema_version": "1.1",
"lens": "code_simplicity",
"candidate": {"head_sha": "8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c", "comparison_base_sha": "9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c"},
"candidate": {
"head_sha": "8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c",
"comparison_base_sha": "9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c"
},
"verdict": "clean",
"findings": [],
"blocking_reasons": [],
Expand Down
44 changes: 29 additions & 15 deletions review-suite/fixtures/complexity-relocating-wrapper/expected.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
{
"schema_version": "1.0",
"schema_version": "1.1",
"lens": "code_simplicity",
"candidate": {"head_sha": "8989898989898989898989898989898989898989", "comparison_base_sha": "9999999999999999999999999999999999999999"},
"candidate": {
"head_sha": "8989898989898989898989898989898989898989",
"comparison_base_sha": "9999999999999999999999999999999999999999"
},
"verdict": "changes_required",
"findings": [{
"id": "code-simplicity.remove-policy-adapter",
"lens": "code_simplicity",
"severity": "strong_recommendation",
"confidence": "high",
"rule": "Prefer direct use of the existing policy owner when a wrapper does not adapt semantics or remove caller knowledge.",
"evidence": [{"location": "access.py:1", "detail": "AccessPolicyAdapter forwards the same actor and resource directly to is_allowed and has one caller."}, {"location": "edit.py:can_edit", "detail": "Nearby code calls policy functions directly when no semantic adaptation exists."}],
"concern": "The adapter moves one call behind a class without removing any branch, parameter, or policy concept.",
"impact": "It adds a public concept, allocation, method, and call-path hop while leaving the caller's knowledge unchanged.",
"proposed_change": "Remove AccessPolicyAdapter and return is_allowed(actor, resource) directly from can_view.",
"expected_effect": "Remove one class, one method, one allocation, and one call hop without changing policy behavior.",
"location": "access.py:1"
}],
"findings": [
{
"id": "code-simplicity.remove-policy-adapter",
"lens": "code_simplicity",
"severity": "strong_recommendation",
"confidence": "high",
"rule": "Prefer direct use of the existing policy owner when a wrapper does not adapt semantics or remove caller knowledge.",
"evidence": [
{
"location": "access.py:1",
"detail": "AccessPolicyAdapter forwards the same actor and resource directly to is_allowed and has one caller."
},
{
"location": "edit.py:can_edit",
"detail": "Nearby code calls policy functions directly when no semantic adaptation exists."
}
],
"concern": "The adapter moves one call behind a class without removing any branch, parameter, or policy concept.",
"impact": "It adds a public concept, allocation, method, and call-path hop while leaving the caller's knowledge unchanged.",
"proposed_change": "Remove AccessPolicyAdapter and return is_allowed(actor, resource) directly from can_view.",
"expected_effect": "Remove one class, one method, one allocation, and one call hop without changing policy behavior.",
"location": "access.py:1"
}
],
"blocking_reasons": [],
"next_action": "Remove the pass-through adapter and retain direct use of is_allowed."
}
44 changes: 29 additions & 15 deletions review-suite/fixtures/duplicated-policy/expected.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
{
"schema_version": "1.0",
"schema_version": "1.1",
"lens": "code_simplicity",
"candidate": {"head_sha": "2222222222222222222222222222222222222222", "comparison_base_sha": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},
"candidate": {
"head_sha": "2222222222222222222222222222222222222222",
"comparison_base_sha": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
},
"verdict": "changes_required",
"findings": [{
"id": "code-simplicity.reuse-auth-policy",
"lens": "code_simplicity",
"severity": "strong_recommendation",
"confidence": "high",
"rule": "Use the repository's existing active-administrator policy helper.",
"evidence": [{"location": "actions.py:2", "detail": "Both actions repeat the same policy."}, {"location": "auth.py:require_active_admin", "detail": "The repository already centralizes this exact rule."}],
"concern": "The change creates three independently editable definitions of one authorization policy.",
"impact": "Future policy changes can leave these actions inconsistent and increase reviewer cognitive load.",
"proposed_change": "Call require_active_admin from both actions.",
"expected_effect": "Remove duplicated policy while preserving behavior.",
"location": "actions.py:2"
}],
"findings": [
{
"id": "code-simplicity.reuse-auth-policy",
"lens": "code_simplicity",
"severity": "strong_recommendation",
"confidence": "high",
"rule": "Use the repository's existing active-administrator policy helper.",
"evidence": [
{
"location": "actions.py:2",
"detail": "Both actions repeat the same policy."
},
{
"location": "auth.py:require_active_admin",
"detail": "The repository already centralizes this exact rule."
}
],
"concern": "The change creates three independently editable definitions of one authorization policy.",
"impact": "Future policy changes can leave these actions inconsistent and increase reviewer cognitive load.",
"proposed_change": "Call require_active_admin from both actions.",
"expected_effect": "Remove duplicated policy while preserving behavior.",
"location": "actions.py:2"
}
],
"blocking_reasons": [],
"next_action": "Reuse the existing authorization helper and rerun focused tests."
}
7 changes: 5 additions & 2 deletions review-suite/fixtures/explicit-tests-preserved/expected.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"schema_version": "1.0",
"schema_version": "1.1",
"lens": "code_simplicity",
"candidate": {"head_sha": "8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b", "comparison_base_sha": "9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b"},
"candidate": {
"head_sha": "8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b8b",
"comparison_base_sha": "9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b"
},
"verdict": "clean",
"findings": [],
"blocking_reasons": [],
Expand Down
Loading
Loading