Skip to content

Revert "feat: add 4 scorer kinds (retrieval, demotion, procedure, dedup) + dashboard surface + dedup React install" - #43

Open
rahuldindor411-glitch wants to merge 1 commit into
Significant-Gravitas:mainfrom
rahuldindor411-glitch:revert-40-feat/ranking-metrics
Open

Revert "feat: add 4 scorer kinds (retrieval, demotion, procedure, dedup) + dashboard surface + dedup React install"#43
rahuldindor411-glitch wants to merge 1 commit into
Significant-Gravitas:mainfrom
rahuldindor411-glitch:revert-40-feat/ranking-metrics

Conversation

@rahuldindor411-glitch

@rahuldindor411-glitch rahuldindor411-glitch commented Jul 26, 2026

Copy link
Copy Markdown

Reverts #40## Intent

AgentProbe's existing memory evaluation routes everything through an
LLM-judge over a transcript. That is the right shape for conversational
behaviors, but it cannot answer the question the AutoGPT dream system
needs answered: given a query, did the right memories come back in
the right order
. This PR adds the missing scorer kind and the
scenarios that exercise it.

It ships:

  1. A pure ranking-metrics module covering precision@k, recall@k, MRR,
    and NDCG@k (with log2(rank + 1) discount), pinned by 25 known-answer
    unit tests.
  2. A new retrieval: block on scenario YAML — golden, optional
    forbidden, k, match, per-metric weight, pass_threshold,
    and a source (either raw_exchange_key for inline adapter
    payloads or fixture for offline runs).
  3. Runner integration that scores retrieval alongside the LLM judge,
    forces a scenario fail when any forbidden item lands in the top-k,
    and surfaces a RetrievalScore on ScenarioRunResult.
  4. A new retrieval_scores persistence table mirroring
    judge_dimension_scores on both SQLite (v8 → v9) and Postgres
    (v4 → v5), with recorders, getters, and Drizzle schema entries.
  5. Report-renderer support — retrieval_rows + a pretty JSON blob
    alongside the existing judge dimension rows.
  6. Five new memory scenarios (data/retrieval-memory.yaml + fixtures
    under data/fixtures/retrieval/) that exercise forget-on-request,
    warm-context relevance, stale-fact demotion, scope filtering, and
    bounded cascading expiry.

Behavior changes

  • Scenarios may now declare a retrieval: block. Without one, behavior
    is unchanged: the judge is still the only signal, the overall pass
    is whatever the judge said.
  • With a retrieval: block present, the runner scores the retrieved
    list (resolved from last_reply.rawExchange[<key>] or a JSON fixture)
    and the overall scenario passed becomes judge.passed && retrieval.passed.
    A forbidden-item hit in the top-k forces retrieval.passed = false
    regardless of the weighted aggregate.
  • Persistence schema bumps: SQLite SCHEMA_VERSION 8 → 9, Postgres
    POSTGRES_TARGET_VERSION 4 → 5. Both backends ship the new
    retrieval_scores table in their baseline DDL and add a forward-only
    migration step that create table if not existss it on upgrade.
  • Run-history readers now return retrievalScores: Array<...> on each
    scenario record. The field is optional on the ScenarioRecord type
    so existing tools that don't read it stay typecheck-clean.

How it's wired

  • Math: src/domains/evaluation/ranking.ts is pure TypeScript with
    no I/O and 100% function coverage from
    src/domains/evaluation/ranking.test.ts. The four metric primitives
    are individually exported (and individually tested against
    known-answer cases like NDCG@3 of [1, 0, 1] and MRR of [0, 0, 1]),
    and a top-level scoreRanking aggregator threads them together with
    a weighted average, forbidden-hit detection, and a pass threshold.
  • Scorer: src/domains/evaluation/retrieval-scorer.ts consumes
    the parsed YAML config plus a RetrievalSourceContext
    (scenariosPath, lastAdapterReply) and resolves the actual
    retrieved list. It accepts strings, {label}/{text}/{name}/{id}
    object payloads, or a JSON file path. Missing sources record a
    source: "missing" score instead of crashing the suite.
  • Schema: src/domains/validation/load-suite.ts validates the
    retrieval: block strictly — non-empty golden, valid match policy,
    threshold ∈ [0,1], known metric weight keys, non-negative weights.
  • Runner: runScenario in src/domains/evaluation/run-suite.ts
    scores retrieval after the judge phase, records it via a new
    recordRetrievalResult recorder hook, and ANDs the two pass flags
    into the final scenario result.
  • Persistence: both backends get an idempotent
    create table if not exists retrieval_scores in the baseline DDL,
    a forward migration step, an ensureRetrievalScoresTable helper for
    the legacy SQLite in-recorder migrator, recorder methods, and a
    getRun join. The Drizzle inventory test pins the table count.
  • Reporting: prepareScenarioView emits retrieval_rows,
    one row per metric with pretty value/percent labels, and a
    retrieval_scores_pretty JSON blob. Templates that already exist
    see no change until they reference the new keys.

