Skip to content

feat(catalog): read trigger sets back and list skill package formats - #211

Merged
xaleryb merged 8 commits into
intel:mainfrom
napetrov:feat/run-trigger-formats
Oct 25, 2026
Merged

xaleryb merged 8 commits into
intel:mainfrom
napetrov:feat/run-trigger-formats

Conversation

@napetrov

@napetrov napetrov commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #210 (feat/task-format-detect). Review the commits after #210: f7abf7c, 19822ba (precision in skill_selection_summary). The fix for vendored-skill discovery is a separate PR, #215.

Summary

dokimi could already write three trigger-set formats. With this PR it can read them too and run them through the existing skill-catalog: arm. It adds no new runner.

skill-reach QuerySet  ─┐
skill-creator / agentskills.io [{query, should_trigger}] =TARGET ─┼─> TriggerQuery ─> lint vs --catalog ─> questions | reach | skill-creator
questions + expected_skill ─┘                                                         └─> arms run --arms skill-catalog:<dir>  (skill_selection_summary)
 dokimi/external/trigger_set.py   + detect_trigger_format, from_reach, from_skill_creator, from_questions, read_trigger_set
 dokimi/commands/catalog.py       + trigger-set --trigger-set PATH[=TARGET];  + catalog formats --root [--json]
 dokimi/commands/arms.py          + a reach or skill-creator file gets the conversion command in its error
 dokimi/task_formats/             + consumer "catalog trigger-set" for skill-reach and skill-creator-trigger
 dokimi/skills/formats.py (new)   agent-skill (host + agentskills.io lint), cursor-rule, copilot-instructions, gemini-extension, claude-plugin

Evidence

  • Before: arms run --questions reach.json failed in the questions loader, and tasks inspect gave no consumer for skill-reach or skill-creator sets.
    After: catalog trigger-set --trigger-set reach30.json --format questions reads the file and re-lints it (30 queries: 19 exam-framed, 17 echo). Arms then score it. The round-trip tests (writer, then reader, gives the same labels) are in tests/test_trigger_set_readers.py, and the package scan tests are in tests/test_skill_formats.py. The full suite passes locally (7834), along with ruff and mypy.
  • skill_selection_summary now reports precision, which is hits over the questions where any skill loaded. The arms report shows it as a column. The precision figures below came from an ad-hoc script that used the same definition.
  • Live run: haiku-4.5 (Bedrock) with the intel/skills@370d84d catalog (33 skills). Runs 1–3 are repeats.
condition runs recall precision false trigger
dokimi skill-catalog: with reach30, 33 skills 3×30 0.77 0.66 0.46
skill-reach claude-code haiku, same 30 ids (earlier run) 2×30 0.41–0.50 0.75 0.19–0.31
dokimi skill-catalog: with onetbb skill-creator set, 33 skills 1×20 1.00 0.56 0.80
dokimi skill-catalog: with onetbb skill-creator set, target alone 2×20 1.00 0.63 0.60
skill-creator run_eval.py native (anthropics/skills@dbd4588), haiku 3×20 0.10 n/a 0.00

The tool-calling proxy triggers too often compared with the real harnesses. The import path is unaffected by this; it is the same finding as before.

Merge Danger

Door: two-way

Additive only: two new CLI options or subcommands and a new module. --questions on catalog trigger-set is no longer required (at least one source is still enforced).

Blast Radius: small

A skill-creator negative is read as "no skill should load". In a catalog of more than one skill, loading a rival skill therefore counts as a false trigger. The CLI warns about this.

🤖 Generated with Claude Code

A probe registry (dokimi.task_formats) names the format of a file, a task
directory or a tree, and reports kind, item count, present/missing parts,
lint problems and which dokimi backends consume it today. Probes: harbor and
task-md (wrapping harnesses.tasks), terminal-bench v1, SWE-bench, Inspect AI
samples and @task files (text scan, never imported), OpenAI evals,
skill-creator evals.json and trigger sets, skill-reach QuerySet, promptfoo
and dokimi questions. Unknown paths get a best-effort structure report;
malformed files are lint problems. Detection only: nothing new runs.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@github-actions github-actions Bot added the cli-interface-change Changes dokimi's user-facing CLI surface label Oct 24, 2026
@github-actions

