Skip to content

[Proposal] Judge recall adoption with a session scorer #1391

Open

Description

@SaulMoro

Example

Today, when a member sets TEAMAI_UPVOTE_JUDGE=1, each Stop asks the local CLI which recalled documents the final reply used without opening them, and upvotes those. Opening a recalled document is credited without any judge, and that path is unchanged by this proposal.

session 7c1e… recalled: [pod-startup-timeouts, helm-values, retry-policy]
opened by a tool call  → credited without AI: [helm-values]
votes-judge (opt-in)   → adopted: [pod-startup-timeouts]   → upvote

As a scorer, the same judgment would go through sampling, leases, any driver's tool and isolation, and land as labels. A valid scorer file, as the scorer contract stands today:

---
# scorers/recall-adoption.md
labels:
  - { value: adopted, score: 1, description: The final reply substantively used a recalled document. }
  - { value: ignored, score: 0, description: No recalled document shaped the final reply. }
passingScore: 1
sessions: true
samplingRate: 25
---
Read the session transcript in the evidence. Did the final reply substantively use any document that recall returned in this session?
{"scorer":"recall-adoption","subject":{"platform":"claude-code","sessionId":"7c1e…"},"label":"adopted","score":1,"passed":true}

This gives one label per session, not per document. Naming the document in the prompt would need per-subject prompt input, which scorers do not have.

Behavior

Question Options
A scorer gives one label per subject; the judge returns a subset of documents one label per (session, document): a new subject kind / an answer schema that returns a list: a new answer shape / keep votes-judge, opt-in, and move its call onto the launcher (#1389) for tool choice and token reports
Evidence: the judge reads only its evidence directory, and session evidence is the redacted transcript put the recalled documents' excerpts into the evidence, grounded as votes-judge grounds them (knowledge roots only, no symlinks, ungrounded documents dropped) / let the judge read the team repo, which breaks isolation
Upvotes today come straight from the judge upvote from published labels / keep the direct upvote and add labels
Sampling adoption on 25% of sessions is enough for confidence scores / adoption needs every session. Recalls are counted on every session, so a sampled judge lowers upvoted / recalled in computeConfidence unless recalls of unjudged sessions are left out
Latency votes-judge runs on every Stop; a session scorer judges after the session is finished (6 hours idle when attended, at teamai score --drain when unattended, #1385). Upvote recency feeds confidence

The rows are not independent. "Upvote from published labels" (Upvotes row) needs the per-document subject or the list answer (first row): one label per session names no document to upvote.

Decision: the maintainers choose in this issue. Choose a scorer option only if per-document upvotes stay possible (first row) and recall confidence keeps its inputs (Sampling row); otherwise keep votes-judge.

Acceptance criteria (if accepted)

  • For the scorer options: votes-judge, its direct CLI call and its hook handler are removed, and the TEAMAI_UPVOTE_JUDGE text leaves the docs. Nothing calls an AI tool for adoption outside scorers.
  • For the "keep" option: votes-judge stays opt-in and calls the launcher from [feat] One launcher for every AI call, from the tool descriptor #1389.
  • Recall confidence keeps its current inputs or a documented replacement.
  • Grounding stays as strict as today: knowledge roots only, no symlinks, fail closed, one upvote per document per session.

Definition of done

  • docs/guide/scorers.md, docs/guide/knowledge.md and their zh-CN pages, for the option chosen.
  • skill-data/core/references/troubleshooting.md: the TEAMAI_UPVOTE_JUDGE text updated or removed.
  • Real-CLI record: one session judged for adoption, with the upvote it produced.

Out of scope

  • Crediting documents opened by a tool call, which needs no judge and stays as it is.
  • Making adoption judging on by default in attended sessions. In unattended runs, [feat] Publish and score sessions by run mode #1385's default (unattended: auto) applies to a scorer with sessions: true like any session scorer, so a team that adds this scorer gets adoption judging there unless it sets unattended: off.

Notes

Activity

  1. SaulMoro commented on Oct 25, 2026

    @SaulMoro
    CollaboratorAuthor

    Corrected today's behavior. votes-judge is opt-in with TEAMAI_UPVOTE_JUDGE=1, runs on every Stop, and adds to the tool-use signal (src/hook-handlers.ts:722-735).
    Replaced the example scorer with one that passes parseScorer: label objects and passingScore (src/scorers/definition.ts:15-45).
    Added the evidence question, latency, the sampling effect on computeConfidence, and a "keep votes-judge on the launcher (#1389)" option.
    Removed the dependency on #1386: session scorers and score --next leases for any driver already exist.

  2. SaulMoro commented on Oct 25, 2026

    @SaulMoro
    CollaboratorAuthor
    • Added who decides and the test: choose a scorer option only if per-document upvotes stay possible and recall confidence keeps its inputs, otherwise keep votes-judge.
    • Noted that upvoting from labels needs the per-document subject or a list answer, and that [feat] Publish and score sessions by run mode #1385's unattended default applies to this scorer like any session scorer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions