skill-claims 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- skill_claims-1.0.0/LICENSE +21 -0
- skill_claims-1.0.0/PKG-INFO +432 -0
- skill_claims-1.0.0/README.md +406 -0
- skill_claims-1.0.0/pyproject.toml +52 -0
- skill_claims-1.0.0/setup.cfg +4 -0
- skill_claims-1.0.0/src/skill_claims.egg-info/PKG-INFO +432 -0
- skill_claims-1.0.0/src/skill_claims.egg-info/SOURCES.txt +10 -0
- skill_claims-1.0.0/src/skill_claims.egg-info/dependency_links.txt +1 -0
- skill_claims-1.0.0/src/skill_claims.egg-info/entry_points.txt +2 -0
- skill_claims-1.0.0/src/skill_claims.egg-info/top_level.txt +1 -0
- skill_claims-1.0.0/src/skill_claims.py +1584 -0
- skill_claims-1.0.0/tests/test_skill_claims.py +731 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jasveer Singh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skill-claims
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Receipt an agent skill's claims against its own code — every claim SUPPORTED, UNEVIDENCED or CONTRADICTED, with file-and-line evidence.
|
|
5
|
+
Author: Jasveer Singh
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/jasveerai88/skill-claims
|
|
8
|
+
Project-URL: Repository, https://github.com/jasveerai88/skill-claims
|
|
9
|
+
Project-URL: Issues, https://github.com/jasveerai88/skill-claims/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/jasveerai88/skill-claims/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: agent-skills,claude-code,ai-agents,honesty,audit,static-analysis,cli
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Security
|
|
21
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
<h1 align="center">skill-claims</h1>
|
|
28
|
+
|
|
29
|
+
<p align="center"><strong>Your agent skill says "offline". Receipt it — every claim SUPPORTED, UNEVIDENCED, or CONTRADICTED, with file-and-line evidence.</strong></p>
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<img alt="tests: 48 passing" src="https://img.shields.io/badge/tests-48%20passing-brightgreen">
|
|
33
|
+
<img alt="python 3.10 | 3.11 | 3.12" src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue">
|
|
34
|
+
<img alt="version 1.0.0" src="https://img.shields.io/badge/version-1.0.0-orange">
|
|
35
|
+
<img alt="dependencies: none" src="https://img.shields.io/badge/dependencies-0-brightgreen">
|
|
36
|
+
<img alt="license: MIT" src="https://img.shields.io/badge/license-MIT-blue">
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
<p align="center"><img alt="skill-claims demo: an 'offline' formatter's receipt flips CONTRADICTED on three claims" src="docs/demo.gif" width="880"></p>
|
|
40
|
+
|
|
41
|
+
A skill's description is a promise. The loader trusts it, the
|
|
42
|
+
marketplace lists it, and you install on it. The measurement of
|
|
43
|
+
how often the promise holds is not reassuring:
|
|
44
|
+
*Behavioral Integrity Verification for AI Agent Skills*
|
|
45
|
+
(arXiv:2605.11770, checked 2026-11-06) compared declared vs
|
|
46
|
+
actual behaviour across **49,943 OpenClaw-registry skills and
|
|
47
|
+
found 80.0% deviate from their declared behaviour — and 81.1%
|
|
48
|
+
of the deviations were developer oversight, only 18.9%
|
|
49
|
+
adversarial.** The honesty problem is mostly not malice. It is
|
|
50
|
+
drift, copy-paste, and a description nobody re-read after the
|
|
51
|
+
code changed.
|
|
52
|
+
|
|
53
|
+
Security scanners ask a different question — *is it
|
|
54
|
+
dangerous?* — and the few that touch claims at all bury the
|
|
55
|
+
answer inside an LLM judgement or a 0–100 security score.
|
|
56
|
+
skill-claims asks only the honesty question, and answers it
|
|
57
|
+
the boring way: extract what the package **claims** (from its
|
|
58
|
+
own description and docs, by a deterministic pattern library),
|
|
59
|
+
extract what the package **does** (from its bundled scripts,
|
|
60
|
+
by static pattern tables), and print a per-claim receipt.
|
|
61
|
+
No LLM. No score. No network. Nothing uploaded.
|
|
62
|
+
|
|
63
|
+
**Static and read-only — it executes nothing.** Claims never
|
|
64
|
+
imports, runs, or evaluates anything in the package; every
|
|
65
|
+
file is read as text and judged as evidence. Its own source
|
|
66
|
+
imports no network or subprocess module, and the test suite
|
|
67
|
+
proves the read-only claim: a fixture script that would write
|
|
68
|
+
a marker file if it ran never runs, and every fixture tree
|
|
69
|
+
comes out byte-identical after an audit.
|
|
70
|
+
|
|
71
|
+
## The honesty pair (and the trio)
|
|
72
|
+
|
|
73
|
+
Two different questions get asked before a skill is trusted,
|
|
74
|
+
and they deserve two different tools:
|
|
75
|
+
|
|
76
|
+
- **[skill-vet](https://github.com/jasveerai88/skill-vet) —
|
|
77
|
+
is it dangerous?** Stealing, spying, hidden sending, each
|
|
78
|
+
proven as a combination of evidence.
|
|
79
|
+
- **skill-claims — is it honest?** Does the package do what
|
|
80
|
+
its description claims — and only that?
|
|
81
|
+
|
|
82
|
+
And after the agent runs:
|
|
83
|
+
**[done-claim-auditor](https://github.com/jasveerai88/done-claim-auditor) —
|
|
84
|
+
did the agent do what *it* claimed?** The same
|
|
85
|
+
claim-vs-evidence logic pointed at session transcripts.
|
|
86
|
+
Claims is built to run beside skill-vet as a pre-install
|
|
87
|
+
gate: vet first for danger, then claims for honesty. That
|
|
88
|
+
is exactly how it is used in its author's own engine —
|
|
89
|
+
every skill adopted there passes both before install.
|
|
90
|
+
|
|
91
|
+
## Quick start
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pipx install git+https://github.com/jasveerai88/skill-claims # or: pip install git+https://github.com/jasveerai88/skill-claims
|
|
95
|
+
skill-claims audit ~/Downloads/some-skill
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
One command, one receipt, an exit code you can gate on —
|
|
99
|
+
**1** = at least one claim CONTRADICTED, **0** = no claim
|
|
100
|
+
contradicted, **2** = input error. Add `--json` for a
|
|
101
|
+
machine-readable receipt. From a source checkout,
|
|
102
|
+
`python3 src/skill_claims.py audit <package>` does the same
|
|
103
|
+
thing. Python 3.10+, standard library only, no dependencies.
|
|
104
|
+
|
|
105
|
+
## What it receipts
|
|
106
|
+
|
|
107
|
+
Claims are read from the frontmatter `description`, the
|
|
108
|
+
SKILL.md body, and a root README.md. Behaviour is read from
|
|
109
|
+
every bundled script. The verdicts:
|
|
110
|
+
|
|
111
|
+
| Claim type | Example phrasing | SUPPORTED when | CONTRADICTED when |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| **Capability** | "Formats markdown tables" | The claim's key words appear in the package's code | *Never* — static analysis cannot prove a feature absent, so a capability with no code evidence is UNEVIDENCED |
|
|
114
|
+
| **Offline** | "Works fully offline, no network access" | No network call in any scanned script | Any network call (`urllib`, `requests`, `socket`, `curl`, …), cited file + line |
|
|
115
|
+
| **Sends nothing** | "Nothing leaves your machine" | No network call in any scanned script | Any network call — every connection sends at least a request |
|
|
116
|
+
| **Read scope** | "Only reads the files you pass it" | No credential read, no read outside the package | A credential-store read, or a read of a path outside the package |
|
|
117
|
+
| **Credentials** | "Never touches your credentials" | No credential-store or env-secret read | Any credential-store path (`.aws`, `.ssh`, …) or env-secret read |
|
|
118
|
+
| **No writes** | "Writes nothing" | No file write in any scanned script | Any write (`open(..., 'w')`, `.write(`, `shutil.copy`, …) |
|
|
119
|
+
| **No writes (scoped)** | "Never write inside the project directory" | No writes at all | A write provably aimed at the package's own location (`__file__`-relative). Writes to runtime-computed paths are UNEVIDENCED — static evidence can't place them inside the named scope |
|
|
120
|
+
| **Write scope** | "Never writes outside the project" | Writes exist but all stay inside scope, or no writes at all | A write to a home / system / outside path |
|
|
121
|
+
| **No shell** | "Never runs shell commands" | No subprocess / shell use; no shell scripts | `subprocess`, `os.system`, `shell=True`, or a bundled `.sh` |
|
|
122
|
+
| **No deletion** | "Never deletes anything" | No deletion in any scanned script | `os.remove`, `shutil.rmtree`, `.unlink(`, `rm -rf`, … |
|
|
123
|
+
| **Environment** | "Does not read environment variables" | No env read in any scanned script | `os.environ`, `getenv(`, `process.env`, … |
|
|
124
|
+
| **Quality / absolute** | "Guaranteed 100% accurate" | — | — (always UNEVIDENCED: no static evidence can test a quality claim, and the receipt says so instead of pretending) |
|
|
125
|
+
|
|
126
|
+
Behaviour that **no claim covers** is listed at the end of
|
|
127
|
+
every receipt too — a skill that never claims to be offline
|
|
128
|
+
but calls the network is not contradicted, it is simply on
|
|
129
|
+
the record.
|
|
130
|
+
|
|
131
|
+
[Quick start](#quick-start) · [What it receipts](#what-it-receipts) ·
|
|
132
|
+
[How it compares](#how-it-compares) · [Reference](#reference)
|
|
133
|
+
|
|
134
|
+
## How it compares
|
|
135
|
+
|
|
136
|
+
| | **skill-claims** | NVIDIA SkillSpector | SkillAuditor.dev | PyPI skill-auditor |
|
|
137
|
+
|---|---|---|---|---|
|
|
138
|
+
| The question | Is it **honest** — does it do what it claims? | Is it **dangerous**? (security) | Is it safe, proven in a sandbox? | Is it safe to install? (security) |
|
|
139
|
+
| Claim-vs-behaviour | The whole product: a per-claim receipt | One part of an optional LLM "Deep Mode" | Part of the hosted verdict | One rule (`description-mismatch`) inside a scanner |
|
|
140
|
+
| Method | Deterministic static patterns — same package, same receipt, forever | Pattern scan + LLM judgement | Hosted sandbox simulation, verdict recorded onchain | LLM-assisted scanner |
|
|
141
|
+
| Output | Per-claim SUPPORTED / UNEVIDENCED / CONTRADICTED with file + line | A 0–100 security score | A hosted verdict | Scanner findings |
|
|
142
|
+
| Runs where | Your machine, offline, stdlib only | Your machine (LLM mode needs a model) | Their service | Your machine + an LLM |
|
|
143
|
+
| Score? | **No score, by design** — a receipt, not a rating | Yes | Verdict | Findings |
|
|
144
|
+
|
|
145
|
+
*(Competitor descriptions from their own public pages,
|
|
146
|
+
checked 2026-11-06. SkillSpector is a strong security
|
|
147
|
+
scanner — it is listed here because it is the closest
|
|
148
|
+
neighbour, and because "dangerous?" and "honest?" are
|
|
149
|
+
different questions that both deserve asking.)*
|
|
150
|
+
|
|
151
|
+
## Honest limits (the short version)
|
|
152
|
+
|
|
153
|
+
Static patterns are evidence, not proof. A package that
|
|
154
|
+
assembles its behaviour at runtime, downloads its real
|
|
155
|
+
logic later, hides behaviour in a bundled binary, or buries
|
|
156
|
+
it in obfuscated code can look consistent — every receipt
|
|
157
|
+
prints this. A SUPPORTED verdict means *the static evidence
|
|
158
|
+
backs the claim*, not that the skill is proven honest. The
|
|
159
|
+
full limits are [below](#honest-limits).
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Reference
|
|
164
|
+
|
|
165
|
+
**Contents:** [The lying formatter](#the-lying-formatter--the-demo-fixture) ·
|
|
166
|
+
[The honest skill](#the-honest-skill--the-other-direction) ·
|
|
167
|
+
[For agents](#for-agents) · [Tests](#tests) ·
|
|
168
|
+
[Honest limits](#honest-limits)
|
|
169
|
+
|
|
170
|
+
### The lying formatter — the demo fixture
|
|
171
|
+
|
|
172
|
+
`examples/lying-formatter/` is a constructed package: a
|
|
173
|
+
markdown formatter whose description promises full offline
|
|
174
|
+
working and reads limited to the files you pass, whose body
|
|
175
|
+
promises it never touches your credentials — and whose
|
|
176
|
+
`scripts/telemetry.py` helper reads `~/.aws/credentials`
|
|
177
|
+
and POSTs it with `urllib`. Every endpoint is an `.invalid`
|
|
178
|
+
name — fictional by design. Verbatim output:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
$ skill-claims audit examples/lying-formatter
|
|
182
|
+
skill-claims v1.0.0 — audit · package lying-formatter · 3 files · 4 claims
|
|
183
|
+
Frontmatter name: lying-formatter
|
|
184
|
+
Read-only: it edits nothing, writes nothing, and never executes anything in the package — every file is analysed as static text.
|
|
185
|
+
Verdict rule: CONTRADICTED needs hard evidence: a claim is only contradicted when the package's own code does the thing the claim rules out, cited file + line. SUPPORTED = the evidence the claim needs was found, or the ruled-out behaviour was searched for across every scanned script and not found. UNEVIDENCED = the claim was made, but static evidence can neither back it nor break it. A capability claim is never CONTRADICTED. Exit 1 only when at least one claim is CONTRADICTED; exit 2 is an input error.
|
|
186
|
+
Limits: Static evidence only: skill-claims reads the package's text and never runs it. Behaviour that appears only at runtime — later downloads, payloads assembled from pieces, obfuscated or encoded code, bundled binaries — is out of scope and can make a dishonest skill look consistent. SUPPORTED means the static evidence backs the claim, not that the skill is proven honest.
|
|
187
|
+
|
|
188
|
+
CLAIMS (4):
|
|
189
|
+
[SUPPORTED] capability — "Formats markdown tables and tidies headings in the files you pass it"
|
|
190
|
+
stated: SKILL.md · line 3
|
|
191
|
+
evidence for: scripts/format.py · line 2 — 'format' appears here
|
|
192
|
+
evidence for: scripts/format.py · line 2 — 'markdown' appears here
|
|
193
|
+
evidence for: scripts/format.py · line 2 — 'tables' appears here
|
|
194
|
+
basis: 5 of the claim's 5 key words (formats, headings, markdown, tables, tidies) appear in the package's code — the vocabulary of the feature the claim names is present in the implementation itself, which is the static evidence a capability claim can be receipted on.
|
|
195
|
+
[CONTRADICTED] offline — "Works fully offline with no network access"
|
|
196
|
+
stated: SKILL.md · line 3
|
|
197
|
+
evidence against: scripts/telemetry.py · line 20 — a urllib request call
|
|
198
|
+
evidence against: scripts/telemetry.py · line 22 — a urllib request call
|
|
199
|
+
basis: the claim rules out network use, but the package's own code makes network calls — the claim and the code cannot both be true.
|
|
200
|
+
[CONTRADICTED] read scope — "only reads the files you pass it"
|
|
201
|
+
stated: SKILL.md · line 3
|
|
202
|
+
evidence against: scripts/telemetry.py · line 11 — an AWS credentials/config path
|
|
203
|
+
evidence against: scripts/telemetry.py · line 11 — a read of a path outside the package
|
|
204
|
+
basis: the claim limits reads to the files the user passes (or the package's own scope), but the package's own code reads beyond that.
|
|
205
|
+
[CONTRADICTED] credentials — "Never touches your credentials"
|
|
206
|
+
stated: SKILL.md · line 21
|
|
207
|
+
evidence against: scripts/telemetry.py · line 11 — an AWS credentials/config path
|
|
208
|
+
basis: the claim rules out touching credentials, but the package's own code reads credential material.
|
|
209
|
+
|
|
210
|
+
BEHAVIOUR FOUND (2 script(s) scanned):
|
|
211
|
+
network calls — 2 hit(s); first: scripts/telemetry.py · line 20 — a urllib request call
|
|
212
|
+
credential-store / env-secret reads — 1 hit(s); first: scripts/telemetry.py · line 11 — an AWS credentials/config path
|
|
213
|
+
environment-variable reads — none found
|
|
214
|
+
reads of paths outside the package — 1 hit(s); first: scripts/telemetry.py · line 11 — a read of a path outside the package
|
|
215
|
+
file writes — none found
|
|
216
|
+
writes to paths outside the package — none found
|
|
217
|
+
shell / subprocess use — none found
|
|
218
|
+
deletions — none found
|
|
219
|
+
|
|
220
|
+
Summary: 4 claims · 1 supported · 0 unevidenced · 3 contradicted
|
|
221
|
+
Verdict: CONTRADICTED — 3 claim(s) are contradicted by the package's own code.
|
|
222
|
+
(exit code 1)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Note what is *not* contradicted: the capability claim. The
|
|
226
|
+
formatter really does format tables — the receipt says so,
|
|
227
|
+
on the same page as the three broken promises. A receipt
|
|
228
|
+
that only lists failures would be a scanner, not a receipt.
|
|
229
|
+
|
|
230
|
+
### The honest skill — the other direction
|
|
231
|
+
|
|
232
|
+
`examples/honest-skill/` makes five claims — a capability,
|
|
233
|
+
offline working, no writes, reads limited to named files,
|
|
234
|
+
no deletion — and its one script does exactly that and no
|
|
235
|
+
more:
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
$ skill-claims audit examples/honest-skill
|
|
239
|
+
skill-claims v1.0.0 — audit · package honest-skill · 2 files · 5 claims
|
|
240
|
+
Frontmatter name: honest-skill
|
|
241
|
+
Read-only: it edits nothing, writes nothing, and never executes anything in the package — every file is analysed as static text.
|
|
242
|
+
Verdict rule: CONTRADICTED needs hard evidence: a claim is only contradicted when the package's own code does the thing the claim rules out, cited file + line. SUPPORTED = the evidence the claim needs was found, or the ruled-out behaviour was searched for across every scanned script and not found. UNEVIDENCED = the claim was made, but static evidence can neither back it nor break it. A capability claim is never CONTRADICTED. Exit 1 only when at least one claim is CONTRADICTED; exit 2 is an input error.
|
|
243
|
+
Limits: Static evidence only: skill-claims reads the package's text and never runs it. Behaviour that appears only at runtime — later downloads, payloads assembled from pieces, obfuscated or encoded code, bundled binaries — is out of scope and can make a dishonest skill look consistent. SUPPORTED means the static evidence backs the claim, not that the skill is proven honest.
|
|
244
|
+
|
|
245
|
+
CLAIMS (5):
|
|
246
|
+
[SUPPORTED] capability — "Formats markdown tables in the files you pass it"
|
|
247
|
+
stated: SKILL.md · line 3
|
|
248
|
+
evidence for: scripts/format.py · line 2 — 'format' appears here
|
|
249
|
+
evidence for: scripts/format.py · line 2 — 'markdown' appears here
|
|
250
|
+
evidence for: scripts/format.py · line 2 — 'tables' appears here
|
|
251
|
+
basis: 3 of the claim's 3 key words (formats, markdown, tables) appear in the package's code — the vocabulary of the feature the claim names is present in the implementation itself, which is the static evidence a capability claim can be receipted on.
|
|
252
|
+
[SUPPORTED] offline — "Works fully offline"
|
|
253
|
+
stated: SKILL.md · line 3; SKILL.md · line 19
|
|
254
|
+
basis: no network call was found in any of the 1 scanned script(s) — the behaviour the claim rules out is absent from the static evidence.
|
|
255
|
+
[SUPPORTED] no writes — "writes nothing"
|
|
256
|
+
stated: SKILL.md · line 3; SKILL.md · line 10
|
|
257
|
+
basis: no file write was found in any of the 1 scanned script(s).
|
|
258
|
+
[SUPPORTED] read scope — "reads only the files you name"
|
|
259
|
+
stated: SKILL.md · line 3
|
|
260
|
+
basis: no credential-store read and no read of a path outside the package was found in any of the 1 scanned script(s).
|
|
261
|
+
[SUPPORTED] no deletion — "It never deletes anything"
|
|
262
|
+
stated: SKILL.md · line 20
|
|
263
|
+
basis: no deletion was found in any of the 1 scanned script(s).
|
|
264
|
+
|
|
265
|
+
BEHAVIOUR FOUND (1 script(s) scanned):
|
|
266
|
+
network calls — none found
|
|
267
|
+
credential-store / env-secret reads — none found
|
|
268
|
+
environment-variable reads — none found
|
|
269
|
+
reads of paths outside the package — none found
|
|
270
|
+
file writes — none found
|
|
271
|
+
writes to paths outside the package — none found
|
|
272
|
+
shell / subprocess use — none found
|
|
273
|
+
deletions — none found
|
|
274
|
+
|
|
275
|
+
Summary: 5 claims · 5 supported · 0 unevidenced · 0 contradicted
|
|
276
|
+
Verdict: SUPPORTED — every claim the package makes is backed by the static evidence.
|
|
277
|
+
(exit code 0)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### For agents
|
|
281
|
+
|
|
282
|
+
`--json` emits one object: the package record, the full
|
|
283
|
+
file inventory (`path`, `bytes`, `kind`, `binary`,
|
|
284
|
+
`scanned`, `symlink_out`), the claims (each with `type`,
|
|
285
|
+
`text`, every `stated_at` file + line, `verdict`, `basis`,
|
|
286
|
+
and `evidence` hits with file + line), the behaviour map
|
|
287
|
+
(per class: `count` + `hits`), `scripts_scanned`,
|
|
288
|
+
`unclaimed_behaviour`, summary counts that recount exactly
|
|
289
|
+
against the claims, the overall verdict, the verdict rule,
|
|
290
|
+
and the limits statement. Input errors — including argument
|
|
291
|
+
errors — are a single JSON object with an `error` key and
|
|
292
|
+
exit 2. [SKILL.md](SKILL.md) states the full claim table,
|
|
293
|
+
the verdict rules, and the JSON contract — and makes
|
|
294
|
+
skill-claims itself installable as a skill: point your
|
|
295
|
+
agent at this repo's SKILL.md and it will receipt skills
|
|
296
|
+
before installing them.
|
|
297
|
+
|
|
298
|
+
### Tests
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
python3 -m unittest discover -s tests
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
48 tests: both fixtures pinned to hand-worked receipts;
|
|
305
|
+
every claim type extracted and judged in both directions
|
|
306
|
+
(the behaviour present flips the claim to CONTRADICTED;
|
|
307
|
+
absent, the same claim is SUPPORTED); the UNEVIDENCED
|
|
308
|
+
paths (a capability with no code evidence, a quality
|
|
309
|
+
claim, a package whose binary content cannot be scanned,
|
|
310
|
+
a scoped write claim whose targets are runtime paths);
|
|
311
|
+
unclaimed behaviour listed without being contradicted;
|
|
312
|
+
the error contract (missing folder, no SKILL.md, empty or
|
|
313
|
+
unparseable SKILL.md — clean `{"error": ...}`, exit 2,
|
|
314
|
+
never a traceback, in text and `--json` modes); regression
|
|
315
|
+
pins from receipts run against real packages before
|
|
316
|
+
release (a directory-tree diagram is not a claim, vendored
|
|
317
|
+
`.venv` code is not the package's own, a noun-phrase
|
|
318
|
+
fragment is not a capability); and the safety proofs —
|
|
319
|
+
nothing in a package is ever executed, fixture trees are
|
|
320
|
+
byte-identical after runs, output is byte-identical
|
|
321
|
+
across runs, and the source's imports are pinned to a
|
|
322
|
+
stdlib set with no network or subprocess module.
|
|
323
|
+
|
|
324
|
+
### Honest limits
|
|
325
|
+
|
|
326
|
+
- **Static evidence only — dynamic behaviour is out of
|
|
327
|
+
scope.** Claims reads the package's text; it never runs
|
|
328
|
+
it. Behaviour that appears only at runtime — code
|
|
329
|
+
downloaded and executed later, payloads assembled from
|
|
330
|
+
innocuous pieces, obfuscated or encoded logic, and
|
|
331
|
+
bundled binaries — cannot be receipted, and a dishonest
|
|
332
|
+
skill can hide behind exactly that. Every receipt
|
|
333
|
+
prints this.
|
|
334
|
+
- **CONTRADICTED is reserved for hard evidence.** A claim
|
|
335
|
+
flips only when the package's own code does the ruled-out
|
|
336
|
+
thing. Suspicion, style, and similarity never flip a
|
|
337
|
+
claim — they produce no verdict at all.
|
|
338
|
+
- **Capability claims are never CONTRADICTED.** Static
|
|
339
|
+
analysis cannot prove a feature absent — a capability
|
|
340
|
+
implemented in an unusual way may earn UNEVIDENCED
|
|
341
|
+
instead of SUPPORTED. The receipt states the key words
|
|
342
|
+
it looked for, so a human can overrule it in seconds.
|
|
343
|
+
- **Capability evidence is vocabulary-level.** SUPPORTED
|
|
344
|
+
for a capability means the feature's key words appear in
|
|
345
|
+
the code — the strongest static signal available without
|
|
346
|
+
running the skill, and a weaker one than the
|
|
347
|
+
contradiction evidence. The basis line says exactly
|
|
348
|
+
which words were found.
|
|
349
|
+
- **Claim extraction is a pattern library.** It reads the
|
|
350
|
+
frontmatter description, the SKILL.md body, and a root
|
|
351
|
+
README.md, and recognises the phrasings in the claim
|
|
352
|
+
table. A claim phrased outside the library is not
|
|
353
|
+
extracted — and therefore not receipted. Claims of the
|
|
354
|
+
same type are receipted together (first phrasing quoted,
|
|
355
|
+
every stating place listed). Capability claims are read
|
|
356
|
+
from the description only — the declared capability of
|
|
357
|
+
record; behavioural claims are read from all three
|
|
358
|
+
documents. In the documents, only **prose** counts:
|
|
359
|
+
fenced code blocks, indented code, table rows, and
|
|
360
|
+
directory-tree diagrams are illustrations, not claims.
|
|
361
|
+
- **Vendored code is not the package's own code.**
|
|
362
|
+
Dependency trees (`node_modules`, `.venv`, `venv`,
|
|
363
|
+
`site-packages`) are excluded from the walk: a claim is
|
|
364
|
+
receipted against what the author wrote, not against a
|
|
365
|
+
bundled library's behaviour. A skill that hides its own
|
|
366
|
+
code inside a folder with one of those names is out of
|
|
367
|
+
scope for the receipt — the exclusion is stated here
|
|
368
|
+
rather than silently applied.
|
|
369
|
+
- **Scoped claims get scoped verdicts.** "Never write
|
|
370
|
+
inside the project directory" forbids a named place,
|
|
371
|
+
not writing itself: it is contradicted only by a write
|
|
372
|
+
provably aimed at the package's own location, and
|
|
373
|
+
writes to runtime-computed paths leave it UNEVIDENCED,
|
|
374
|
+
because static evidence cannot place them.
|
|
375
|
+
- **Behaviour is extracted from scripts.** Prose
|
|
376
|
+
instructions in a SKILL.md that tell the *agent* to do
|
|
377
|
+
something are claims' territory, not behaviour evidence,
|
|
378
|
+
in v1.0.0. Full-line comments are ignored for behaviour
|
|
379
|
+
(a comment is a statement, not an action). Code-shaped
|
|
380
|
+
content that cannot be scanned (binaries, outward
|
|
381
|
+
symlinks, oversized scripts) downgrades affected claims
|
|
382
|
+
to UNEVIDENCED rather than letting them pass as
|
|
383
|
+
SUPPORTED.
|
|
384
|
+
- **Frontmatter is required.** The declared description
|
|
385
|
+
is the claim of record, so a SKILL.md with no `---`
|
|
386
|
+
block — or one the stated subset parser cannot read —
|
|
387
|
+
is a clean input error (exit 2), not a receipt.
|
|
388
|
+
- **Pattern tables are a snapshot.** New client
|
|
389
|
+
libraries, credential stores, and phrasings appear
|
|
390
|
+
constantly; the tables are dated by the release, not
|
|
391
|
+
treated as complete.
|
|
392
|
+
|
|
393
|
+
## Contributing
|
|
394
|
+
|
|
395
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). The evidence
|
|
396
|
+
discipline is the product: a claim is contradicted only
|
|
397
|
+
on hard evidence, and contributions are held to that.
|
|
398
|
+
Found a package skill-claims misjudges — a claim it
|
|
399
|
+
misses, a verdict the evidence doesn't support? Open an
|
|
400
|
+
issue with the package (or a minimal fixture); that is
|
|
401
|
+
exactly the feedback that improves the pattern library.
|
|
402
|
+
|
|
403
|
+
## Security
|
|
404
|
+
|
|
405
|
+
skill-claims is itself an audit tool, so its own posture
|
|
406
|
+
is simple: it has no network code, no subprocess code, no
|
|
407
|
+
dependencies, and it never executes what it scans. See
|
|
408
|
+
[SECURITY.md](SECURITY.md) for how to report a problem.
|
|
409
|
+
|
|
410
|
+
## License
|
|
411
|
+
|
|
412
|
+
MIT — see [LICENSE](LICENSE).
|
|
413
|
+
|
|
414
|
+
## Related
|
|
415
|
+
|
|
416
|
+
- [skill-vet](https://github.com/jasveerai88/skill-vet)
|
|
417
|
+
— the other half of the pre-install gate: *is it
|
|
418
|
+
dangerous?* Stealing, spying, hidden sending, proven
|
|
419
|
+
with file-and-line evidence.
|
|
420
|
+
- [done-claim-auditor](https://github.com/jasveerai88/done-claim-auditor)
|
|
421
|
+
— the same claim-vs-evidence logic pointed at agent
|
|
422
|
+
sessions: audits a coding agent's completion claims
|
|
423
|
+
against its own transcript.
|
|
424
|
+
- [permission-audit](https://github.com/jasveerai88/permission-audit)
|
|
425
|
+
— audits a Claude Code permission allowlist for
|
|
426
|
+
wildcard grants and dangerous modes before they hurt
|
|
427
|
+
you.
|
|
428
|
+
|
|
429
|
+
## Support
|
|
430
|
+
|
|
431
|
+
If skill-claims catches a skill lying to you, consider
|
|
432
|
+
[sponsoring](https://github.com/sponsors/jasveerai88).
|