Copy link
Copy Markdown

CLI interface change detected

This PR changes dokimi's user-facing CLI surface (commands and/or options):

+ added command `dokimi catalog formats`
    + option `--help/-h`
    + option `--json`
    + option `--root`
+ added command `dokimi tasks inspect`
    + argument `path`
    + option `--help/-h`
    + option `--json`
~ `dokimi catalog trigger-set` parameters changed:
    + added option `--trigger-set`
    ~ changed option `--questions`: required: True -> False

Updated on every push; the cli-interface-change label is on while the diff is non-empty.

@codecov-commenter

codecov-commenter commented Oct 24, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 91.62411% with 82 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.07%. Comparing base (dd089ad) to head (21b6433).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
dokimi/dokimi/task_formats/detect.py 87.61% 8 Missing and 5 partials ⚠️
dokimi/dokimi/task_formats/source.py 82.43% 8 Missing and 5 partials ⚠️
dokimi/dokimi/external/trigger_set.py 88.67% 6 Missing and 6 partials ⚠️
dokimi/dokimi/task_formats/datasets.py 94.54% 5 Missing and 7 partials ⚠️
dokimi/dokimi/skills/formats.py 93.19% 6 Missing and 4 partials ⚠️
dokimi/dokimi/task_formats/dirs.py 89.36% 4 Missing and 6 partials ⚠️
dokimi/dokimi/task_formats/configs.py 90.32% 3 Missing and 3 partials ⚠️
dokimi/dokimi/commands/catalog.py 95.65% 1 Missing and 2 partials ⚠️
dokimi/dokimi/commands/arms.py 83.33% 2 Missing ⚠️
dokimi/dokimi/commands/tasks.py 96.77% 0 Missing and 1 partial ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #211      +/-   ##
==========================================
- Coverage   92.09%   92.07%   -0.02%     
==========================================
  Files         225      233       +8     
  Lines       28101    29090     +989     
  Branches     4622     4787     +165     
==========================================
+ Hits        25879    26784     +905     
- Misses       1576     1620      +44     
- Partials      646      686      +40     
Files with missing lines Coverage Δ
dokimi/dokimi/__init__.py 100.00% <ø> (ø)
dokimi/dokimi/eval/arm_summary.py 97.41% <ø> (ø)
dokimi/dokimi/report/arms_report.py 96.95% <100.00%> (ø)
dokimi/dokimi/skills/loader.py 97.56% <100.00%> (+0.06%) ⬆️
dokimi/dokimi/task_formats/__init__.py 100.00% <100.00%> (ø)
dokimi/dokimi/task_formats/model.py 100.00% <100.00%> (ø)
dokimi/dokimi/commands/tasks.py 92.40% <96.77%> (+1.06%) ⬆️
dokimi/dokimi/commands/arms.py 89.03% <83.33%> (-0.19%) ⬇️
dokimi/dokimi/commands/catalog.py 96.72% <95.65%> (-0.73%) ⬇️
dokimi/dokimi/task_formats/configs.py 90.32% <90.32%> (ø)
... and 6 more

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@napetrov
napetrov force-pushed the feat/run-trigger-formats branch from 29df5da to f7abf7c Compare October 24, 2026 17:13
Readers for the three trigger-set formats dokimi already writes (skill-reach
QuerySet, skill-creator / agentskills.io eval queries, questions with
expected_skill) into TriggerQuery, held to the writers by round-trip tests.
catalog trigger-set --trigger-set relints an imported set against the catalog
and hands it to the skill-catalog: arm; arms run points external sets at it.

