feat(eval)!: add eval measurements and EM-001 trace_fitness scorer - #6036
Conversation
|
🤖 Finished Review · ✅ Success · Started 11:45 AM UTC · Completed 12:02 PM UTC Commit: |
PR Summary by QodoAdd eval measurements CLI and EM-001 trace_fitness scoring
AI Description
Diagram
High-Level Assessment
Files changed (31)
|
Site previewPreview: https://5a1aca36-site.fullsend-ai.workers.dev Commit: |
Code Review by Qodo
1.
|
ReviewFindingsMedium
Low
Previous runReviewFindingsMedium
Low
Previous run (2)ReviewFindingsLow
Previous run (3)ReviewFindingsMedium
Low
Info
Previous run (4)ReviewFindingsLow
Previous run (5)ReviewFindingsLow
Previous run (6)ReviewFindingsLow
Previous run (7)ReviewFindingsLow
Previous run (8)ReviewFindingsLow
Previous run (9)ReviewFindingsLow
Previous run (10)ReviewFindingsHigh
Low
Next steps:
Previous run (11)ReviewFindingsLow
Previous run (12)ReviewFindingsLow
Previous run (13)ReviewFindingsCritical
High
Medium
Low
Next steps:
Previous run (14)ReviewFindingsHigh
Medium
Low
Labels: PR adds new Go eval-measure package (internal/evalmeasure/), modifies CI workflows (.github/workflows/), and adds documentation (docs/guides/, docs/ADRs/) Next steps:
|
|
🤖 Review · ❌ Terminated · Started 1:34 PM UTC · Ended 1:54 PM UTC Commit: |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
|
🤖 Finished Review · ✅ Success · Started 1:34 PM UTC · Completed 1:54 PM UTC Commit: |
- Fix data-loss bug: swap AppendMeasurements before RecordScored so ledger only marks scored after measurement is persisted - Fix broken curl header args in action.yml using bash array instead of parameter expansion (word-split safe) - Add Prerequisites section to eval-measurements guide - Add OTEL/OTLP inline definitions on first use in guide - Use > **Planned:** callout format for unimplemented OTLP export - Update docs/guides/README.md with eval measurements entry - Consolidate ADR 0087 Decision into single paragraph (was multiple sub-decisions); trim Consequences to 5 bullets - ADR 0050 cross-reference uses Planned callout format - Rename printResults → printMeasurementResults Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
🤖 Review · Commit: |
|
🤖 Finished Review · ✅ Success · Started 1:15 AM UTC · Completed 1:33 AM UTC Commit: |
Superseded by updated review
|
🤖 Finished Review · ✅ Success · Started 1:43 PM UTC · Completed 2:04 PM UTC Commit: |
waynesun09
left a comment
There was a problem hiding this comment.
Review-only pass: 2 findings on this PR (scaffold breaking-change labeling, eval-measure manifest trust boundary). See inline comments.
Managed GHA/GitLab eval-measure no longer prefers MR/PR-tree
.fullsend/eval overrides; use default/base tip via --registry or
SHA-pinned agents@v0. Label the GitLab output-dir default move as
breaking per COMMITS.md.
BREAKING CHANGE: GitLab fullsend-agent scaffold default --output-dir
now writes under ${CI_PROJECT_DIR}/output (was an ephemeral tmp path)
so eval-measurements.jsonl can be retained as a CI artifact. Re-sync
adds a top-level output/ directory, excludes it from the sandbox
upload/git when nested under --target-repo, and keeps telemetry as a
1-week artifact. Jobs that depended on the old tmp layout must adopt
the new path or pin an older scaffold.
Signed-off-by: Adam Scerra <ascerra@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Per-org installs use workspace-root eval/measurements/, not .fullsend/eval/… — derive the git-show path from inputs.fullsend-dir while still reading bytes from the PR base / GITHUB_SHA tip. Signed-off-by: Adam Scerra <ascerra@redhat.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
🤖 Finished Review · ✅ Success · Started 2:41 PM UTC · Completed 3:00 PM UTC Commit: |
waynesun09
left a comment
There was a problem hiding this comment.
Approving at head 903c0a42 after multiple review rounds. Design assessment:
Architecture/intention — sound.
- Clean layering: eval measurements (online, deterministic, fail-open, never gating) are correctly separated from the ADR 0051 functional eval harness, and from primary OTEL facts (measurements are a derived sibling artifact that never rewrites the trace). The
id@versionledger keying gives trend continuity a real contract. - The ownership seam matches the repo split: executable logic (parser/scorers/CLI/CI step) in fullsend because it reads what fullsend writes; per-agent enablement policy in
fullsend-ai/agentsmanifests; org policy via local override. The change-guide table in the PR body makes the seam actionable. - Tool-agnostic export is the right call: portable JSONL now, remote export reusing the ADR 0050
OTEL_EXPORTER_OTLP_*path later — no vendor Assessments coupling in core. - The manifest trust model is now sound after
8f3564d6/903c0a42: managed jobs never read measurement policy from the MR/PR working tree (trend-poisoning closed); overrides come from the default/base tip viagit show+--registry(mirroring kill-switch config trust), else SHA-pinnedagents@v0viaGetRef— and theGITHUB_SHAfallback only engages on non-PR events, where it is trusted by definition. - Known failure modes are handled deliberately: skip semantics for pre-script-skipped/incomplete traces,
gen_ai.system→gen_ai.provider.namesemconv-rename tolerance inmodelOK, retro work-item gap closed viaORIGINATING_URL, and the breaking GitLab--output-dirmove is properly labeled with a migration path.
Non-blocking notes (fine as follow-ups):
- The per-org claim in
903c0a42doesn't hold end-to-end: reusable-dispatch passesfullsend-dir: ""in org mode, and the measure step's shell default is.fullsend(theGITHUB_WORKSPACEequality case also derives an emptyMEASURE_REL), so a workspace-rooteval/measurements/override never activates — it silently falls back toagents@v0. Fail-safe, and org mode is deprecated (ADR 0044), but either fix the derivation or drop the per-org wording from docs/comments so nobody expects it to work. - Two-step activation (#6384): nothing enforces the release cut after agents#722 merges, so merged manifests can silently no-op until
v0re-points. The tracking issue is the mitigation — keep it pinned until the release lands. - Agreed with the bot lows: shell-level
${AGENT}/${STAGE}validation before thegit showinterpolation would be cheap defense-in-depth (the Go CLI sanitizes, but the shell path runs first), and the base-tip manifest lookup is case-sensitive whereScoreTracematching is not. eval-measurements.jsonlbecomes a de-facto cross-repo contract once dashboards consume it — worth a short normative note (like normalized-event v1) before a second consumer appears.
Prior rounds (output/ exclusion scoping, UserCacheDir fetch cache, exporter→parser round-trip test, architecture-doc consistency, BREAKING labeling, MR-tree manifest trust) are all verified fixed at this head. CI green; review bot approved.
Keep the eval-measurements branch current with main. Signed-off-by: Adam Scerra <ascerra@redhat.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
🤖 Finished Review · ✅ Success · Started 3:30 PM UTC · Completed 3:51 PM UTC Commit: |
|
🤖 Finished Retro · ✅ Success · Started 4:07 PM UTC · Completed 4:24 PM UTC Commit: |
Retro: PR #6036 — feat(eval-measurements): online trace scoringWorkflow shape: Human-authored PR (49 files, +3943/−112) reviewed by fullsend-ai-review[bot] (19 runs over 10 days), qodo-code-review[bot] (2 runs), and human reviewer waynesun09 (8 review rounds). No code/fix/triage agents dispatched. 26 additional workflow triggers resolved to "no stage matched." Agents repo: Review quality gapThe human reviewer identified 9 HIGH and 31+ MEDIUM findings; the review agent identified 1 HIGH and 2 MEDIUM (plus ~18 LOW). The agent's unique HIGH (duplicate artifact upload step causing name collision) was valid and not caught by the human. However, the agent missed every security-critical and cross-cutting finding:
Token cost19 review agent runs (each reviewing a 49-file, 3943-line diff with Opus) plus 26 "no stage matched" workflow triggers. The agent produced largely similar LOW findings across the last ~8 runs with minimal progression in finding quality. 4 runs on Aug 20 alone within 3 hours. Evidence for existing issues
Proposals filed |
Summary
Introduce eval measurements: fail-open same-job scoring of wild agent OTEL traces (
fullsend eval-measure), writing portableeval-measurements.jsonlbeside telemetry when at least one new score is produced. First scorer istrace_fitness(EM-001). Decision recorded in ADR 0087.Companion default-policy PR: fullsend-ai/agents#722 (manifests under
eval/measurements/).Activation is two-step: merge agents#722 and cut a
v0.x.yrelease that re-points floatingagents@v0. Until that release lands, managed GHA/GitLab measure steps stay provisional (clean skip when the remote manifest is missing). Tracking: #6384. LocalFULLSEND_DIRoverrides work today.Breaking change
GitLab
fullsend-agentscaffold default--output-dirnow writes under${CI_PROJECT_DIR}/output(was an ephemeral tmp path) soeval-measurements.jsonlcan be retained as a CI artifact. Re-sync adds top-leveloutput/, excludes it from the sandbox upload/git when nested under--target-repo, and keeps telemetry as a 1-week artifact. Migrate by re-syncing the scaffold (or pin an older scaffold if you must keep the tmp layout).Ownership (please read)
internal/evalmeasure/)FULLSEND_DIRfullsend-ai/agents@v0when no local file exists — installs do not copy manifests to score stock agents.${FULLSEND_DIR}/eval/measurements/${AGENT}.yamlis override / opt-out / custom-agent only.eval-measureis the released binary that readsrun-telemetry.jsonl(which fullsend writes). Agents is content/policy, not that binary.assert:→ fullsend PR; new id / enable / thresholds on an existing scorer for a stock agent → agents-only; org-specific policy → local override.Tool-agnostic export
Core does not pick an observability product. Scores land in local
eval-measurements.jsonl. Remote score export (when implemented) reuses the sameOTEL_EXPORTER_OTLP_*path as ADR 0050. No vendor Assessments adapters orMLFLOW_*(or similar) wiring in managed workflows.Related
agents@v0cut: #6384Changes
v0activation, declarative sketch, planned L3 content scorers), glossary / tracing cross-linksinternal/evalmeasureparser +trace_fitness+ local JSONL/ledgerfullsend eval-measureCLI; fail-open post-step inaction.ymland GitLabfullsend-agent.ymlFULLSEND_DIRthen SHA-pinnedagents@v0fetch (--offlinesupported)agent-<name>-…runDirs; EM-001 skips incomplete/runner-health traces (no agent span, missing rootrunspan, pre-script skip)GITLAB_ISSUE_URL; keep hostoutput/out of sandbox tarball + git excludeTesting
go test ./internal/evalmeasure/(+ focused CLI / sandbox / scaffold tests)FULLSEND_DIRmanifest path produceseval-measurements.jsonlagents@v0after merge + release cut (agents#722, #6384)Optional dogfood (outside core): post-process the portable JSONL into an org-chosen backend. Example MLflow UI showing
trace_fitnessassessments — not coreMLFLOW_*wiring:Checklist
Notes for reviewers
--registry(path to the YAML); rename to “manifest” is follow-up.v0(Track agents@v0 release cut for eval measurement manifests #6384).