memproof 0.1.0__tar.gz → 0.3.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.
- {memproof-0.1.0 → memproof-0.3.0}/PKG-INFO +27 -2
- {memproof-0.1.0 → memproof-0.3.0}/README.md +25 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/__init__.py +1 -1
- {memproof-0.1.0 → memproof-0.3.0}/memproof/cli.py +50 -0
- memproof-0.3.0/memproof/skills.py +529 -0
- memproof-0.3.0/memproof/skillsec.py +309 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof.egg-info/PKG-INFO +27 -2
- {memproof-0.1.0 → memproof-0.3.0}/memproof.egg-info/SOURCES.txt +5 -1
- {memproof-0.1.0 → memproof-0.3.0}/memproof.egg-info/requires.txt +1 -1
- {memproof-0.1.0 → memproof-0.3.0}/pyproject.toml +2 -2
- {memproof-0.1.0 → memproof-0.3.0}/tests/test_cli.py +1 -1
- memproof-0.3.0/tests/test_security.py +163 -0
- memproof-0.3.0/tests/test_skills.py +225 -0
- {memproof-0.1.0 → memproof-0.3.0}/LICENSE +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/__main__.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/checks/__init__.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/checks/freshness.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/checks/frontmatter.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/checks/links.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/checks/provenance.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/checks/structure.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/model.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/report.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof/vault.py +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof.egg-info/dependency_links.txt +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof.egg-info/entry_points.txt +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/memproof.egg-info/top_level.txt +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/setup.cfg +0 -0
- {memproof-0.1.0 → memproof-0.3.0}/tests/test_checks.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memproof
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Evidence-first health checks for Markdown knowledge vaults.
|
|
5
5
|
Author: memproof contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -19,24 +19,49 @@ License-File: LICENSE
|
|
|
19
19
|
Requires-Dist: pyyaml>=6.0
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
22
|
-
Requires-Dist: ruff
|
|
22
|
+
Requires-Dist: ruff==0.17.2; extra == "dev"
|
|
23
23
|
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
24
24
|
Dynamic: license-file
|
|
25
25
|
|
|
26
26
|
# memproof
|
|
27
27
|
|
|
28
|
+
[](https://pypi.org/project/memproof/)
|
|
29
|
+
[](https://github.com/hsys123/memproof/actions/workflows/test.yml)
|
|
30
|
+
[](LICENSE)
|
|
31
|
+
|
|
28
32
|
Evidence-first health checks for Markdown knowledge vaults.
|
|
29
33
|
|
|
30
34
|
`memproof` answers one question: **can you prove what your knowledge base claims?**
|
|
31
35
|
Every finding carries a `path:line`, the evidence behind it, and a concrete fix.
|
|
32
36
|
It is read-only, offline, and deterministic.
|
|
33
37
|
|
|
38
|
+
## Security rule layer
|
|
39
|
+
|
|
40
|
+
memproof skills also scans every skill for credential-shaped strings,
|
|
41
|
+
rule-override instructions, memory-file tampering, and fetch-piped-to-execute
|
|
42
|
+
combos. Evidence for matched secrets is masked in the report - the finding tells
|
|
43
|
+
you where and what shape, never the value itself. Use --no-security to run
|
|
44
|
+
spec/registry checks only.
|
|
45
|
+
|
|
46
|
+
## Check Agent Skills (agentskills.io)
|
|
47
|
+
|
|
48
|
+
Point `memproof skills` at a directory of `skills/<name>/SKILL.md` to validate the agentskills.io
|
|
49
|
+
contract: kebab-case names that match their directory, description limits,
|
|
50
|
+
optional-field types and unknown keys. Add `--registry skills.json` to diff the disk against a declared skill registry in both directions.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
memproof skills ./skills --registry config/skills.json --fail-on high
|
|
54
|
+
```
|
|
55
|
+
|
|
34
56
|
## Install
|
|
35
57
|
|
|
36
58
|
```bash
|
|
37
59
|
uv tool install memproof
|
|
38
60
|
# or
|
|
39
61
|
pip install memproof
|
|
62
|
+
|
|
63
|
+
# before the PyPI release, install straight from GitHub:
|
|
64
|
+
uv tool install git+https://github.com/hsys123/memproof
|
|
40
65
|
```
|
|
41
66
|
|
|
42
67
|
## Use
|
|
@@ -1,17 +1,42 @@
|
|
|
1
1
|
# memproof
|
|
2
2
|
|
|
3
|
+
[](https://pypi.org/project/memproof/)
|
|
4
|
+
[](https://github.com/hsys123/memproof/actions/workflows/test.yml)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
3
7
|
Evidence-first health checks for Markdown knowledge vaults.
|
|
4
8
|
|
|
5
9
|
`memproof` answers one question: **can you prove what your knowledge base claims?**
|
|
6
10
|
Every finding carries a `path:line`, the evidence behind it, and a concrete fix.
|
|
7
11
|
It is read-only, offline, and deterministic.
|
|
8
12
|
|
|
13
|
+
## Security rule layer
|
|
14
|
+
|
|
15
|
+
memproof skills also scans every skill for credential-shaped strings,
|
|
16
|
+
rule-override instructions, memory-file tampering, and fetch-piped-to-execute
|
|
17
|
+
combos. Evidence for matched secrets is masked in the report - the finding tells
|
|
18
|
+
you where and what shape, never the value itself. Use --no-security to run
|
|
19
|
+
spec/registry checks only.
|
|
20
|
+
|
|
21
|
+
## Check Agent Skills (agentskills.io)
|
|
22
|
+
|
|
23
|
+
Point `memproof skills` at a directory of `skills/<name>/SKILL.md` to validate the agentskills.io
|
|
24
|
+
contract: kebab-case names that match their directory, description limits,
|
|
25
|
+
optional-field types and unknown keys. Add `--registry skills.json` to diff the disk against a declared skill registry in both directions.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
memproof skills ./skills --registry config/skills.json --fail-on high
|
|
29
|
+
```
|
|
30
|
+
|
|
9
31
|
## Install
|
|
10
32
|
|
|
11
33
|
```bash
|
|
12
34
|
uv tool install memproof
|
|
13
35
|
# or
|
|
14
36
|
pip install memproof
|
|
37
|
+
|
|
38
|
+
# before the PyPI release, install straight from GitHub:
|
|
39
|
+
uv tool install git+https://github.com/hsys123/memproof
|
|
15
40
|
```
|
|
16
41
|
|
|
17
42
|
## Use
|
|
@@ -10,6 +10,15 @@ from .checks import ALL_CHECKS
|
|
|
10
10
|
from .checks import links as links_check
|
|
11
11
|
from .model import Finding
|
|
12
12
|
from .report import render_json, render_markdown, write_report
|
|
13
|
+
from .skills import (
|
|
14
|
+
render_json as render_skills_json,
|
|
15
|
+
)
|
|
16
|
+
from .skills import (
|
|
17
|
+
render_markdown as render_skills_markdown,
|
|
18
|
+
)
|
|
19
|
+
from .skills import (
|
|
20
|
+
scan_skills,
|
|
21
|
+
)
|
|
13
22
|
from .vault import load_vault
|
|
14
23
|
|
|
15
24
|
FAIL_RANK = {"high": 0, "medium": 1, "low": 2}
|
|
@@ -56,6 +65,20 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
56
65
|
default=None,
|
|
57
66
|
help="reference date for freshness checks (YYYY-MM-DD)",
|
|
58
67
|
)
|
|
68
|
+
skills = subparsers.add_parser("skills", help="check Agent Skills (SKILL.md) spec conformance")
|
|
69
|
+
skills.add_argument("path", type=Path, help="directory containing skills/<name>/SKILL.md")
|
|
70
|
+
skills.add_argument("--registry", type=Path, help="JSON file listing the expected skill ids")
|
|
71
|
+
skills.add_argument(
|
|
72
|
+
"--no-security", action="store_true", help="skip the secret/injection/exec rule layer"
|
|
73
|
+
)
|
|
74
|
+
skills.add_argument("--format", choices=("markdown", "json"), default="markdown")
|
|
75
|
+
skills.add_argument("--output", type=Path, help="write the report to this file")
|
|
76
|
+
skills.add_argument(
|
|
77
|
+
"--fail-on",
|
|
78
|
+
choices=("none", "low", "medium", "high"),
|
|
79
|
+
default="none",
|
|
80
|
+
help="exit 1 when a finding at or above this severity exists",
|
|
81
|
+
)
|
|
59
82
|
subparsers.add_parser("version", help="print the version")
|
|
60
83
|
return parser
|
|
61
84
|
|
|
@@ -80,6 +103,33 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
80
103
|
print(__version__)
|
|
81
104
|
return 0
|
|
82
105
|
|
|
106
|
+
if args.command == "skills":
|
|
107
|
+
skills_root = args.path
|
|
108
|
+
if not skills_root.is_dir():
|
|
109
|
+
print(f"memproof: not a directory: {skills_root}", file=sys.stderr)
|
|
110
|
+
return 2
|
|
111
|
+
skill_findings, scan = scan_skills(
|
|
112
|
+
skills_root, args.registry, security=not args.no_security
|
|
113
|
+
)
|
|
114
|
+
content = (
|
|
115
|
+
render_skills_markdown(scan, skill_findings)
|
|
116
|
+
if args.format == "markdown"
|
|
117
|
+
else render_skills_json(scan, skill_findings)
|
|
118
|
+
)
|
|
119
|
+
if args.output:
|
|
120
|
+
write_report(args.output, content)
|
|
121
|
+
print(f"wrote {args.output}")
|
|
122
|
+
else:
|
|
123
|
+
sys.stdout.write(content)
|
|
124
|
+
if args.fail_on == "none":
|
|
125
|
+
return 0
|
|
126
|
+
threshold = FAIL_RANK[args.fail_on]
|
|
127
|
+
worst = min(
|
|
128
|
+
(FAIL_RANK.get(finding.severity, 99) for finding in skill_findings),
|
|
129
|
+
default=99,
|
|
130
|
+
)
|
|
131
|
+
return 1 if worst <= threshold else 0
|
|
132
|
+
|
|
83
133
|
root = args.path
|
|
84
134
|
if not root.is_dir():
|
|
85
135
|
print(f"memproof: not a directory: {root}", file=sys.stderr)
|