catalog formats names the skill/rule packages of other ecosystems (Cursor
rules, Copilot instructions, Gemini extensions, Claude plugins) next to
agentskills.io SKILL.md, with spec lint and the selecting mechanism.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Hits over the questions where the arm loaded any skill, strict on
multi-load like recall; rendered in the arms report's Skill selection
table. Replaces the ad-hoc calculation used for the intel#211 evidence table.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
build_trigger_set rebuilt each query from its text alone, so a questions
set read back with --trigger-set (or --questions) lost its pre-rewrite
source_text. Carry it, and keep it as the original on a second --rewrite.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
`catalog formats` aborted the whole scan with a TypeError when a
gemini-extension.json had a number or boolean mcpServers, and counted a
string by its characters. Record it as a package problem instead.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
@xaleryb

xaleryb commented Oct 25, 2026

Copy link
Copy Markdown
Contributor
  • Ran: the full suite, lint, types and security on the head, plus each point's input through the CLI.
  • Reach set read back and written as reach (the default --format), with kind: neighbor_negative, notes: "..." -> output has no kind and no notes, so the neighbour-negative turns into a positive for its skill; exit 0, no warning -> expected: kind and notes kept, or a refusal.
  • --trigger-set a.json=linux-perf --trigger-set b.json=dpnp-io (two skill-creator sets) -> duplicate question id across sources: sc-001, exit 1 -> expected: they combine, as "Repeatable" says. Id-less reach and questions sets collide the same way (q-001, q1).
  • catalog formats on a template/SKILL.md plus an identical .agents/skills/bar and .claude/skills/bar -> "3 loadable as skills", while discover_skills loads 1 -> expected: equal counts.
  • Pushed: b427538 keeps source_text when a set is read back; e33173d lists a non-object mcpServers as a package problem instead of crashing the scan.
  • Left for the author: the three points above.

…d back

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
@xaleryb

xaleryb commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Pushed 98cb170 for the first point above: a reach set written back as reach keeps each entry's kind and notes, so a neighbor_negative stays a negative (out_of_scope is still written for an entry with no skill). The two fields travel on the in-memory rows under a private key, so --format questions output gains no undeclared key; the new test checks both. Full suite, ruff and mypy pass on Linux; the test fails on e33173d.

Not covered: reach -> questions -> reach still drops them, since keeping them would mean declaring kind/notes in questions.v2.json. Still open: duplicate ids across repeated --trigger-set sources, and the catalog formats count.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
@xaleryb

xaleryb commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Also merged main (472ff96): the only conflict was growth_baseline.json; after #163 cmd_catalog_scan is back under the cap (entry removed) and cmd_catalog_trigger_set measures 16 (lowered from main's 18). Full suite, ruff and mypy pass on Linux.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
@xaleryb

xaleryb commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Pushed 21b6433 for the catalog formats count: its "loadable as skills" now uses the files discover_skills loads (new skill_files() in skills/loader.py, which discover_skills now calls), so a template is left out and mirrors count once: the tree from our review gives 1, not 3. Mirror grouping decodes the name with errors="replace", so a non-UTF-8 SKILL.md still does not crash catalog formats; the hash is still taken over the raw bytes. Two tests; full suite, ruff and mypy pass on Linux.

The duplicate-id error across repeated --trigger-set sources fails loudly, so it can follow in its own PR; nothing else from our review is open here.

@xaleryb xaleryb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at 21b6433: the points from our review are fixed at this head (the duplicate-id error can follow separately), the full suite passes on Linux, and CI is green.

@xaleryb
xaleryb merged commit 98d709a into intel:main Oct 25, 2026
20 checks passed
xaleryb added a commit to napetrov/dokimi that referenced this pull request Oct 25, 2026
Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

intel#211 landed with a copy of this branch's first commit (f4ce883) plus its own reach consumers. Each conflicting file was merged three-way against f4ce883, so main's additions (BY_TRIGGER_SET and its consumers) and this branch's later commits are both kept.
xaleryb added a commit to napetrov/dokimi that referenced this pull request Oct 25, 2026
…ntel#211

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
xaleryb added a commit that referenced this pull request Oct 26, 2026
* feat(tasks): detect eval-task formats with `tasks inspect`

