Repository navigation
feat(eval): add eval redteam to probe grading checks with planted answers #281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
napetrov
wants to merge
30
commits into
intel:main
Choose a base branch
from
napetrov:feat/verifier-redteam
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,237
−8
Open
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
28a3609
feat(eval): red-team grading blocks against wrong, empty, hedged and …
napetrov 71cc8e6
fix(eval): redteam skips the attacks a grading block passes by design
napetrov 068abc8
fix(redteam): inconclusive status, single-literal stuffing, hedge col…
napetrov 04f2142
fix(redteam): negated checks no longer silence wrong, empty and hedge
napetrov 6e16c6b
fix(redteam): clear wrong answer of check values, stuff negated checks
napetrov e881ab5
fix(redteam): skip the stuffed probe for a negated mode all match
napetrov 12f653b
Merge branch 'main' of https://github.com/intel/dokimi into pr281-work
napetrov d96f87d
fix(redteam): choose the planted wrong answer and the hedge probe by …
napetrov 6b6aa2f
fix(redteam): grade wrong, empty and hedge against the whole block, t…
napetrov 19f30ef
fix(redteam): a set with a question that was not measured is inconclu…
napetrov 3b4c701
fix(redteam): bury aliases between decoys instead of listing them for…
napetrov 1b64508
fix(redteam): grade each question with its own block when an id repeats
napetrov 4d7cef6
feat(redteam): record the judge model and provider in the redteam.v1 …
napetrov 70e66bd
refactor(redteam): read check values and build the judge ask through …
napetrov ef1ed29
fix(redteam): name -o in the cut-violations line when no artifact is …
napetrov f108f53
test(redteam): pin the canary of a whole-answer match and of a string…
napetrov 89641b7
docs(redteam): list the negated mode all exclusion and say where nega…
napetrov 0918eea
test(redteam): run judge checks through run(ask=) and through the --j…
napetrov 27828e4
test(redteam): run an ungradable block through the command and pin th…
napetrov 1946f48
test(redteam): check the artifact of a blocked and an inconclusive co…
napetrov c1596ef
test(redteam): pin the bare stuffed answer of a whole-answer check wi…
napetrov a296b5a
docs(redteam): changelog fragment says what an inconclusive run is
napetrov 2a259de
Address review: answer the review summaries and bot comments in their…
napetrov c68a1f1
docs(redteam): refresh two stale comments on the wrong and stuffed at…
napetrov 98ccb96
fix(redteam): a question set nested too deep to parse exits 2, not wi…
napetrov c09f9b6
fix(redteam): a block with an unrun judge or regex is unprobed, not a…
napetrov 0742a49
Merge remote-tracking branch 'intel/main' into pr281-1029
napetrov 5e39635
test(redteam): a regex past its timeout leaves the probe unscored, wi…
napetrov de35dd8
docs: keep the comment blocks this PR adds to two lines
napetrov 04c4541
fix(redteam): a json contains check's stuffed answer goes after a decoy
napetrov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
3 changes: 3 additions & 0 deletions
3
dokimi/changelog.d/20261028_120100_napetrov_feat-verifier-redteam.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| ### Added | ||
|
|
||
| - **`eval redteam` checks that grading blocks reject wrong answers** — grades a planted wrong, an empty, a hedged and a keyword-stuffed answer against each question's `grading` block, and a canary right answer built from its one literal check. A wrong answer the grader accepts, or a canary it rejects, is a violation: the command prints pass rates, exits 1 and, with `-o`, writes a `redteam.v1` artifact (it records the judge model and provider). A run in which a graded question was not measured (judge checks without `--judge`, a block of only negated checks) is `inconclusive` and also exits 1. Judge checks are unscored unless `--judge` is given, so the default run makes no model call. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| # Copyright (C) 2026 Intel Corporation | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """``eval redteam``: check that a question set's grading rejects the answers it should. | ||
|
|
||
| Reads a questions set (with ``grading`` blocks), grades synthetic attacks against it and prints | ||
| the pass rates. Exits 1 when any attack is accepted, a canary is rejected, or nothing was graded | ||
| (``inconclusive``); exits 2 on an unreadable input or an unwritable ``-o``. Judge checks are not | ||
| scored unless ``--judge`` is given, so the default run makes no model call. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import argparse | ||
| import sys | ||
|
|
||
|
|
||
| def _ask(args: argparse.Namespace): | ||
| if not args.judge: | ||
| return None | ||
| from dokimi.eval.judge import judge_ask | ||
|
|
||
| return judge_ask(args.judge_model, args.judge_provider) | ||
|
|
||
|
|
||
| def cmd_eval_redteam(args: argparse.Namespace) -> None: | ||
| from dokimi.artifacts import save_artifact | ||
| from dokimi.eval.redteam import format_table, run | ||
| from dokimi.questions.artifact import load_questions | ||
|
|
||
| try: | ||
| questions = load_questions(args.questions).artifact.get("questions") or [] | ||
| result = run(questions, ask=_ask(args)) | ||
| except (OSError, ValueError, RecursionError) as e: # RecursionError: nested too deep | ||
| print(f"Error: {e}", file=sys.stderr) | ||
| sys.exit(2) | ||
| result["questions_path"] = str(args.questions) | ||
| result["judge_model"] = args.judge_model if args.judge else None | ||
| result["judge_provider"] = args.judge_provider if args.judge else None | ||
| print(format_table(result, output=args.output)) | ||
| if args.output: | ||
| try: | ||
| save_artifact("redteam", result, args.output) | ||
|
napetrov marked this conversation as resolved.
|
||
| except (OSError, ValueError) as e: | ||
| print(f"Error: {e}", file=sys.stderr) | ||
| sys.exit(2) | ||
| print(f"Wrote redteam artifact to {args.output}") | ||
| if result["status"] != "pass": | ||
| sys.exit(1) | ||
|
|
||
|
|
||
| def register_eval(eval_sub) -> None: | ||
| from dokimi.defaults import DEFAULT_JUDGE_PROVIDER, JUDGE_MODEL_FOR_PROVIDER, JUDGE_MODEL_HELP | ||
| from dokimi.eval.judge import JUDGE_PROVIDERS | ||
|
|
||
| r = eval_sub.add_parser( | ||
| "redteam", | ||
| help="Check grading blocks reject wrong, empty, hedged and stuffed answers and accept a canary") | ||
| r.add_argument("questions", help="questions JSON with grading blocks (from `questions import`)") | ||
| r.add_argument("--judge", action="store_true", | ||
| help="Grade judge checks with the judge model (model calls); default leaves them unscored") | ||
| r.add_argument("--judge-model", default=JUDGE_MODEL_FOR_PROVIDER, help=JUDGE_MODEL_HELP) | ||
| r.add_argument("--judge-provider", default=DEFAULT_JUDGE_PROVIDER, choices=JUDGE_PROVIDERS) | ||
| r.add_argument("-o", "--output", default=None, help="redteam.v1 JSON to write") | ||
| r.set_defaults(func=cmd_eval_redteam) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: The docstring leaves out the case that most often exits 1 here: a graded question that no probe measured. A set with a judge-only question, a negated-only question and a
matchquestion, run without--judge, printsstatus inconclusive: 3 questions, 1 probed, 2 unprobedand exits 1, while the docstring lists only "nothing was graded".Suggestion: replace line 7 with
the pass rates. Exits 1 when any attack is accepted, a canary is rejected, a graded question was not measured,, so line 8 startsor nothing was graded (``inconclusive``); ....