SDK

Judgments from code

The same judgment memory as oort judge: record an expert's decisions, then predict how they would judge a new item from those precedents. Local mode only.

Judgments from codeYour code records an expert's decisions with judge.record. judge.apply finds the closest precedents in the local store and returns a prediction with them, never the expert's own decision.YOUR MACHINEYour codeagent or expert rolejudge.applya predictionPrecedentslocal store

Record, confirm and apply

An expert-role handle records a person's decision. An agent-role handle derived from it records a draft, which counts only after the expert confirms it. Then judge.apply predicts a verdict for a new item.

TypeScript
import { createOort } from 'oortmem';

// The expert role is for code paths where a person really decided: a review UI, an import job.
await using expert = await createOort({
  mode: 'local',
  judge: { role: 'expert', operator: 'ada' },
  config: { judge: { experts: ['ada'] } },
});

await expert.judge.record({
  subject: 'Post claims a cure for diabetes',
  verdict: 'rejected',
  reason: 'A medical claim with no source.',
  domain: 'content',
  by: 'ada',
});

// Model-facing code runs in the agent role: it records only for listed experts, and what it
// records waits for a person to confirm it before it counts as a precedent.
const agent = expert.scoped({ judgeRole: 'agent' });
const draft = await agent.judge.record({
  subject: 'Post claims a miracle cure for colds',
  verdict: 'rejected',
  reason: 'No source.',
  domain: 'content',
  by: 'ada',
});
console.log(draft.status); // 'agent-recorded'
await expert.judge.confirm(draft.id);

const r = await agent.judge.apply({ summary: 'Post claims a miracle cure', domain: 'content' });
// 'suggested' | 'needs-expert' | 'precedents-only'. A prediction is never the expert's decision.
console.log(r.status, r.prediction?.verdict, r.precedents.length);
statusMeaning
suggestedA prediction at or above threshold (default 0.7) that at least two close precedents agree with. prediction holds the verdict and its probability.
needs-expertNo trustworthy prediction. why says which: no-precedents, too-far, too-few, precedents-disagree, low-confidence, no-decider or decider-failed.
precedents-onlyNo TypeSafe key: the close precedents and their reasons, and no verdict.

Every result lists its precedents, with similarity and who decided each one. Show them next to the prediction, so a person can check it.

Agent and expert roles

Your code is an agent by default, because the rule protects the expert's record from the model, not from you. The expert role is one explicit option, for code paths where a person really decided: a review screen, or an import job.

How
Agent (default)The default.
Expertjudge: { role: 'expert', operator: 'marcus' }
Records for
Agent (default)Experts listed in judge.experts only.
ExpertAnyone.
Daily cap
Agent (default)50 a day per Oort home.
ExpertNone.
Stored as
Agent (default)Agent-recorded and unconfirmed (via: 'mcp'), exactly like an MCP agent's.
ExpertA person's judgment (via: 'sdk').
Counts in judge.apply
Agent (default)Only after a person confirms it.
ExpertYes.
judge.confirm
Agent (default)Refused (expert-only).
ExpertConfirms an agent's record.

scoped({ judgeRole: 'agent' }) narrows a handle back to the agent role, and nothing widens it. Framework tools, the oortmem/ai-sdk ones included, always run in the agent role.

Listing experts: judge.experts

An agent may record only for the experts listed in judge.experts: in the home config, or in the config option as above.

  • With none listed, judge.record is refused with experts-not-listed.
  • A by that is not listed is refused with not-an-expert.

The daily cap

Agents record at most 50 judgments a day per Oort home. The count is shared with the MCP server's record_judgment tool (the same counter file, so 0.5.x counts too).

  • Over the cap: OortRefusedError with reason daily-limit. A person records more with oort judge record.
  • When the count cannot be kept, nothing is saved: cap-unavailable, which is retryable.

Confirm an agent's record

judge.apply leaves agent-recorded judgments out until a person confirms them, and an agent's record never corrects a person's. A person confirms one with oort judge confirm in a terminal, or your code calls judge.confirm(id) on an expert-role handle, as the example above does.

  • judge.confirm returns { id, changed }. judge.list({ domain, by }) finds the judgments to review.
  • changed is false when the judgment was already confirmed.
  • A judgment that is no longer current is refused with not-current.
  • In host code, judge.apply(item, { includeAgentRecorded: true }) also uses unconfirmed records, and includeImported uses judgments from packs. Model-facing tools never offer either.

Cost

judge.record makes one Voyage embed. judge.apply makes one Voyage embed and one TypeSafe judge call. judge.list and judge.confirm call no model. In cloud mode every judge method is refused (local-only). See What costs usage.