feat(skills): add skill-local safe_mode and resource classification #166
No reviewers
Labels
No labels
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Bounty
$100
Bounty
$1000
Bounty
$10000
Bounty
$20
Bounty
$2000
Bounty
$250
Bounty
$50
Bounty
$500
Bounty
$5000
Bounty
$750
MoSCoW
Could have
MoSCoW
Must have
MoSCoW
Should have
Needs Feedback
Points
1
Points
13
Points
2
Points
21
Points
3
Points
34
Points
5
Points
55
Points
8
Points
88
Priority
Backlog
Priority
CI Blocker
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
State
Completed
State
Duplicate
State
In Progress
State
In Review
State
Paused
State
Unverified
State
Verified
State
Wont Do
Type
Automation
Type
Bug
Type
Discussion
Type
Documentation
Type
Epic
Type
Feature
Type
Legendary
Type
Refactor
Type
Support
Type
Task
Type
Testing
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Blocks
#161 feat(skills): add skill-local safe_mode and resource classification
cleveragents/cleveractors-core
Reference
cleveragents/cleveractors-core!166
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feature/m1-skill-safe-mode-resource-classification"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds the ADR-2034 D-8/D-9 foundation to the Skill Package Schema:
safe_modeboolean (defaulttrue); non-boolean values raise the registryValidationError; absence stays canonical so existing Package IDs are unchanged;safe_mode: falseis retained and changes the content-addressed ID.references/,assets/,scripts/, non-standard, root file), case-sensitively.safe_modethroughSkill/SkillResourceand the loaded skill catalogue.Closes #161
Verification
nox -s unit_tests -- features/agent_skills.featurenox -s integration_tests -- robot/agent_skills.robotnox -s coverage_report— 97.2%nox -s lint,nox -s format,nox -s typecheck,nox -s security_scan,nox -s dead_codenox -s docsnox -s benchmark -- --bench SkillSince the PR likely has a wrong target branch (feature branch cut off from develop but PR merges into master), so the review agent gives a corrupted report. I'll pick the related stuff here.
Changes in commit
073ea04d7aare mostly solid, but the ADRs are kinda broken. The code and comments referencedADR-2034 D-8/D-9, but we have two ADR-2034 and the related one has only D1 to D-7, there is no D8 and D9. Due to this, I think my review agent failed to review the code because there is no spec to compare against.The minor issue and nits:
Minor Issues
src/cleveractors/agents/skill_schema.pylines 79–84 (classify) and 353–366 (_validate_resources). Path validation (pre-existing, unchanged here) rejects leading/and../segments but not\; a path likescripts\run.pycontains no/and classifies asROOT_FILE, which would let it bypass the futurescripts/policy gate. No enforcement exists yet in this PR, so impact is deferred — Recommendation: reject\in resource-path validation (or classify such pathsNON_STANDARD) now, or explicitly note it in the upcoming enforcement issue.Nits
src/cleveractors/agents/skill_schema.pylines 77–78 — theclassify()non-string/empty-pathValueErrorguard is the file's only uncovered line (99.6% file coverage). Defensive-only (the validator pre-validates paths); acceptable to leave.PR Review: !166 (Ticket #161)
Verdict: Request Changes
The implementation code is solid — validation order, ID canonicalization, catalogue plumbing, and tests are all correct and well-structured. However, the PR ships references to design decisions (ADR-2034 D-8/D-9/D-10) that are not recorded anywhere, and leaves the normative Skill Package Schema (§16.1/§16.2) unupdated while the new guide explicitly defers normativity to it. Both were flagged in the earlier comment and remain unaddressed; the author has not yet responded, so they stay open.
Scope notes: the wrong-target-branch problem mentioned earlier is resolved (base is now
develop, matching the branch point) and is dropped. Red-tape items (commit message, labels, atomicity, branch name) all check out and are excluded per instructions. No author responses exist on the PR or #161, so no item has been formally deferred by the author.Critical Issues
None
Major Issues
ADR-2034 D-8/D-9/D-10 are cited throughout but do not exist in the ADR.
docs/adr/ADR-2034-skill-package-support.mdrecords only D-1 through D-7. The following cite the nonexistent decisions:src/cleveractors/agents/skill_schema.py:41,skill_schema.py:51(docstrings: "ADR-2034 D-8")docs/guides/skill-packages.md:6anddocs/guides/skill-packages.md:122(D-8, D-9, D-10)benchmarks/skill_schema_benchmark.py:4,benchmarks/skill_schema_benchmark.py:21robot/agent_skills.robot(test documentation),examples/README.mdThe taxonomy and safe-mode decisions are the entire normative basis of this PR, yet no ADR records them. (The pre-existing ADR-2034 numbering collision with
ADR-2034-content-not-contains-all-subsystems.mdmakes the dangling references more confusing.)Recommendation: amend ADR-2034 with the D-8 (resource taxonomy) and D-9 (skill-local
safe_mode) decisions — or add a follow-up ADR — before merge, so the code and guide cite a decision that actually exists.The normative schema was not updated: §16.1 field table and §16.2 identity enumeration lack
safe_mode.docs/guides/skill-packages.md:8-9states "The normative field table remains Package Registry Standard §16.1", butdocs/actor-registry-standard.md§16.1's field table has nosafe_moderow, and §16.2's identity discussion enumerates the hashed fields (skill/name/description/.../resources) withoutsafe_mode— even though this PR makessafe_mode: falsepart of the content-addressed identity.Recommendation: add the
safe_moderow (optional boolean, defaulttrue, non-boolean rejected) to §16.1 and include it in §16.2's identity enumeration.Minor Issues
ROOT_FILE.src/cleveractors/agents/skill_schema.py:353-366(_validate_resources) andskill_schema.py:79-84(classify): path validation rejects leading/and./..segments but not\\; a path likescripts\\run.pycontains no/and classifies asROOT_FILE, which would let it bypass the futurescripts/policy gate. No enforcement exists yet in this PR, so impact is deferred — as noted in the earlier comment — but this PR is the foundation that classification is built on.Recommendation: reject
\\in resource-path validation (or classify such pathsNON_STANDARD) now, or explicitly record it in the upcoming enforcement issue.Nits
src/cleveractors/agents/skill_schema.py:77-78— theclassify()non-string/empty-pathValueErrorguard is the file's only uncovered code (defensive-only; the validator pre-validates paths). A one-line scenario asserting theValueErrorwould bring the file to 100%.Summary
Well-implemented foundation: the classifier is a clean table-driven Strategy,
safe_modevalidation/canonicalization is correct (absence ≡truefor ID purposes,falseretained and identity-changing, validated before ID computation), the catalogue picks up the new fields automatically viato_context_dict()with no changes needed inSkillLoader, no otherSkillResourceconstruction sites break, and the skill tool tolerates the additiveclasskey. Behave and Robot coverage is meaningful, including case-sensitivity and package-ID equivalence scenarios. The blockers are purely documentary but matter in a docs-first project: record D-8/D-9 in the ADR and update §16.1/§16.2, then this is ready to merge.@ -0,0 +3,4 @@A `skill` package is a single content-addressed YAML mapping that carries askill's metadata, instructions, and bundled files. This guide covers theskill-local safety switch and the resource-directory taxonomy added by[ADR-2034](../adr/ADR-2034-skill-package-support.md) (D-8 and D-9).Major: ADR-2034 (skill-package-support) records only D-1..D-7 — D-8/D-9/D-10 cited here (and in
skill_schema.pydocstrings, benchmarks, robot docs, examples/README) do not exist. Please amend the ADR (or add a follow-up ADR) recording these decisions before merge.@ -0,0 +6,4 @@[ADR-2034](../adr/ADR-2034-skill-package-support.md) (D-8 and D-9).The normative field table remains[Package Registry Standard §16.1](../actor-registry-standard.md#161-skill-package-schema).Major: this guide defers normativity to §16.1 of
docs/actor-registry-standard.md, but that field table was not updated in this PR — it has nosafe_moderow, and §16.2's identity enumeration does not include it even thoughsafe_mode: falsenow changes the Package ID. Please update both sections.@ -39,0 +74,4 @@from the first segment, or ``NON_STANDARD`` when it is not one ofthe three standard directories."""if not isinstance(path, str) or not path:Nit: this defensive ValueError guard is the only uncovered code in the file; a one-line scenario asserting the error would bring the file to 100%.
Minor (deferred impact, flagged earlier): path validation rejects leading
/and./..segments but not\\;scripts\\run.pyhas no/and classifies as ROOT_FILE, which would bypass the futurescripts/policy gate. Recommend rejecting\\here (or classifying such paths NON_STANDARD), or explicitly noting it in the upcoming enforcement issue.Review complete — see the report above. Two major documentation/spec-integrity issues (missing ADR-2034 D-8/D-9 records; §16.1/§16.2 not updated) block the merge; code itself looks correct.
@ -0,0 +3,4 @@A `skill` package is a single content-addressed YAML mapping that carries askill's metadata, instructions, and bundled files. This guide covers theskill-local safety switch and the resource-directory taxonomy added by[ADR-2034](../adr/ADR-2034-skill-package-support.md) (D-8 and D-9).Major: ADR-2034 (skill-package-support) records only D-1..D-7 — D-8/D-9/D-10 cited here (and in
skill_schema.pydocstrings, benchmarks, robot docs, examples/README) do not exist. Please amend the ADR (or add a follow-up ADR) recording these decisions before merge.@ -0,0 +6,4 @@[ADR-2034](../adr/ADR-2034-skill-package-support.md) (D-8 and D-9).The normative field table remains[Package Registry Standard §16.1](../actor-registry-standard.md#161-skill-package-schema).Major: this guide defers normativity to §16.1 of
docs/actor-registry-standard.md, but that field table was not updated in this PR — it has nosafe_moderow, and §16.2's identity enumeration does not include it even thoughsafe_mode: falsenow changes the Package ID. Please update both sections.@ -39,0 +74,4 @@from the first segment, or ``NON_STANDARD`` when it is not one ofthe three standard directories."""if not isinstance(path, str) or not path:Nit: this defensive ValueError guard is the only uncovered code in the file; a one-line scenario asserting the error would bring the file to 100%.
Minor (deferred impact, flagged earlier): path validation rejects leading
/and./..segments but not\\;scripts\\run.pyhas no/and classifies as ROOT_FILE, which would bypass the futurescripts/policy gate. Recommend rejecting\\here (or classifying such paths NON_STANDARD), or explicitly noting it in the upcoming enforcement issue.073ea04d7a98fbb9886398fbb98863939e93d391939e93d391ae7b44734aPR Review: !166 (Ticket #161)
Verdict: Approve
All four findings from the earlier (now stale) REQUEST_CHANGES review were addressed in the reworked single commit
ae7b447: the ADR-2034 amendment now records D-8/D-9/D-10 with rationale and revision history; Package Registry Standard §16.1/§16.2 are updated with the 1.2.0 version bump; backslash paths are now rejected by validation; and the classifier's defensive guard is covered by a scenario. The implementation matches the ticket and the amended spec, the Behave/Robot tests are meaningful and cover every acceptance criterion, and all blocking CI gates pass (thebenchmarkjob failure is pre-existing ondevelopitself and non-gating by design —continue-on-error: true, excluded fromstatus-check).Note on prior discussion: the PR author left no text comments; the response came as the reworked commit, which resolved every prior finding (ADR records, §16 updates, backslash rejection, guard coverage) and the PR is now correctly based on/merged into
develop(branch cut from4b98ce0= develop head).Critical Issues
None.
Major Issues
None.
Minor Issues
None.
Nits
docs/adr/ADR-2034-skill-package-support.md, "Follow-up Required" section: the "Specification updates (revision)" bullet still asks to addsafe_modeand the D-8 taxonomy to §16.1/§16.3 "(intended Version 1.2.0)", and the "Revision implementation (D-8–D-10)" bullet lumps in the schema-side work (safe_modethroughSkill/SkillValidator/SkillLoader, path classification) that this PR itself completes. Only the D-10 enforcement half (llm_toolsexecute/args/timeout, the double-safety gate plus temporary-tree execution inToolAgent._skill_tool) actually remains open. Recommend splitting these bullets into "done by #161" vs "remaining (D-10 enforcement)" so the follow-up list stays accurate.safe_modenaming ambiguity in the new guide —docs/guides/skill-packages.md("Related documentation"):safe_modenow denotes two distinct switches — the agent-levelsafe_mode(§4.5,docs/tools/safe-mode.md) and the new skill-level field (§16.1). The guide states the double-gate relationship in prose; a one-line disambiguation or a cross-link to the agent-level safe-mode guide would prevent confusion for readers arriving from either document.Scope confirmations (per prior discussion — not re-reported, excluded from this review)
executeaction, double-safety gate inToolAgent._skill_tool, temporary-tree materialization) is explicitly deferred by the ADR's "Follow-up Required" and the ticket's "no script execution" scope — correctly out of scope here.pack_skill_directorypreserving directories and emittingsafe_modeonly when false) — ADR follow-up, does not exist yet in the codebase; out of scope.developand is based on its head.benchmarkjob failure — pre-existing: the same job fails on thedevelophead commit (4b98ce0) for both push and pull_request events, before this PR's benchmark file existed on that branch; the job iscontinue-on-error: trueand excluded from thestatus-checkgate, which passed. Not attributable to this PR.Summary
A clean, well-scoped foundation PR for ADR-2034 D-8/D-9.
skill_schema.pyadds theSkillResourceClassenum and a table-driven, case-sensitiveSkillResourceClassifier;safe_modevalidation raises the registryValidationErrorfor non-boolean values (includingnulland1); absence stays canonical for the Package ID while an explicittrueis normalized away andfalseis retained, exactly per D-9/D-3. The pre-existing backslash gap is closed (validator, error message, tests, and docs all agree).SkillLoaderneeds no changes — the catalogue serializesto_context_dict(), which now carriessafe_modeand per-resourceclass; the only consumer (ToolAgent._skill_tool) readscontent/encodingkeys, so the additions are inert. Tests are genuinely assertive: ID equality/difference is checked against an independently computed canonical ID, all five classes plus theScripts/case-sensitivity rule are covered, and the loaded-catalogue exposure is verified in both Behave and Robot. Documentation is thorough and internally consistent (ADR D-8/D-9/D-10 + alternatives A-7..A-13 + revision history; standard 1.2.0 field table, classification paragraph, §16.2 identity paragraph, §16.3 example; new authoring guide wired into mkdocs nav; example package; CHANGELOG entry). Coverage gating and all required CI jobs pass. Only two documentation nits remain, neither blocking.ae7b44734ac97ffe7b6b