Scope rails

  • No new env vars. No new top-level deps.
  • Adapter abstractions untouched. The scorer reads rawExchange
    data the adapter already returns; no EndpointAdapter shape change.
    Scenarios that need offline scoring use the fixture source.
  • No frontend dashboard work. The data is persisted and surfaced
    in the report-prepared view, but the React dashboard is not
    updated. Flagged as a follow-up below.
  • No mass-rewrite of existing scenarios. The five new scenarios
    live in their own data/retrieval-memory.yaml pack alongside the
    existing data/multi-session-memory.yaml. The forget-on-request
    scenario is a ranking-scored sibling of the existing judge-only
    mem-negative-forget-on-request.

Risk

  • Persistence migration touches both backends. The new table is
    additive and the migration is create table if not exists, so the
    forward path is safe. Rollback to prior schema would require
    dropping the table.
  • Scenarios with a retrieval: block but no fixture and no adapter
    payload will score source: "missing" and fail. This is intentional
    — silently passing a "we got nothing" run would mask real regressions
    — but it does mean integrating this against an adapter that doesn't
    populate rawExchange.retrieved requires that adapter to be updated
    or the scenarios to use the fixture source.
  • The RetrievalScore is ANDed with the judge for the final pass flag.
    A scenario that previously passed via judge alone and now adds a
    retrieval block that fails will see its overall pass flip. That is
    the intended UX — both signals must be green — but it's a behavior
    change worth calling out.

Out of scope (deferred)

  • Dashboard UI for retrieval scores. The data is persisted and
    prepared for the renderer; React surfaces are not updated. The
    retrieval_rows array is structured the same way as dimension_rows
    so a UI addition should be a small follow-up.
  • Adapter-side retrieval emission. Wiring AutoGPT or OpenClaw to
    return rawExchange.retrieved payloads is left as adapter work and
    doesn't belong in this scorer-shaped PR. The scenarios ship with
    fixtures so the scorer math is exercised against curated graph
    snapshots in the meantime.
  • Multi-judge aggregation. AgentProbe's bias_mitigation.multiple_judges
    config remains unimplemented (preexisting); not in scope here.
  • Sweeping the remaining 24 unused multi-session-memory scenarios
    into the new format.
    Out of scope; the brief calls for ≥5 new
    scenarios and that's what shipped.

Validation

  • bun test: 250 pass / 7 fail. The 7 failures are all
    pre-existing dashboard React tests
    (useDashboard, RunDetailView SSE, StartRunView, CompareView)
    that fail identically on origin/main at the parent commit. They
    are not touched by this PR.
  • bun run lint: clean.
  • bunx tsc --noEmit (root): clean.
  • bun run docs:validate: clean (new scenario added to platform.md,
    current-state.md, e2e-checklist.md; generated docs refreshed).
  • Persistence migration: SQLite baseline + forward migration both
    exercised by tests/unit/db.test.ts and
    tests/unit/persistence/migrations.test.ts. Postgres migration
    exercised by tests/unit/persistence/migrations.test.ts against a
    pre-v5 baseline.
  • Scenario pack: every scenario parses, references a known memory
    rubric, and points at a fixture file that exists relative to the
    YAML. Pinned by tests/unit/retrieval-memory.test.ts.

Checklist

  • bun run lint clean.
  • bunx tsc --noEmit (root) clean.
  • bun run docs:validate clean.
  • bun test shows no new failures vs. origin/main.
  • No new env vars.
  • No secrets committed.
  • Behavior docs updated (docs/product-specs/platform.md +
    current-state.md + e2e-checklist.md).

Commits

  • feat(evaluation): add ranking metrics primitives — pure math module + 25 unit tests
  • feat(evaluation): add retrieval scorer kind and YAML schema — typed config, scorer module, loader, schema validation
  • feat(evaluation): wire retrieval scorer into runScenario — runner integration + two runner-level tests
  • feat(persistence): persist retrieval scores in sqlite and postgres — table, migrations, recorders, getters
  • feat(reporting): expose retrieval metrics in run reports — prepared view fields + biome touch-ups
  • feat(data): add five ranking-scored memory scenarios — YAML pack + fixtures + pack-level tests
  • docs(specs): document ranking-scored retrieval scenarios — platform spec entry + generated docs refresh

@rahuldindor411-glitch

Copy link
Copy Markdown
Author

@rahuldindor411-glitch

Copy link
Copy Markdown
Author

Rekha dindor

@rahuldindor411-glitch

Copy link
Copy Markdown
Author
  1. 8209423503

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