A probe registry (dokimi.task_formats) names the format of a file, a task
directory or a tree, and reports kind, item count, present/missing parts,
lint problems and which dokimi backends consume it today. Probes: harbor and
task-md (wrapping harnesses.tasks), terminal-bench v1, SWE-bench, Inspect AI
samples and @task files (text scan, never imported), OpenAI evals,
skill-creator evals.json and trigger sets, skill-reach QuerySet, promptfoo
and dokimi questions. Unknown paths get a best-effort structure report;
malformed files are lint problems. Detection only: nothing new runs.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

* feat(tasks): task_inspect.v1 report, config-named datasets, LFS pointers

`tasks inspect --json` now prints a stamped task_inspect.v1 artifact and
`--out FILE` writes it through save_artifact, as `repo budget` does.

Probes added or widened from runs over upstream checkouts:
- a dataset file a config names is read as that config says: Inspect
  FieldSpec remaps, OpenAI evals registry specs (openai-evals-spec, with
  model-graded samples needing no ideal), promptfoo `tests: file://`
  (promptfoo-tests);
- git-LFS pointer stubs are git-lfs-pointer, with the expected format
  when a config names them;
- CSV datasets, promptfooconfig.<variant>.yaml and redteam configs,
  ExploreBench task YAML (dokimi-explore-task, localization);
- a task.md with no BenchFlow front matter and no task part directories
  is no longer a task-md task.
YAML aliases are reported as refused, not as invalid YAML.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

* test(tasks): real-format corpus for tasks inspect, with its manifest

tests/fixtures/task_formats/ holds small upstream files of every format
the probes know (intel/skills, skillsbench, terminal-bench, Inspect AI,
openai/evals, promptfoo; licenses in LICENSES/) and generated ones where
no public file exists (SWE-bench row, skill-creator evals.json,
skill-reach QuerySet, and the output of dokimi's trigger-set writers).
MANIFEST.yaml records each file's source, commit and license and what
inspect must report; test_task_format_corpus.py inspects the corpus as
one mixed tree, validates every --json report as task_inspect.v1, and
reads back what to_skill_creator, to_reach and to_questions write.

The fixture tree is kept out of pytest collection, ruff and the license
header check: its test_*.py are the verifiers of copied tasks.

Fixes found on the way: a task.md scan leaked the loader's UserWarning
from the fingerprint, and a path that is neither file nor directory
(/dev/null) crashed the tree scan.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

* fix(tasks): keep a tree scan alive on NUL paths and non-string YAML keys

A config naming a path with a NUL byte raised ValueError in links._key,
and a skill-reach key YAML loads as bool or int (on:, yes:, 1:) raised
TypeError in the key lint; either one killed the whole `tasks inspect`.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(tasks): write YAML dates, sets and NaN in details as plain JSON

Probes copy YAML values into details unchanged. --json hid it with
default=str, but --out (save_artifact) raised TypeError and wrote
nothing, and a YAML .nan went out as bare NaN in both modes.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(tasks): do not read FIFOs in a tree scan; cap reads of sizeless files

The 64 MiB guard trusted st_size, which is 0 for a FIFO or device: a
FIFO left in a scanned tree hung the scan, and /dev/zero was read until
memory ran out. The scan now takes regular files only and the read is bounded.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(tasks): claim docker-* only for tasks with environment/Dockerfile

docker-* always builds environment/Dockerfile, so a harbor or task-md
task without it errors in every cell, yet inspect listed docker-* as a
consumer whenever tests/ or verifier/ existed.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* test(tasks): pin the guards that keep a tree scan finite

Removing the symlink skip, the dot-directory skip, RecursionError from
the parse catch or the file-cap flag left every task-format test green;
two of those turn into crashes on real trees.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(tasks): report a file a tree scan could not read, as a single-file inspect does

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* ci(codefactor): leave the task-format corpus out; it mirrors upstream files

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* ci(codefactor): the exclusion key is exclude_patterns

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* ci(codefactor): drop .codefactor.yml; CodeFactor did not apply it on this PR

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(tasks): catalog trigger-set is a consumer of trigger sets since #211

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* test(tasks): fix the three CodeFactor findings in the copied corpus files

solution.sh: shebang above the canary line; Dockerfile: pip3 --no-cache-dir; verifier/test.sh: test pytest's exit code directly. Detection reads only which files exist, and MANIFEST.yaml notes each change, as its header asks.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(tasks): scan Inspect FieldSpec calls in linear time

_FIELD_SPEC's [^)]* let each unclosed FieldSpec( run to the end of the
segment, and search retried at every following one: 40000 of them after
an @task file's dataset call took 43 s. The arguments are now bounded at
1000 characters and a run stops at the next FieldSpec(, so each start
scans at most up to the next one. The bound alone (the review's
[^)]{0,500}) is linear too but still took 17 s on a file at the 64 MiB
read cap; with the stop it takes 1.2 s.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(tasks): read a CSV with a UTF-8 BOM without it in the first column

An Excel or Sheets export of an Inspect samples.csv or a promptfoo
tests.csv starts with a BOM, which csv.DictReader kept in the first
header (\ufeffinput), so the file was unknown and a BOM on __expected
hid the promptfoo marker. Both consumers drop it: Inspect's csv_dataset
reads utf-8-sig and promptfoo parses CSV with bom: true.

The BOM is stripped for CSV only, not by opening every file as
utf-8-sig. A JSON or JSONL file with a BOM stays a 'not valid JSON:
Unexpected UTF-8 BOM' problem, because that is what its readers do:
read_json_input (catalog trigger-set --trigger-set), load_questions and
Inspect's json_dataset all decode plain utf-8, so stripping it here
would advertise a consumer that refuses the file. YAML needs nothing:
the loader skips a leading BOM.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(tasks): report a task.md a tree scan cannot read instead of aborting

TaskMdProbe.fingerprint reads task.md (_is_benchflow_task_md,
_has_frontmatter) and walk called detect outside any try, so one
mode-000 task.md ended inspect_path with a PermissionError and no
report for any other task. walk now catches OSError around detect, the
one place that covers every directory probe, and reports the directory
as unknown with 'cannot read: ...', as an unreadable file in a tree is.
This also covers a directory whose entries cannot be stat'ed (a mode-000
directory holding a task.toml), which failed the same way before this
PR in task_format.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* test(tasks): pin the verifier condition of the docker-* claim

_docker_runnable needs environment/Dockerfile and a tests/ or verifier/
directory, but only the Dockerfile half was tested: returning just the
Dockerfile check passed every test. A Harbor and a task-md task with
both verifier directories removed must not be claimed for docker-*.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* test(tasks): cover three guards the mutation run left untested

- the samples of a model-graded OpenAI evals spec are read without the
  ideal lint (graded = False passed every test);
- promptfoo tests: file://tests.csv labels a CSV that has no __expected
  column (the only fixture CSV is claimed with or without the reference);
- a scan does not enter node_modules/ or venv/ (only .git and .venv were
  tested, and those are skipped as dot directories anyway).

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

---------

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
Co-authored-by: Alexander Rybkin <alexander.rybkin@intel.com>
napetrov added a commit that referenced this pull request Oct 28, 2026
…217)

* feat(tasks): detect eval-task formats with `tasks inspect`

A probe registry (dokimi.task_formats) names the format of a file, a task
directory or a tree, and reports kind, item count, present/missing parts,
lint problems and which dokimi backends consume it today. Probes: harbor and
task-md (wrapping harnesses.tasks), terminal-bench v1, SWE-bench, Inspect AI
samples and @task files (text scan, never imported), OpenAI evals,
skill-creator evals.json and trigger sets, skill-reach QuerySet, promptfoo
and dokimi questions. Unknown paths get a best-effort structure report;
malformed files are lint problems. Detection only: nothing new runs.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

* feat(catalog): read trigger sets back and list skill package formats

Readers for the three trigger-set formats dokimi already writes (skill-reach
QuerySet, skill-creator / agentskills.io eval queries, questions with
expected_skill) into TriggerQuery, held to the writers by round-trip tests.
catalog trigger-set --trigger-set relints an imported set against the catalog
and hands it to the skill-catalog: arm; arms run points external sets at it.

catalog formats names the skill/rule packages of other ecosystems (Cursor
rules, Copilot instructions, Gemini extensions, Claude plugins) next to
agentskills.io SKILL.md, with spec lint and the selecting mechanism.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

* feat(arms): precision in skill_selection_summary

Hits over the questions where the arm loaded any skill, strict on
multi-load like recall; rendered in the arms report's Skill selection
table. Replaces the ad-hoc calculation used for the #211 evidence table.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

* feat(catalog): trigger-probe runs each query in real Claude Code; payload leak audit

catalog trigger-probe runs every trigger-set query in a fresh claude -p: a new
git repo with the catalog committed in .claude/skills, scratch HOME and config,
the query verbatim, bundled skills on. Skill calls are scored by the same
selection summary as the skill-catalog arm, one column per trial.

payload_audit reports dokimi artifacts (arm names, label keys, question ids,
grading words, task paths) in a captured request, argv or env, with operator
content blanked and the stock harness's own text subtracted.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

* fix(catalog): group trigger-probe Skill calls by message.id

Claude Code streams one assistant event per content block, so two Skill
calls in one turn were scored as two turns and the strict first-turn rule,
multi_load_rate and mean_first_turn_loads never fired. Group by message.id
as agent_runner groups by iteration, and skip subagent events.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(catalog): score a trigger-probe choice made before a timeout

run_query checked timed_out first, so a query whose Skill call was already
in the transcript, or whose result event was read before the CLI hung on a
backgrounded Bash call, was dropped as n_failed. A Skill call seen is now
the choice, and a result event decides the rest.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(catalog): apply the arms' plugin seal in trigger-probe --sealed

--sealed set only the env seal, so the built-in plugin skills the
docker-claude arms switch off via --settings stayed listed. Sealed argv now
carries the same enabledPlugins, merged with --listing-budget-fraction
into one --settings.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(catalog): keep trigger-probe results when one run fails

A relative --claude passed the which() preflight but was spawned from the
scratch work dir, and any OSError/RuntimeError in one run escaped pool.map
and lost every paid result before --out was written. Resolve --claude to
an absolute path and record a failed run as that trial's error.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(catalog): address trigger-probe review on #217

- tools_before_choice stops at the first Skill turn.
- --out directory and --target are checked before any paid run; records
  are written after each query, so an interrupt keeps what ran.
- Fail when a catalog skill is missing from the init event's listing;
  report runs that ended on error_max_turns (max_turns_hit).
- Kill processes left in the run's workspace (a backgrounded Bash job
  runs in its own session and escaped the group kill).
- Docs: the operator's config is not loaded, but host paths stay readable.
- Tests: every CLI flag reaches ProbeConfig, argv/env/timeout/stdin of a
  run, symlinked skills copied as files, payload-audit case, lookbehind,
  tuple and longest-first blanking.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

* fix(catalog): trigger-probe self-review: partial file, input errors, result_subtype

Keep in-progress records in <out>.partial so a rerun does not clobber a
finished result; refuse a non-writable --out and a malformed catalog as
input errors (exit 2) before any run; name the field result_subtype as
the rest of the codebase does; document max_turns_hit, not_listed and the
partial file.

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>

* Reject a non-positive --timeout before any run

Signed-off-by: Anton Volkov <antonwolfy@gmail.com>

* test(catalog): pin trigger-probe's stray-process kill in run_query

Only kill_strays itself was tested, so dropping its call from run_query
or matching a sibling root's prefix left the suite green. Run a fake
claude that leaves a job in its workspace and one in a same-prefix
sibling root: the first must die, the second must survive.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

* fix(catalog): refuse a trigger-probe label that names no catalog skill

A query whose expected_skill is not in --catalog can never be loaded, so
it scored as a miss after the paid run: a typo read as recall 0. The
skill-catalog: arm refuses such a label; trigger-probe now does too,
before any run, as it already does for --target.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>

---------

Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
Co-authored-by: Alexander Rybkin <alexander.rybkin@intel.com>
Co-authored-by: Anton Volkov <antonwolfy@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli-interface-change Changes dokimi's user-facing CLI surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants