Repository navigation
fix(novelty): keep a skill whose only spec error is an over-long description in the routing field - #405
fix(novelty): keep a skill whose only spec error is an over-long description in the routing field#405napetrov wants to merge 14 commits into
Conversation
…r 1024 chars in the routing field Harnesses differ on that one error: Claude Code lists the skill with the description cut short (probed on 2.1.318: about 1,536 characters and an ellipsis), pi.dev rejects it. Routing now keeps such a skill, from --catalog or --competitors skill:, with its full description, warns with the skill name and length, and records it under field.spec_warnings. Other spec errors still leave a skill out unless --include-invalid. catalog scan's name-conflict check uses the same listing rule. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
There was a problem hiding this comment.
🟢 Approval recommended
There are no active review issues requiring changes.
No open issues 🎉
What changed in this PR
0 new findings; nothing to fix.
This PR updates dokimi’s routing evaluation to retain skills whose only specification error is a description over 1024 characters, accommodating differences in how harnesses handle them.
Changes:
- Keeps full over-limit descriptions in routing fields while continuing to exclude skills with other specification errors by default.
- Adds stderr warnings and saved
field.spec_warnings, and aligns catalog name-conflict detection with routing eligibility. - Updates regression tests, documentation, and the changelog for the revised behavior.
| File | Description |
|---|---|
dokimi/tests/test_skill_repo_shapes.py |
Updates routing expectations for over-limit descriptions. |
dokimi/tests/test_novelty_routing_field.py |
Tests retention, warnings, saved metadata, and other-error exclusion. |
dokimi/tests/test_novelty_routing_all_vs_all.py |
Updates invalid fixtures and expected field metadata. |
dokimi/tests/test_catalog_validate.py |
Tests name conflicts involving over-limit descriptions. |
dokimi/dokimi/novelty/routing.py |
Retains length-only violations and generates warning records. |
dokimi/dokimi/external/validate.py |
Uses shared eligibility rules for name conflicts. |
dokimi/dokimi/external/listing.py |
Defines shared default listing eligibility. |
dokimi/dokimi/commands/novelty.py |
Uses the shared field serializer and updates CLI help. |
dokimi/dokimi/commands/novelty_routing_inputs.py |
Emits warnings and saves specification-warning metadata. |
dokimi/docs/skill-novelty.md |
Documents retention behavior and saved warnings. |
dokimi/docs/external-content.md |
Clarifies the catalog name-conflict exception. |
dokimi/changelog.d/20261104_120000_napetrov_desc-over-limit-kept.md |
Records the routing and catalog behavior changes. |
Review effort: Balanced
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 12 selected item(s). CI at Review details
|
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #405 +/- ##
=======================================
Coverage 94.78% 94.79%
=======================================
Files 353 355 +2
Lines 46527 46606 +79
Branches 7967 7976 +9
=======================================
+ Hits 44100 44179 +79
Misses 1540 1540
Partials 887 887
🚀 New features to boost your workflow:
|
antonwolfy
left a comment
There was a problem hiding this comment.
LGTM. The rule is one function (only_description_too_long), and the routing field, the explicit skill: competitors, the catalog path and catalog scan's name-conflict check all go through it. A description over 1024 characters with any other spec error still leaves the skill out. Two nits inline.
What I ran, on a Linux review host at 8db4eb4:
make ci-local: all steps pass exceptci.yml:test / Run tests. The whole suite ran to 100% with no test failure; the step then exited 1 on an unraisableResourceWarning(unclosed scandir iterator) in pytest's temp-dir cleanup at session end. It happened under Python 3.13 and no test failed; the PR touches nothing that opens a directory scan. Changed-line coverage is 100% on all five source files.- A mutation run: 16 mutants of
only_description_too_long,in_field,competitor_left_out,_left_out_by_flag,_name_conflicts,over_limit_warningsandfield_recordagainst the four touched test files. 14 are killed (includingall()toany(), dropping the guard in either path, and emptying the warning orspec_warnings). The survivors are the>to>=boundary (inline) and droppingbool(errors), which cannot be reached because both callers checkstate == "error"first. - Reproductions with the LLM transport mocked: a long description plus a second error is left out;
--include-invalidkeeps both and warns; a byte-identical mirror warns once; the warning prints once per run. - Commit has a
Signed-off-by. Noschemas/file coversfield.spec_warnings, so no schema bump is needed. The changelog fragment follows the README format.
Checked, no issues
- Imports:
dokimi.novelty.routing,external.listingandexternal.validateeach import on their own;listing.pyimportsSkillReviewonly underTYPE_CHECKING. - Help and docs: the
--include-invalidhelp text,skill-novelty.mdandexternal-content.mdagree with the code on the exception.
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
…over-limit-kept
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Not reproduced on head: py3.12 suite with -W error::ResourceWarning passes (15722, 0 warnings); CI py3.11/3.14 green. Send the py3.13 traceback if it persists. |
vlad-perevezentsev
left a comment
There was a problem hiding this comment.
Review at e343bb2. The fix is right: one predicate (only_description_too_long) keeps a skill whose only spec error is the length, in the catalog path, the skill: competitors and catalog scan's name-conflict check; any other error still leaves it out. The small gaps in the warning text, the skill under test and the changelog are in the line comments.
What I ran, at e343bb2:
make ci-local --offline: 15,670 passed, 0 failed, 63 skipped; all steps pass.- A lexical-only
novelty routingrun (no model call) with a 1139-character skill in the catalog and as--artifact: the catalog one is kept and warned about; the artifact itself is not inspec_warnings.
Checked, no issues
- Both nits from @antonwolfy: the 1024-character boundary is pinned by a test (652958a), and the
validate.pydocstring now names the exception (dc17ff8). --include-invalid: a long description plus a second error is still left out without it, and kept with it.- Saved field:
field_recordmoved tonovelty_routing_inputs.pyand both modes writespec_warnings; no schema coversfield, so no schema version is needed.
…over-limit-kept Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Claude Code shows a description in full up to about 1,536 characters, so the warning, the listing docstring and the changelog no longer say it cuts every over-limit description short. Thread: PRRT_kwDOVBg7g860Lum4 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…r the limit over_limit_warnings saw only the competitors, so a 1139-character --artifact was measured with no warning and was missing from field.spec_warnings. Thread: PRRT_kwDOVBg7g860Lum7 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…re-run Thread: PRRT_kwDOVBg7g860LunC Review: PRR_kwDOVBg7g88AAAABWQ4sRw Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…ning It is not in the field, so its warning and spec_warnings entry no longer say "kept in the field". Thread: PRRT_kwDOVBg7g860Lum7 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Thread: PRRT_kwDOVBg7g860Lum4 Thread: PRRT_kwDOVBg7g860Lum7 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…over-limit-kept Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Thanks. All three line comments fixed in 83251e8 and the commits before it. |
Conflicts: keep the PR's description-over-limit text in skill-novelty.md and routing.py, with catalog scan renamed to catalog check as intel#396 did; same rename in the PR's changelog fragment and external/listing.py docstring. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
vlad-perevezentsev
left a comment
There was a problem hiding this comment.
LGTM
I checked 20ec659. All three points from my last round are fixed: the warning says what each harness does at every over-limit length, the skill under test is warned about and saved in spec_warnings, and the changelog says to re-run a routing baseline.
Merge: safe now: it merges cleanly into current main, 0 commits behind. Once it is in, #394, #403 and #417 conflict with it (novelty.py, novelty_routing_inputs.py, validate.py, test_novelty_routing_field.py) and need a rebase.
What I ran, at 20ec659:
make ci-local --offline: 15,873 passed, 0 failed, 63 skipped; all steps pass.
Checked, no issues
- Skill under test:
load_routing_fieldprints its warning once andfield_recordputs it first inspec_warnings, named as the skill under test;--all-vs-allstill lists every skill once, as a field skill. The new test fails without thegoldargument. - Merge of #396: the docs, the docstrings and the fragment now say
catalog check.
antonwolfy
left a comment
There was a problem hiding this comment.
LGTM. The delta since my last review holds up: the 1024-character boundary is pinned by a test, the validate.py docstring names the exception, the skill under test is warned about and saved in field.spec_warnings, and the warning text and changelog now say what each harness does. Nothing new to fix.
What I ran, on a Linux review host at 20ec659:
make ci-local: 30 passed, 0 failed, 7 skipped (the skips are jobs that do not run on a PR or need tools absent here). The test step and the changed-line coverage step both pass. TheResourceWarningat session end from my earlier run did not recur.- A mutation run: 25 mutants of
only_description_too_long,in_field,over_limit_warnings,competitor_left_out,_left_out_by_flag,field_record, the warning prints inload_routing_fieldand_name_conflicts. 23 are killed. The two survivors are the redundantbool(errors)guard (unreachable, both callers checkstate == "error"first) and a> DESCRIPTION_MAX + 1threshold, which changes only whether a 1025-character skill gets its warning. The new tests against the base modules: 9 fail, as they should. - Reproductions with no model call: 1024 characters is not warned, 1025 is, by character count and not bytes; a long description plus a second error is left out by default and kept with
--include-invalid; a mirror warns once; the skill under test warns once and is listed once inspec_warnings;--all-vs-allsavesspec_warningsfor the field. - Every non-merge commit has a
Signed-off-by.
Checked, no issues
- Rule: the routing field, explicit
skill:competitors, the catalog path andcatalog check's name-conflict check all go throughonly_description_too_long. - Repo rules: no schema covers
field, so no version bump;cli-interface.jsonholds no help text, so the changed--include-invalidhelp needs no regeneration; the changelog fragment passes its check and the growth check is clean. - Tests: the new tests use
tmp_pathand leave the tree clean.
Summary
novelty routingused to leave a skill out of the field by default when its description is over 1024 characters, the Agent Skills spec limit. Harnesses do not agree on this: Claude Code 2.1.318 lists such a skill and cuts the description to about 1,536 characters, while pi.dev reportedly rejects it (anthropics/skills#881, #1622). So leaving the skill out measured every harness as the strictest one.--include-invalidfield.spec_warningsin the JSON--artifact) over the limitfield.spec_warningscatalog scanname-conflictEvidence
make ci-local: 15717 passedMerge danger
spec_warningssay why; re-run a saved baseline before comparing🤖 Generated with Claude Code