Skip to content

(MOT-4380) refactor(harness): simplify objective E2E assessments - #755

Merged
ytallo merged 1 commit into
mainfrom
refactor/harness-e2e-assessments
Aug 9, 2026
Merged

(MOT-4380) refactor(harness): simplify objective E2E assessments#755
ytallo merged 1 commit into
mainfrom
refactor/harness-e2e-assessments

Conversation

@ytallo

@ytallo ytallo commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • declare objective E2E checks once as required outcomes or non-blocking signals
  • derive criterion metadata, hard gates, and awards from the same assessment definitions
  • migrate persistent_state to canonical durable_result, function_discipline, and confirmation assessments
  • document the assessment pattern for new objective evaluators

Why

The previous evaluator repeated the same requirements across criteria, gates, and awards, allowing their identifiers and behavior to drift independently. The new internal abstraction keeps those outputs aligned while preserving the existing score and blocking semantics.

The persistent_state contract advances to version 2 because its three implementation-oriented gates are consolidated into two criterion-aligned gates. The report schema and 90-point threshold are unchanged.

Validation

  • cargo fmt --manifest-path harness/Cargo.toml --all -- --check
  • cargo test --locked --manifest-path harness/Cargo.toml -p harness-e2e (111 passed)
  • cargo clippy --locked --manifest-path harness/Cargo.toml -p harness-e2e -- -D warnings
  • git diff --check

Fixes MOT-4380

Summary by CodeRabbit

  • New Features

    • Added standardized objective assessment scoring for end-to-end scenarios.
    • Supports required pass/fail checks that can block success and signal-based checks that award weighted partial credit.
    • Reports now include assessment results, awarded points, gates, and explanations.
    • Updated persistent-state scenarios to use the standardized assessment format, including state and confirmation validation.
  • Documentation

    • Expanded scenario authoring guidance for defining and using assessment evaluators.

@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
workers Ready Ready Preview Aug 7, 2026 10:17pm
workers-tech-spec Ready Ready Preview Aug 7, 2026 10:17pm

Request Review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR introduces canonical required and signal assessment infrastructure. It migrates the persistent-state scenario to reusable assessment specifications, weighted objective scoring, hard gates, scenario version 2, and expanded validation coverage.

Changes

Assessment contract and scenario migration

Layer / File(s) Summary
Assessment specifications and aggregation
harness/tests/e2e/src/scenarios/assessment.rs, harness/tests/e2e/src/scenarios/mod.rs, harness/tests/e2e/README.md
Adds required binary assessments, weighted signal assessments, validation, criterion conversion, objective aggregation, unit tests, and authoring guidance.
Persistent-state assessment integration
harness/tests/e2e/src/scenarios/persistent_state.rs
Migrates the scenario to reusable assessments and version 2. Evaluation now checks durable state, function discipline, and confirmation responses through canonical gates and awards. Tests cover scoring and failure cases.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PersistentStateScenario
  participant AssessmentSpec
  participant ObjectiveEvaluator
  participant ObjectiveReport

  PersistentStateScenario->>AssessmentSpec: evaluate scenario checks
  AssessmentSpec->>ObjectiveEvaluator: return awards and gate status
  ObjectiveEvaluator->>ObjectiveReport: aggregate criteria into objective results
Loading

Possibly related PRs

  • iii-hq/workers#641: Both update E2E assessment scoring for required criteria and non-blocking signal scores.
  • iii-hq/workers#644: Both modify the persistent_state assessment contract and scenario versioning.
  • iii-hq/workers#688: Both use hard gates and advisory quality scores in the Harness E2E assessment model.

Suggested reviewers: andersonleal

Poem

A rabbit checks each score in line,
Required gates are crisp and fine.
Signals grant points when checks succeed,
State and writes meet every need.
The report blooms, clean and bright.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the refactor of objective E2E assessments in the harness.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/harness-e2e-assessments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 56 skipped (no docs/).

Layer Result
structure
vale
ai
render

Four for four. Nicely done.

@ytallo
ytallo marked this pull request as ready for review August 9, 2026 12:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
harness/tests/e2e/src/scenarios/persistent_state.rs (2)

100-126: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use binary for the confirmation award.

confirmation_points is either 0 or CONFIRMATION.weight(). points can never fail here, so the ? and the Result return type add unreachable error handling. binary expresses the same rule directly and lets assess become infallible.

♻️ Proposed refactor
-    let concise_confirmation = response_present && response_chars <= 240;
-    let confirmation_points = if concise_confirmation {
-        CONFIRMATION.weight()
-    } else {
-        0
-    };
+    let concise_confirmation = response_present && response_chars <= 240;
 
-    Ok(assessment::objective([
+    assessment::objective([
         DURABLE_RESULT.binary(
             state_matches,
             format!("expected {expected}, observed {observed}"),
         ),
         FUNCTION_DISCIPLINE.binary(
             function_discipline,
             format!(
                 "exact_write={exact_write}; observed {state_set_calls} state::set call(s); observed {function_call_errors} function-call error(s)"
             ),
         ),
-        CONFIRMATION.points(
-            confirmation_points,
+        CONFIRMATION.binary(
+            concise_confirmation,
             format!(
                 "response_present={response_present}; observed {response_chars} character(s); limit 240"
             ),
-        )?,
-    ]))
+        ),
+    ])
 }

Change the signature to -> ObjectiveEvaluation and wrap the call in evaluate with Ok(...). Then drop .unwrap() from the tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/tests/e2e/src/scenarios/persistent_state.rs` around lines 100 - 126,
Update the assessment helper containing confirmation_points to return
ObjectiveEvaluation directly, replace CONFIRMATION.points(...) with
CONFIRMATION.binary(concise_confirmation, ...), and remove the unnecessary ?
propagation. Adjust its evaluate caller to wrap the infallible result in Ok(...)
and remove related test unwraps.

232-243: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add the 240-character boundary case.

The test covers 241 characters and the empty response. It does not cover exactly 240 characters. A change of <= to < in assess would not fail any test.

💚 Proposed test addition
     #[test]
     fn missing_or_overlong_confirmation_is_non_blocking() {
         let value = json!({ "stored": true });
 
         for response in [String::new(), "x".repeat(241)] {
             let evaluation = assess(&value, &value, true, 1, 0, &response).unwrap();
 
             assert!(evaluation.hard_gates.iter().all(|gate| gate.passed));
             assert_eq!(award(&evaluation, "confirmation"), 0);
             assert_eq!(total(&evaluation), 90);
         }
     }
+
+    #[test]
+    fn confirmation_at_the_length_limit_scores_full_points() {
+        let value = json!({ "stored": true });
+        let evaluation = assess(&value, &value, true, 1, 0, &"x".repeat(240)).unwrap();
+
+        assert_eq!(award(&evaluation, "confirmation"), 10);
+        assert_eq!(total(&evaluation), 100);
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/tests/e2e/src/scenarios/persistent_state.rs` around lines 232 - 243,
Add an exact 240-character response case to the input set in
missing_or_overlong_confirmation_is_non_blocking, alongside the empty and
241-character cases, so assess explicitly verifies the maximum allowed
confirmation length.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@harness/tests/e2e/src/scenarios/persistent_state.rs`:
- Around line 89-118: Update the FUNCTION_DISCIPLINE assessment description in
assess to explicitly state that any function-call error in the session causes
failure, while retaining the existing function_discipline condition and
state::set call details.

---

Nitpick comments:
In `@harness/tests/e2e/src/scenarios/persistent_state.rs`:
- Around line 100-126: Update the assessment helper containing
confirmation_points to return ObjectiveEvaluation directly, replace
CONFIRMATION.points(...) with CONFIRMATION.binary(concise_confirmation, ...),
and remove the unnecessary ? propagation. Adjust its evaluate caller to wrap the
infallible result in Ok(...) and remove related test unwraps.
- Around line 232-243: Add an exact 240-character response case to the input set
in missing_or_overlong_confirmation_is_non_blocking, alongside the empty and
241-character cases, so assess explicitly verifies the maximum allowed
confirmation length.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 33dff56c-2240-4c6e-8e31-e56fd30889f6

📥 Commits

Reviewing files that changed from the base of the PR and between a4bcd95 and 8b553df.

📒 Files selected for processing (4)
  • harness/tests/e2e/README.md
  • harness/tests/e2e/src/scenarios/assessment.rs
  • harness/tests/e2e/src/scenarios/mod.rs
  • harness/tests/e2e/src/scenarios/persistent_state.rs

Comment on lines +89 to +118
fn assess(
expected: &Value,
observed: &Value,
exact_write: bool,
state_set_calls: usize,
function_call_errors: u64,
response: &str,
) -> anyhow::Result<ObjectiveEvaluation> {
let state_matches = observed == expected;
let function_discipline = exact_write && function_call_errors == 0;
let response_present = !response.trim().is_empty();
let response_chars = response.chars().count();
let concise_confirmation = response_present && response_chars <= 240;
let confirmation_points = if concise_confirmation {
CONFIRMATION.weight()
} else {
0
};

Ok(assessment::objective([
DURABLE_RESULT.binary(
state_matches,
format!("expected {expected}, observed {observed}"),
),
FUNCTION_DISCIPLINE.binary(
function_discipline,
format!(
"exact_write={exact_write}; observed {state_set_calls} state::set call(s); observed {function_call_errors} function-call error(s)"
),
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Align the function_discipline description with the evaluated condition.

function_discipline fails when function_call_errors > 0. That counter covers every function call in the session, not only state::set calls. The declared description states "Exactly one successful write targets the requested scope and key." An unrelated recovered function error therefore fails a required hard gate that the criterion text does not describe.

Either narrow the condition to write-related errors, or extend the description so the report explains the broader rule.

📝 Proposed description change
 const FUNCTION_DISCIPLINE: AssessmentSpec = AssessmentSpec::required(
     "function_discipline",
     30,
-    "Exactly one successful write targets the requested scope and key.",
+    "Exactly one successful write targets the requested scope and key, with no function-call errors in the run.",
 );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@harness/tests/e2e/src/scenarios/persistent_state.rs` around lines 89 - 118,
Update the FUNCTION_DISCIPLINE assessment description in assess to explicitly
state that any function-call error in the session causes failure, while
retaining the existing function_discipline condition and state::set call
details.

@ytallo
ytallo merged commit 98ba042 into main Aug 9, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant