pkgwhy 1.0.0__tar.gz → 1.6.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.
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/CHANGELOG.md +61 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/PKG-INFO +170 -8
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/README.md +169 -7
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/SECURITY.md +17 -3
- pkgwhy-1.6.0/docs/ci-templates.md +77 -0
- pkgwhy-1.6.0/docs/commercial-agent-platform.md +135 -0
- pkgwhy-1.6.0/docs/json-schema-compatibility.md +67 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/release-checklist.md +9 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/versioning-policy.md +7 -1
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/pyproject.toml +1 -1
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/__init__.py +1 -1
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/cli.py +678 -1
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/core/constants.py +3 -0
- pkgwhy-1.6.0/src/pkgwhy/core/decision_contract.py +165 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/core/models.py +417 -1
- pkgwhy-1.6.0/src/pkgwhy/pip_gate.py +382 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/policy/tool_execution.py +6 -1
- pkgwhy-1.6.0/src/pkgwhy/precheck.py +1217 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/tools.py +59 -2
- pkgwhy-1.6.0/src/pkgwhy/registry/trust.py +30 -0
- pkgwhy-1.6.0/src/pkgwhy/registry/validate.py +421 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/reports/audit.py +45 -0
- pkgwhy-1.6.0/tests/fixtures/precheck/requirements.txt +2 -0
- pkgwhy-1.6.0/tests/fixtures/private-tools/hello-tool/hello.py +6 -0
- pkgwhy-1.6.0/tests/fixtures/private-tools/hello-tool/pkgwhy.toml +18 -0
- pkgwhy-1.6.0/tests/test_agent_check.py +86 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_agent_policy.py +11 -0
- pkgwhy-1.6.0/tests/test_ci_templates.py +34 -0
- pkgwhy-1.6.0/tests/test_commercial_design_docs.py +27 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_json_snapshots.py +132 -1
- pkgwhy-1.6.0/tests/test_pip_gate.py +390 -0
- pkgwhy-1.6.0/tests/test_precheck.py +622 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_reports.py +8 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_runner.py +14 -0
- pkgwhy-1.6.0/tests/test_tool_judgement.py +295 -0
- pkgwhy-1.6.0/tests/test_tool_validate.py +191 -0
- pkgwhy-1.0.0/docs/json-schema-compatibility.md +0 -37
- pkgwhy-1.0.0/tests/test_tool_judgement.py +0 -110
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/.gitignore +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/CONTRIBUTING.md +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/LICENSE +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/dynamic-sandbox.md +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/production-readiness.md +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/release-candidate-surface.md +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/static-rule-corpus.md +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/threat-model.md +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/scripts/check_public_traces.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/__main__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/agent/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/agent/judge.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/core/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dependencies/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dependencies/graph.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dependencies/reason.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dynamic/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dynamic/analysis.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/explanations/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/explanations/explain.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/explanations/local_db.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/imports/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/imports/scanner.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/files.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/python_static.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/size.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/text_patterns.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/manifests/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/manifests/lockfiles.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/manifests/pyproject.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/manifests/requirements.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/metadata/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/metadata/installed.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/metadata/pypi.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/policy/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/policy/agent_policy.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/policy/audit_log.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/provenance/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/provenance/installed.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/local.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/manifest.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/publish.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/run.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/reports/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/risk/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/risk/rules.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/risk/scoring.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/typosquat/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/typosquat/detector.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/typosquat/popular_packages.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/vulnerabilities/__init__.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/vulnerabilities/matching.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/vulnerabilities/osv.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/extension.so +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/helper.exe +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/javascript_false_positive.js +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/javascript_signals.min.js +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/module.wasm +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/postinstall +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/pyproject.toml +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/setup.cfg +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/setup.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/deserialisation.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/dynamic_execution.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/encoded_payloads.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/import_trap.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/process_environment_package_manager.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/url_credential_patterns.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_audit_log.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_cli.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_dependency_graph.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_dynamic.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_explanations.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_file_static_analysis.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_import_scanner.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_manifests.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_provenance.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_publish.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_python_static.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_registry.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_risk.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_risk_rules.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_size.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_static_rule_corpus.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_tool_manifest.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_tool_policy.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_typosquat.py +0 -0
- {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_vulnerabilities.py +0 -0
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.0 - 2026-07-01
|
|
4
|
+
|
|
5
|
+
- Improve agent JSON consistency across decision commands with shared top-level fields for command, target, recommended next action, exit code, exit-code meaning, evidence summary, source freshness, and policy where available.
|
|
6
|
+
- Add `pkgwhy.error.v1` JSON error objects for handled `--json` user/configuration errors in agent-facing gates.
|
|
7
|
+
- Improve pyproject precheck routing for explicitly passed TOML files that contain a `[project]` table.
|
|
8
|
+
- Add batch precheck summaries: `blocking_targets`, `review_targets`, `allowed_targets`, and `aggregate_recommendation`.
|
|
9
|
+
- Add JSON output for registry trust-state commands: `trust`, `review`, `quarantine`, `block`, and `blocked`.
|
|
10
|
+
- Make local registry `blocked` and `quarantined` trust states produce blocking `pkgwhy tool judge` decisions without weakening hash, signature, manifest, or static-analysis cautions.
|
|
11
|
+
- Add non-executing `pkgwhy tool validate <path> --json` for local private-tool source validation.
|
|
12
|
+
- Add static capability analysis for verified local tool bundles during `pkgwhy tool judge`.
|
|
13
|
+
- Add `pkgwhy agent check <target> --json` as a safe dispatcher for package specs, requirements files, pyproject-style TOML files, and local tool folders/scripts.
|
|
14
|
+
- Document the public agent integration contract, exit-code meanings, batch summary interpretation, pip gate safety model, and registry trust-state effects.
|
|
15
|
+
- No cloud services, billing, hosted review, secrets, publishing, or OS-level sandboxing claims were added.
|
|
16
|
+
|
|
17
|
+
## 1.5.0 - 2026-06-30
|
|
18
|
+
|
|
19
|
+
- Add `docs/commercial-agent-platform.md` to describe the future commercial and agent platform direction without implementing cloud services, billing, hosted review, API keys, or secrets.
|
|
20
|
+
- Document the product habit around `pkgwhy precheck`, `pkgwhy pip install`, and `pkgwhy agent precheck`.
|
|
21
|
+
- Document future tiers for the free local CLI, Pro local policy packs, team review dashboard, hosted package review cache, shared organization policy, and agent install gateway.
|
|
22
|
+
- Add explicit hosted-review boundaries so the current local CLI does not imply active cloud review or definitive malware detection.
|
|
23
|
+
- Add tests that keep the commercial platform design doc future-only and boundary-aware.
|
|
24
|
+
- Harden precheck and pip-gate follow-up review items: direct-reference handling, hash-locked requirements parsing, PyPI specifier release selection, Python 3.11-compatible tar extraction, private pip decision log paths/permissions, and CI pyproject gate coverage.
|
|
25
|
+
- Harden second-pass review items: sanitized artifact URLs, stable-release preference for PyPI specifiers, safer keep-artifact failure handling, advisory-mode CI audit behavior, quarantine CLI coverage, and stricter pip requirements snapshot boundaries.
|
|
26
|
+
|
|
27
|
+
## 1.4.0 - 2026-06-30
|
|
28
|
+
|
|
29
|
+
- Add local registry trust states: `trusted`, `reviewed`, `quarantined`, `blocked`, and `unknown`.
|
|
30
|
+
- Add trust-state storage to registry index entries and include trust state in tool judgement JSON and human output.
|
|
31
|
+
- Add `pkgwhy registry trust <tool>`, `pkgwhy registry review <tool>`, `pkgwhy registry quarantine <tool>`, `pkgwhy registry block <tool>`, and `pkgwhy registry blocked`.
|
|
32
|
+
- Enforce registry trust state in the local runner policy: `quarantined` and `blocked` tools are refused before execution.
|
|
33
|
+
- Keep newly published local tools at `unknown` trust until a human marks them.
|
|
34
|
+
- Keep tool lock/verify and registry export/import deferred rather than inventing incomplete trust guarantees.
|
|
35
|
+
|
|
36
|
+
## 1.3.0 - 2026-06-30
|
|
37
|
+
|
|
38
|
+
- Add a reusable GitHub Actions package-gate template at `examples/github-actions/pkgwhy-package-gate.yml`.
|
|
39
|
+
- Document CI advisory, strict, and agent modes in `docs/ci-templates.md`.
|
|
40
|
+
- The CI template installs `pkgwhy`, runs requirements precheck, emits JSON and Markdown audit reports, optionally runs agent precheck, uploads reports, and fails only in strict or agent mode.
|
|
41
|
+
- Keep CI package-gate usage local and secret-free by default; no cloud service, hosted review, billing, or credentials are required.
|
|
42
|
+
- Add static validation tests for the CI template and documentation boundaries.
|
|
43
|
+
|
|
44
|
+
## 1.2.0 - 2026-06-30
|
|
45
|
+
|
|
46
|
+
- Add `pkgwhy pip install <package>` as a local pip install gate over `pkgwhy precheck`.
|
|
47
|
+
- Add `pkgwhy pip install -r requirements.txt` for requirements-file gate checks before pip is invoked.
|
|
48
|
+
- Add schema-versioned `pkgwhy.pip_install_gate.v1` JSON with precheck decision, gate exit code, pip invocation status, override status, warnings, reasons, and embedded precheck output.
|
|
49
|
+
- Add `--policy strict`, `--dry-run`, `--override-review`, `--override-block`, and `--override-reason` for explicit install-gate workflows.
|
|
50
|
+
- Add best-effort compact local pip gate decision logs that omit full precheck evidence.
|
|
51
|
+
- Keep tests deterministic by using fake pip runners and dry-run paths; tests do not install arbitrary public packages.
|
|
52
|
+
- Keep the pip gate conservative: pip is called only after precheck allows it or an explicit override is used, and unavailable or incomplete precheck evidence exits without invoking pip.
|
|
53
|
+
|
|
54
|
+
## 1.1.0 - 2026-06-30
|
|
55
|
+
|
|
56
|
+
- Add top-level `pkgwhy precheck` as a local pre-install package gate for humans, CI, and agents.
|
|
57
|
+
- Add schema-versioned `pkgwhy.precheck.v1` JSON for single package requirements, including decision, risk, confidence, evidence summaries, vulnerability/provenance/typosquat/static summaries, and embedded package judgement.
|
|
58
|
+
- Add schema-versioned `pkgwhy.precheck_batch.v1` JSON for `pkgwhy precheck -r requirements.txt` and `pkgwhy precheck pyproject.toml`.
|
|
59
|
+
- Add explicit `--download-artifacts` support that queries PyPI, downloads one wheel or source artifact to a temporary review directory, verifies SHA-256 when PyPI metadata provides it, extracts safely, statically inspects files, and deletes temporary files unless `--keep-artifacts` is set.
|
|
60
|
+
- Add optional `--pypi`, `--osv`, and local `--vulnerability-file` enrichment boundaries to precheck without enabling network by default.
|
|
61
|
+
- Add `--enforce-exit-code` for gate usage while keeping default JSON and human precheck commands easy to inspect interactively.
|
|
62
|
+
- Keep precheck static-first: it does not install, import, or execute inspected package code.
|
|
63
|
+
|
|
3
64
|
## 1.0.0 - 2026-06-30
|
|
4
65
|
|
|
5
66
|
- Promote the `1.0.0rc1` release-candidate surface to the final 1.0.0 tracked codebase after local release-prep review.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pkgwhy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.0
|
|
4
4
|
Summary: Offline-first Python package intelligence and supply-chain security decision support.
|
|
5
5
|
Project-URL: Homepage, https://github.com/devlukeg/pkgwhy
|
|
6
6
|
Project-URL: Repository, https://github.com/devlukeg/pkgwhy
|
|
@@ -36,17 +36,19 @@ Description-Content-Type: text/markdown
|
|
|
36
36
|
|
|
37
37
|
# pkgwhy
|
|
38
38
|
|
|
39
|
+
pip install pkgwhy
|
|
40
|
+
|
|
39
41
|
Know why a package exists before you or your agent trusts it.
|
|
40
42
|
|
|
41
43
|
`pkgwhy` is an offline-first Python package intelligence, agent policy, and local private-tool CLI. It explains installed packages, inspects local package files without importing them, reports conservative vulnerability, provenance, and static security signals, produces agent-readable JSON judgements, and can publish and run local private Python tools from a local registry.
|
|
42
44
|
|
|
43
45
|
## Status
|
|
44
46
|
|
|
45
|
-
`pkgwhy` 1.
|
|
47
|
+
`pkgwhy` 1.6.0 is a Python supply-chain security decision-support tool and local pip/CI install gate for developers and AI agents. It is useful for local package inspection, conservative static package review, agent-readable JSON, vulnerability and provenance foundations, policy checks, artifact precheck, guarded pip installs, CI package-gate templates, local registry trust states, local tool validation, agent check dispatching, and the local private-registry and runner MVP.
|
|
46
48
|
|
|
47
49
|
It is not a production security scanner, not malware-detection certainty, and not a full sandbox. Results are evidence and signals for review, not proof that a package is safe or malicious.
|
|
48
50
|
|
|
49
|
-
Current packaged version: `1.
|
|
51
|
+
Current packaged version: `1.6.0`.
|
|
50
52
|
|
|
51
53
|
## What Works Now
|
|
52
54
|
|
|
@@ -58,8 +60,16 @@ pkgwhy explain typer
|
|
|
58
60
|
pkgwhy why typer
|
|
59
61
|
pkgwhy inspect typer
|
|
60
62
|
pkgwhy judge typer --json
|
|
63
|
+
pkgwhy precheck typer --json
|
|
64
|
+
pkgwhy precheck "typer==0.12.5" --json
|
|
65
|
+
pkgwhy precheck -r requirements.txt --json
|
|
66
|
+
pkgwhy precheck pyproject.toml --json
|
|
67
|
+
pkgwhy precheck annotated-doc==0.0.4 --download-artifacts --json
|
|
68
|
+
pkgwhy pip install typer --dry-run
|
|
69
|
+
pkgwhy pip install -r requirements.txt --dry-run
|
|
61
70
|
pkgwhy agent policy --json
|
|
62
71
|
pkgwhy agent precheck typer --json
|
|
72
|
+
pkgwhy agent check typer --json
|
|
63
73
|
pkgwhy risk typer
|
|
64
74
|
pkgwhy audit --limit 5 --json
|
|
65
75
|
pkgwhy audit --limit 5 --json --vulnerability-file ./osv-fixture.json
|
|
@@ -87,6 +97,15 @@ Implemented capabilities include:
|
|
|
87
97
|
- Metadata-derived provenance/source-trust fields from installed metadata and optional PyPI JSON, with unsupported attestation and trusted-publishing checks marked as unknown or not implemented.
|
|
88
98
|
- Conservative risk level, decision, warning, recommendation, evidence, confidence, risk model version, and rule-ID output.
|
|
89
99
|
- Human `inspect`, `risk`, and `judge` reports that show compact rule-evidence summaries, while JSON reports include structured rule details.
|
|
100
|
+
- Pre-install package precheck for package requirements, requirements files, and `pyproject.toml` dependencies.
|
|
101
|
+
- Explicit artifact-download precheck that downloads a PyPI wheel or source artifact to a temporary review directory, verifies SHA-256 when available, extracts safely, statically inspects files, and deletes temporary files by default.
|
|
102
|
+
- Optional gate exit codes via `pkgwhy precheck --enforce-exit-code`.
|
|
103
|
+
- Guarded pip install flow via `pkgwhy pip install`, with precheck first, stable exit codes, explicit overrides, and compact local decision logs.
|
|
104
|
+
- Reusable GitHub Actions package-gate template with advisory, strict, and agent modes.
|
|
105
|
+
- Local registry trust states for private tools: `trusted`, `reviewed`, `quarantined`, `blocked`, and `unknown`.
|
|
106
|
+
- Local private-tool source validation with `pkgwhy tool validate <path> --json`.
|
|
107
|
+
- Agent check dispatching with `pkgwhy agent check <target> --json` for package specs, dependency files, pyproject-style TOML, and local tool folders/scripts.
|
|
108
|
+
- Commercial and agent platform architecture documentation for future local policy packs, team review, hosted evidence cache, shared organization policy, and agent install gateway.
|
|
90
109
|
- Stable JSON output for agent workflows.
|
|
91
110
|
- Schema-versioned agent policy and package precheck output.
|
|
92
111
|
- Conservative non-interactive agent defaults that block unknown or high-risk package use until a human reviews the evidence.
|
|
@@ -100,8 +119,12 @@ pkgwhy registry list
|
|
|
100
119
|
pkgwhy registry add local-copy ~/.pkgwhy/registry
|
|
101
120
|
pkgwhy registry use local
|
|
102
121
|
pkgwhy publish ./my_tool.py
|
|
122
|
+
pkgwhy registry trust local/my_tool
|
|
123
|
+
pkgwhy registry quarantine local/my_tool
|
|
124
|
+
pkgwhy registry blocked
|
|
103
125
|
pkgwhy tool inspect local/my_tool
|
|
104
126
|
pkgwhy tool judge local/my_tool --json
|
|
127
|
+
pkgwhy tool validate ./my-tool-folder --json
|
|
105
128
|
pkgwhy run local/my_tool
|
|
106
129
|
pkgwhy run local/my_tool --non-interactive
|
|
107
130
|
```
|
|
@@ -121,6 +144,7 @@ Current runner policy is intentionally conservative:
|
|
|
121
144
|
- Corrupt registry indexes fail closed for publish and tool-judgement paths.
|
|
122
145
|
- Symlinks are not bundled, and stored registry paths must remain inside the registry root.
|
|
123
146
|
- Bundle hash mismatch or a missing bundle blocks execution.
|
|
147
|
+
- Quarantined or blocked registry trust states block execution.
|
|
124
148
|
- `sandbox_only` and `block` tool judgements block execution.
|
|
125
149
|
- Non-interactive execution is blocked unless both the judgement and manifest agent policy allow it.
|
|
126
150
|
- Tools with declared dependencies are not run yet because dependency installation is not implemented.
|
|
@@ -134,11 +158,12 @@ These are roadmap items, not current features:
|
|
|
134
158
|
|
|
135
159
|
- Complete vulnerability database coverage, transitive vulnerability analysis, or guaranteed advisory freshness.
|
|
136
160
|
- Default online vulnerability lookup. Network access is only used when explicitly requested.
|
|
137
|
-
-
|
|
161
|
+
- Persistent cached PyPI/source lookup beyond the current OSV response cache.
|
|
138
162
|
- Cloud/private remote registry backends.
|
|
139
163
|
- `pull`, mirroring, and remote synchronization.
|
|
140
164
|
- Tool dependency installation in the runner.
|
|
141
165
|
- Tool bundle signing and signature verification.
|
|
166
|
+
- Tool lock/verify commands and registry export/import.
|
|
142
167
|
- Dynamic sandbox analysis for arbitrary packages.
|
|
143
168
|
- Tool-specific `pkgwhy agent judge` expansion beyond the current package precheck path.
|
|
144
169
|
- `pkgwhy agent explain-decision <review-id>`.
|
|
@@ -197,15 +222,70 @@ Emit machine-readable judgement JSON:
|
|
|
197
222
|
pkgwhy judge typer --json
|
|
198
223
|
```
|
|
199
224
|
|
|
225
|
+
Before installing a package, run a local precheck:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
pkgwhy precheck typer --json
|
|
229
|
+
pkgwhy precheck "typer==0.12.5" --json
|
|
230
|
+
pkgwhy precheck -r requirements.txt --json
|
|
231
|
+
pkgwhy precheck pyproject.toml --json
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
By default, `pkgwhy precheck` uses local installed metadata when available and does not use the network. Add `--pypi` or `--osv` only when you want explicit online enrichment. Add `--download-artifacts` to query PyPI, download one wheel or source artifact, verify its SHA-256 when PyPI metadata provides it, extract it to a temporary review directory, inspect it statically, and delete the temporary files. The command does not install, import, or execute inspected package code.
|
|
235
|
+
|
|
236
|
+
For CI or install-gate usage, add `--enforce-exit-code`:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
pkgwhy precheck typer --json --enforce-exit-code
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Exit codes are:
|
|
243
|
+
|
|
244
|
+
- `0`: allow.
|
|
245
|
+
- `1`: allow with caution or manual review.
|
|
246
|
+
- `2`: block or sandbox-only.
|
|
247
|
+
- `4`: requested online/artifact lookup was unavailable or failed.
|
|
248
|
+
|
|
249
|
+
To gate an install, use `pkgwhy pip install` instead of raw `pip install`:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
pkgwhy pip install typer
|
|
253
|
+
pkgwhy pip install typer --policy strict
|
|
254
|
+
pkgwhy pip install -r requirements.txt
|
|
255
|
+
pkgwhy pip install typer --dry-run --json
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The pip gate always runs precheck first. It invokes pip only when the precheck policy allows the install, or when a human uses an explicit override flag. Review/caution results exit `1`, block/sandbox-only results exit `2`, tool/config errors exit `3`, and unavailable or incomplete requested evidence exits `4`. `--dry-run` evaluates the gate and writes the local decision log without invoking pip.
|
|
259
|
+
|
|
260
|
+
Overrides are explicit:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
pkgwhy pip install typer --override-review --override-reason "reviewed local evidence"
|
|
264
|
+
pkgwhy pip install suspicious-name --override-block --override-reason "temporary isolated test"
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Agents and automated workflows should use `pkgwhy pip install` when dependency policy is required, not raw `pip install`. The command is still decision support: it does not prove a package is safe and it does not sandbox pip or installed package code.
|
|
268
|
+
|
|
269
|
+
For CI package gates, start from the reusable GitHub Actions template:
|
|
270
|
+
|
|
271
|
+
```text
|
|
272
|
+
examples/github-actions/pkgwhy-package-gate.yml
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
See [CI Templates](docs/ci-templates.md) for advisory, strict, and agent-mode usage. The template does not require secrets or a hosted `pkgwhy` service.
|
|
276
|
+
|
|
200
277
|
Inspect the default agent policy and run a conservative agent precheck:
|
|
201
278
|
|
|
202
279
|
```bash
|
|
203
280
|
pkgwhy agent policy --json
|
|
204
281
|
pkgwhy agent precheck typer --json
|
|
205
282
|
pkgwhy agent judge typer --json
|
|
283
|
+
pkgwhy agent check typer --json
|
|
284
|
+
pkgwhy agent check requirements.txt --json
|
|
285
|
+
pkgwhy agent check ./my-tool-folder --json
|
|
206
286
|
```
|
|
207
287
|
|
|
208
|
-
`pkgwhy agent precheck` applies policy to the package judgement. In the default non-interactive mode, unknown and high-risk package decisions are blocked until a human reviews the judgement evidence.
|
|
288
|
+
`pkgwhy agent precheck` applies policy to the package judgement. In the default non-interactive mode, unknown and high-risk package decisions are blocked until a human reviews the judgement evidence. `pkgwhy agent check` dispatches the target to the safest matching local check and returns one normalized decision envelope. These commands do not install, import, or execute inspected package code. Agent precheck writes a compact local decision log under the user config directory when that directory is writable.
|
|
209
289
|
|
|
210
290
|
Run a conservative risk report:
|
|
211
291
|
|
|
@@ -314,10 +394,36 @@ Apply the stricter non-interactive runner policy:
|
|
|
314
394
|
pkgwhy run local/my_tool --non-interactive
|
|
315
395
|
```
|
|
316
396
|
|
|
317
|
-
## Agent
|
|
397
|
+
## Agent Integration Contract
|
|
318
398
|
|
|
319
399
|
Compatibility policy: [docs/json-schema-compatibility.md](docs/json-schema-compatibility.md).
|
|
320
400
|
|
|
401
|
+
Decision-oriented JSON commands expose a shared top-level contract where the field applies: `schema_version`, `command`, `target`, `target_type`, `decision`, `risk_level`, `confidence`, `recommended_next_action`, `exit_code`, `exit_code_meaning`, `warnings`, `evidence`, `evidence_summary`, `source_freshness`, `policy`, and `errors` for JSON error objects. Existing command-specific fields remain available.
|
|
402
|
+
|
|
403
|
+
Exit code meanings are stable for agent consumers:
|
|
404
|
+
|
|
405
|
+
- `0`: allowed or completed successfully.
|
|
406
|
+
- `1`: review or caution required before proceeding.
|
|
407
|
+
- `2`: blocked by policy or risk decision.
|
|
408
|
+
- `3`: tool, configuration, or user input error.
|
|
409
|
+
- `4`: external data unavailable or evidence incomplete.
|
|
410
|
+
|
|
411
|
+
Decision meanings:
|
|
412
|
+
|
|
413
|
+
- `allow`: proceed under normal review practices.
|
|
414
|
+
- `allow_with_caution`: proceed only after reviewing warnings and evidence.
|
|
415
|
+
- `review_manually`: ask a human to review before proceeding.
|
|
416
|
+
- `sandbox_only`: use only inside a real sandbox; a Python virtual environment is not a full OS sandbox.
|
|
417
|
+
- `block`: do not install, import, or run unless a human approves a policy exception.
|
|
418
|
+
|
|
419
|
+
When `--json` is set and a handled user/configuration error occurs, commands emit `pkgwhy.error.v1` with `error_type`, `message`, `exit_code`, `exit_code_meaning`, `suggested_fix`, `command`, `target`, and `target_type` where available.
|
|
420
|
+
|
|
421
|
+
Batch precheck JSON includes top-level `blocking_targets`, `review_targets`, `allowed_targets`, and `aggregate_recommendation` so automation can see the package-level reason without walking every nested result. Full evidence remains available, and `evidence_summary` gives compact counts, top evidence, top warnings, and top rule IDs for agents that need a smaller decision surface.
|
|
422
|
+
|
|
423
|
+
The pip gate safety model is unchanged: `pkgwhy pip install` runs precheck before pip and does not invoke pip in dry-run mode, for blocked decisions, or when required evidence is unavailable. It does not sandbox pip or installed package code.
|
|
424
|
+
|
|
425
|
+
Local registry trust state now affects tool judgement. `blocked` and `quarantined` tools return blocking `tool judge` decisions. `trusted` and `reviewed` are local human labels; they do not override hash mismatch, signature status, manifest approval requirements, or static capability warnings.
|
|
426
|
+
|
|
321
427
|
Package judgement schema version: `pkgwhy.package_judgement.v1`.
|
|
322
428
|
|
|
323
429
|
Field shape for `pkgwhy judge <package> --json`:
|
|
@@ -457,13 +563,68 @@ Field shape for `pkgwhy tool judge <tool> --json`:
|
|
|
457
563
|
"hash_status": "verified",
|
|
458
564
|
"signature_status": "not_implemented",
|
|
459
565
|
"warnings": [
|
|
460
|
-
"Signature verification is not implemented yet."
|
|
461
|
-
"Static capability detection for tool bundles is not implemented yet."
|
|
566
|
+
"Signature verification is not implemented yet."
|
|
462
567
|
],
|
|
463
568
|
"recommendation": "Review declared permissions and manifest metadata before running this private tool."
|
|
464
569
|
}
|
|
465
570
|
```
|
|
466
571
|
|
|
572
|
+
Tool validation schema version: `pkgwhy.tool_validation.v1`.
|
|
573
|
+
|
|
574
|
+
Field shape for `pkgwhy tool validate ./folder --json`:
|
|
575
|
+
|
|
576
|
+
```json
|
|
577
|
+
{
|
|
578
|
+
"schema_version": "pkgwhy.tool_validation.v1",
|
|
579
|
+
"command": "pkgwhy tool validate",
|
|
580
|
+
"target": "./folder",
|
|
581
|
+
"target_type": "tool_folder",
|
|
582
|
+
"valid": true,
|
|
583
|
+
"decision": "allow",
|
|
584
|
+
"risk_level": "low",
|
|
585
|
+
"confidence": "high",
|
|
586
|
+
"entrypoint": "main.py",
|
|
587
|
+
"declared_permissions": [],
|
|
588
|
+
"detected_capabilities": [],
|
|
589
|
+
"issues": [],
|
|
590
|
+
"errors": [],
|
|
591
|
+
"warnings": [],
|
|
592
|
+
"policy": {
|
|
593
|
+
"executes_tool_code": false,
|
|
594
|
+
"writes_to_registry": false,
|
|
595
|
+
"symlinks_supported": false
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
Tool validation reads local files and manifests, checks path boundaries and entrypoints, and statically analyzes files. It does not publish to a registry and does not execute tool code.
|
|
601
|
+
|
|
602
|
+
Agent check schema version: `pkgwhy.agent_check.v1`.
|
|
603
|
+
|
|
604
|
+
Field shape for `pkgwhy agent check <target> --json`:
|
|
605
|
+
|
|
606
|
+
```json
|
|
607
|
+
{
|
|
608
|
+
"schema_version": "pkgwhy.agent_check.v1",
|
|
609
|
+
"command": "pkgwhy agent check",
|
|
610
|
+
"target": "requirements.txt",
|
|
611
|
+
"target_type": "requirements",
|
|
612
|
+
"decision": "block",
|
|
613
|
+
"risk_level": "high",
|
|
614
|
+
"confidence": "medium",
|
|
615
|
+
"recommended_next_action": "conservative next action text",
|
|
616
|
+
"exit_code": 2,
|
|
617
|
+
"exit_code_meaning": "blocked by policy or risk decision",
|
|
618
|
+
"evidence_summary": {},
|
|
619
|
+
"result_schema_version": "pkgwhy.precheck_batch.v1",
|
|
620
|
+
"result": {
|
|
621
|
+
"schema_version": "pkgwhy.precheck_batch.v1"
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
`pkgwhy agent check` currently dispatches package specs to package precheck, requirements files and pyproject-style TOML files to batch precheck, and local tool folders/scripts to tool validation.
|
|
627
|
+
|
|
467
628
|
Supported package and tool decision values are:
|
|
468
629
|
|
|
469
630
|
- `allow`
|
|
@@ -669,6 +830,7 @@ Release and process references:
|
|
|
669
830
|
- [1.0.0 Feature Surface](docs/release-candidate-surface.md)
|
|
670
831
|
- [Threat Model](docs/threat-model.md)
|
|
671
832
|
- [Production Readiness Blockers](docs/production-readiness.md)
|
|
833
|
+
- [Commercial And Agent Platform Direction](docs/commercial-agent-platform.md)
|
|
672
834
|
|
|
673
835
|
## Roadmap
|
|
674
836
|
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
# pkgwhy
|
|
2
2
|
|
|
3
|
+
pip install pkgwhy
|
|
4
|
+
|
|
3
5
|
Know why a package exists before you or your agent trusts it.
|
|
4
6
|
|
|
5
7
|
`pkgwhy` is an offline-first Python package intelligence, agent policy, and local private-tool CLI. It explains installed packages, inspects local package files without importing them, reports conservative vulnerability, provenance, and static security signals, produces agent-readable JSON judgements, and can publish and run local private Python tools from a local registry.
|
|
6
8
|
|
|
7
9
|
## Status
|
|
8
10
|
|
|
9
|
-
`pkgwhy` 1.
|
|
11
|
+
`pkgwhy` 1.6.0 is a Python supply-chain security decision-support tool and local pip/CI install gate for developers and AI agents. It is useful for local package inspection, conservative static package review, agent-readable JSON, vulnerability and provenance foundations, policy checks, artifact precheck, guarded pip installs, CI package-gate templates, local registry trust states, local tool validation, agent check dispatching, and the local private-registry and runner MVP.
|
|
10
12
|
|
|
11
13
|
It is not a production security scanner, not malware-detection certainty, and not a full sandbox. Results are evidence and signals for review, not proof that a package is safe or malicious.
|
|
12
14
|
|
|
13
|
-
Current packaged version: `1.
|
|
15
|
+
Current packaged version: `1.6.0`.
|
|
14
16
|
|
|
15
17
|
## What Works Now
|
|
16
18
|
|
|
@@ -22,8 +24,16 @@ pkgwhy explain typer
|
|
|
22
24
|
pkgwhy why typer
|
|
23
25
|
pkgwhy inspect typer
|
|
24
26
|
pkgwhy judge typer --json
|
|
27
|
+
pkgwhy precheck typer --json
|
|
28
|
+
pkgwhy precheck "typer==0.12.5" --json
|
|
29
|
+
pkgwhy precheck -r requirements.txt --json
|
|
30
|
+
pkgwhy precheck pyproject.toml --json
|
|
31
|
+
pkgwhy precheck annotated-doc==0.0.4 --download-artifacts --json
|
|
32
|
+
pkgwhy pip install typer --dry-run
|
|
33
|
+
pkgwhy pip install -r requirements.txt --dry-run
|
|
25
34
|
pkgwhy agent policy --json
|
|
26
35
|
pkgwhy agent precheck typer --json
|
|
36
|
+
pkgwhy agent check typer --json
|
|
27
37
|
pkgwhy risk typer
|
|
28
38
|
pkgwhy audit --limit 5 --json
|
|
29
39
|
pkgwhy audit --limit 5 --json --vulnerability-file ./osv-fixture.json
|
|
@@ -51,6 +61,15 @@ Implemented capabilities include:
|
|
|
51
61
|
- Metadata-derived provenance/source-trust fields from installed metadata and optional PyPI JSON, with unsupported attestation and trusted-publishing checks marked as unknown or not implemented.
|
|
52
62
|
- Conservative risk level, decision, warning, recommendation, evidence, confidence, risk model version, and rule-ID output.
|
|
53
63
|
- Human `inspect`, `risk`, and `judge` reports that show compact rule-evidence summaries, while JSON reports include structured rule details.
|
|
64
|
+
- Pre-install package precheck for package requirements, requirements files, and `pyproject.toml` dependencies.
|
|
65
|
+
- Explicit artifact-download precheck that downloads a PyPI wheel or source artifact to a temporary review directory, verifies SHA-256 when available, extracts safely, statically inspects files, and deletes temporary files by default.
|
|
66
|
+
- Optional gate exit codes via `pkgwhy precheck --enforce-exit-code`.
|
|
67
|
+
- Guarded pip install flow via `pkgwhy pip install`, with precheck first, stable exit codes, explicit overrides, and compact local decision logs.
|
|
68
|
+
- Reusable GitHub Actions package-gate template with advisory, strict, and agent modes.
|
|
69
|
+
- Local registry trust states for private tools: `trusted`, `reviewed`, `quarantined`, `blocked`, and `unknown`.
|
|
70
|
+
- Local private-tool source validation with `pkgwhy tool validate <path> --json`.
|
|
71
|
+
- Agent check dispatching with `pkgwhy agent check <target> --json` for package specs, dependency files, pyproject-style TOML, and local tool folders/scripts.
|
|
72
|
+
- Commercial and agent platform architecture documentation for future local policy packs, team review, hosted evidence cache, shared organization policy, and agent install gateway.
|
|
54
73
|
- Stable JSON output for agent workflows.
|
|
55
74
|
- Schema-versioned agent policy and package precheck output.
|
|
56
75
|
- Conservative non-interactive agent defaults that block unknown or high-risk package use until a human reviews the evidence.
|
|
@@ -64,8 +83,12 @@ pkgwhy registry list
|
|
|
64
83
|
pkgwhy registry add local-copy ~/.pkgwhy/registry
|
|
65
84
|
pkgwhy registry use local
|
|
66
85
|
pkgwhy publish ./my_tool.py
|
|
86
|
+
pkgwhy registry trust local/my_tool
|
|
87
|
+
pkgwhy registry quarantine local/my_tool
|
|
88
|
+
pkgwhy registry blocked
|
|
67
89
|
pkgwhy tool inspect local/my_tool
|
|
68
90
|
pkgwhy tool judge local/my_tool --json
|
|
91
|
+
pkgwhy tool validate ./my-tool-folder --json
|
|
69
92
|
pkgwhy run local/my_tool
|
|
70
93
|
pkgwhy run local/my_tool --non-interactive
|
|
71
94
|
```
|
|
@@ -85,6 +108,7 @@ Current runner policy is intentionally conservative:
|
|
|
85
108
|
- Corrupt registry indexes fail closed for publish and tool-judgement paths.
|
|
86
109
|
- Symlinks are not bundled, and stored registry paths must remain inside the registry root.
|
|
87
110
|
- Bundle hash mismatch or a missing bundle blocks execution.
|
|
111
|
+
- Quarantined or blocked registry trust states block execution.
|
|
88
112
|
- `sandbox_only` and `block` tool judgements block execution.
|
|
89
113
|
- Non-interactive execution is blocked unless both the judgement and manifest agent policy allow it.
|
|
90
114
|
- Tools with declared dependencies are not run yet because dependency installation is not implemented.
|
|
@@ -98,11 +122,12 @@ These are roadmap items, not current features:
|
|
|
98
122
|
|
|
99
123
|
- Complete vulnerability database coverage, transitive vulnerability analysis, or guaranteed advisory freshness.
|
|
100
124
|
- Default online vulnerability lookup. Network access is only used when explicitly requested.
|
|
101
|
-
-
|
|
125
|
+
- Persistent cached PyPI/source lookup beyond the current OSV response cache.
|
|
102
126
|
- Cloud/private remote registry backends.
|
|
103
127
|
- `pull`, mirroring, and remote synchronization.
|
|
104
128
|
- Tool dependency installation in the runner.
|
|
105
129
|
- Tool bundle signing and signature verification.
|
|
130
|
+
- Tool lock/verify commands and registry export/import.
|
|
106
131
|
- Dynamic sandbox analysis for arbitrary packages.
|
|
107
132
|
- Tool-specific `pkgwhy agent judge` expansion beyond the current package precheck path.
|
|
108
133
|
- `pkgwhy agent explain-decision <review-id>`.
|
|
@@ -161,15 +186,70 @@ Emit machine-readable judgement JSON:
|
|
|
161
186
|
pkgwhy judge typer --json
|
|
162
187
|
```
|
|
163
188
|
|
|
189
|
+
Before installing a package, run a local precheck:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
pkgwhy precheck typer --json
|
|
193
|
+
pkgwhy precheck "typer==0.12.5" --json
|
|
194
|
+
pkgwhy precheck -r requirements.txt --json
|
|
195
|
+
pkgwhy precheck pyproject.toml --json
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
By default, `pkgwhy precheck` uses local installed metadata when available and does not use the network. Add `--pypi` or `--osv` only when you want explicit online enrichment. Add `--download-artifacts` to query PyPI, download one wheel or source artifact, verify its SHA-256 when PyPI metadata provides it, extract it to a temporary review directory, inspect it statically, and delete the temporary files. The command does not install, import, or execute inspected package code.
|
|
199
|
+
|
|
200
|
+
For CI or install-gate usage, add `--enforce-exit-code`:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
pkgwhy precheck typer --json --enforce-exit-code
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Exit codes are:
|
|
207
|
+
|
|
208
|
+
- `0`: allow.
|
|
209
|
+
- `1`: allow with caution or manual review.
|
|
210
|
+
- `2`: block or sandbox-only.
|
|
211
|
+
- `4`: requested online/artifact lookup was unavailable or failed.
|
|
212
|
+
|
|
213
|
+
To gate an install, use `pkgwhy pip install` instead of raw `pip install`:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
pkgwhy pip install typer
|
|
217
|
+
pkgwhy pip install typer --policy strict
|
|
218
|
+
pkgwhy pip install -r requirements.txt
|
|
219
|
+
pkgwhy pip install typer --dry-run --json
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The pip gate always runs precheck first. It invokes pip only when the precheck policy allows the install, or when a human uses an explicit override flag. Review/caution results exit `1`, block/sandbox-only results exit `2`, tool/config errors exit `3`, and unavailable or incomplete requested evidence exits `4`. `--dry-run` evaluates the gate and writes the local decision log without invoking pip.
|
|
223
|
+
|
|
224
|
+
Overrides are explicit:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
pkgwhy pip install typer --override-review --override-reason "reviewed local evidence"
|
|
228
|
+
pkgwhy pip install suspicious-name --override-block --override-reason "temporary isolated test"
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Agents and automated workflows should use `pkgwhy pip install` when dependency policy is required, not raw `pip install`. The command is still decision support: it does not prove a package is safe and it does not sandbox pip or installed package code.
|
|
232
|
+
|
|
233
|
+
For CI package gates, start from the reusable GitHub Actions template:
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
examples/github-actions/pkgwhy-package-gate.yml
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
See [CI Templates](docs/ci-templates.md) for advisory, strict, and agent-mode usage. The template does not require secrets or a hosted `pkgwhy` service.
|
|
240
|
+
|
|
164
241
|
Inspect the default agent policy and run a conservative agent precheck:
|
|
165
242
|
|
|
166
243
|
```bash
|
|
167
244
|
pkgwhy agent policy --json
|
|
168
245
|
pkgwhy agent precheck typer --json
|
|
169
246
|
pkgwhy agent judge typer --json
|
|
247
|
+
pkgwhy agent check typer --json
|
|
248
|
+
pkgwhy agent check requirements.txt --json
|
|
249
|
+
pkgwhy agent check ./my-tool-folder --json
|
|
170
250
|
```
|
|
171
251
|
|
|
172
|
-
`pkgwhy agent precheck` applies policy to the package judgement. In the default non-interactive mode, unknown and high-risk package decisions are blocked until a human reviews the judgement evidence.
|
|
252
|
+
`pkgwhy agent precheck` applies policy to the package judgement. In the default non-interactive mode, unknown and high-risk package decisions are blocked until a human reviews the judgement evidence. `pkgwhy agent check` dispatches the target to the safest matching local check and returns one normalized decision envelope. These commands do not install, import, or execute inspected package code. Agent precheck writes a compact local decision log under the user config directory when that directory is writable.
|
|
173
253
|
|
|
174
254
|
Run a conservative risk report:
|
|
175
255
|
|
|
@@ -278,10 +358,36 @@ Apply the stricter non-interactive runner policy:
|
|
|
278
358
|
pkgwhy run local/my_tool --non-interactive
|
|
279
359
|
```
|
|
280
360
|
|
|
281
|
-
## Agent
|
|
361
|
+
## Agent Integration Contract
|
|
282
362
|
|
|
283
363
|
Compatibility policy: [docs/json-schema-compatibility.md](docs/json-schema-compatibility.md).
|
|
284
364
|
|
|
365
|
+
Decision-oriented JSON commands expose a shared top-level contract where the field applies: `schema_version`, `command`, `target`, `target_type`, `decision`, `risk_level`, `confidence`, `recommended_next_action`, `exit_code`, `exit_code_meaning`, `warnings`, `evidence`, `evidence_summary`, `source_freshness`, `policy`, and `errors` for JSON error objects. Existing command-specific fields remain available.
|
|
366
|
+
|
|
367
|
+
Exit code meanings are stable for agent consumers:
|
|
368
|
+
|
|
369
|
+
- `0`: allowed or completed successfully.
|
|
370
|
+
- `1`: review or caution required before proceeding.
|
|
371
|
+
- `2`: blocked by policy or risk decision.
|
|
372
|
+
- `3`: tool, configuration, or user input error.
|
|
373
|
+
- `4`: external data unavailable or evidence incomplete.
|
|
374
|
+
|
|
375
|
+
Decision meanings:
|
|
376
|
+
|
|
377
|
+
- `allow`: proceed under normal review practices.
|
|
378
|
+
- `allow_with_caution`: proceed only after reviewing warnings and evidence.
|
|
379
|
+
- `review_manually`: ask a human to review before proceeding.
|
|
380
|
+
- `sandbox_only`: use only inside a real sandbox; a Python virtual environment is not a full OS sandbox.
|
|
381
|
+
- `block`: do not install, import, or run unless a human approves a policy exception.
|
|
382
|
+
|
|
383
|
+
When `--json` is set and a handled user/configuration error occurs, commands emit `pkgwhy.error.v1` with `error_type`, `message`, `exit_code`, `exit_code_meaning`, `suggested_fix`, `command`, `target`, and `target_type` where available.
|
|
384
|
+
|
|
385
|
+
Batch precheck JSON includes top-level `blocking_targets`, `review_targets`, `allowed_targets`, and `aggregate_recommendation` so automation can see the package-level reason without walking every nested result. Full evidence remains available, and `evidence_summary` gives compact counts, top evidence, top warnings, and top rule IDs for agents that need a smaller decision surface.
|
|
386
|
+
|
|
387
|
+
The pip gate safety model is unchanged: `pkgwhy pip install` runs precheck before pip and does not invoke pip in dry-run mode, for blocked decisions, or when required evidence is unavailable. It does not sandbox pip or installed package code.
|
|
388
|
+
|
|
389
|
+
Local registry trust state now affects tool judgement. `blocked` and `quarantined` tools return blocking `tool judge` decisions. `trusted` and `reviewed` are local human labels; they do not override hash mismatch, signature status, manifest approval requirements, or static capability warnings.
|
|
390
|
+
|
|
285
391
|
Package judgement schema version: `pkgwhy.package_judgement.v1`.
|
|
286
392
|
|
|
287
393
|
Field shape for `pkgwhy judge <package> --json`:
|
|
@@ -421,13 +527,68 @@ Field shape for `pkgwhy tool judge <tool> --json`:
|
|
|
421
527
|
"hash_status": "verified",
|
|
422
528
|
"signature_status": "not_implemented",
|
|
423
529
|
"warnings": [
|
|
424
|
-
"Signature verification is not implemented yet."
|
|
425
|
-
"Static capability detection for tool bundles is not implemented yet."
|
|
530
|
+
"Signature verification is not implemented yet."
|
|
426
531
|
],
|
|
427
532
|
"recommendation": "Review declared permissions and manifest metadata before running this private tool."
|
|
428
533
|
}
|
|
429
534
|
```
|
|
430
535
|
|
|
536
|
+
Tool validation schema version: `pkgwhy.tool_validation.v1`.
|
|
537
|
+
|
|
538
|
+
Field shape for `pkgwhy tool validate ./folder --json`:
|
|
539
|
+
|
|
540
|
+
```json
|
|
541
|
+
{
|
|
542
|
+
"schema_version": "pkgwhy.tool_validation.v1",
|
|
543
|
+
"command": "pkgwhy tool validate",
|
|
544
|
+
"target": "./folder",
|
|
545
|
+
"target_type": "tool_folder",
|
|
546
|
+
"valid": true,
|
|
547
|
+
"decision": "allow",
|
|
548
|
+
"risk_level": "low",
|
|
549
|
+
"confidence": "high",
|
|
550
|
+
"entrypoint": "main.py",
|
|
551
|
+
"declared_permissions": [],
|
|
552
|
+
"detected_capabilities": [],
|
|
553
|
+
"issues": [],
|
|
554
|
+
"errors": [],
|
|
555
|
+
"warnings": [],
|
|
556
|
+
"policy": {
|
|
557
|
+
"executes_tool_code": false,
|
|
558
|
+
"writes_to_registry": false,
|
|
559
|
+
"symlinks_supported": false
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
Tool validation reads local files and manifests, checks path boundaries and entrypoints, and statically analyzes files. It does not publish to a registry and does not execute tool code.
|
|
565
|
+
|
|
566
|
+
Agent check schema version: `pkgwhy.agent_check.v1`.
|
|
567
|
+
|
|
568
|
+
Field shape for `pkgwhy agent check <target> --json`:
|
|
569
|
+
|
|
570
|
+
```json
|
|
571
|
+
{
|
|
572
|
+
"schema_version": "pkgwhy.agent_check.v1",
|
|
573
|
+
"command": "pkgwhy agent check",
|
|
574
|
+
"target": "requirements.txt",
|
|
575
|
+
"target_type": "requirements",
|
|
576
|
+
"decision": "block",
|
|
577
|
+
"risk_level": "high",
|
|
578
|
+
"confidence": "medium",
|
|
579
|
+
"recommended_next_action": "conservative next action text",
|
|
580
|
+
"exit_code": 2,
|
|
581
|
+
"exit_code_meaning": "blocked by policy or risk decision",
|
|
582
|
+
"evidence_summary": {},
|
|
583
|
+
"result_schema_version": "pkgwhy.precheck_batch.v1",
|
|
584
|
+
"result": {
|
|
585
|
+
"schema_version": "pkgwhy.precheck_batch.v1"
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
`pkgwhy agent check` currently dispatches package specs to package precheck, requirements files and pyproject-style TOML files to batch precheck, and local tool folders/scripts to tool validation.
|
|
591
|
+
|
|
431
592
|
Supported package and tool decision values are:
|
|
432
593
|
|
|
433
594
|
- `allow`
|
|
@@ -633,6 +794,7 @@ Release and process references:
|
|
|
633
794
|
- [1.0.0 Feature Surface](docs/release-candidate-surface.md)
|
|
634
795
|
- [Threat Model](docs/threat-model.md)
|
|
635
796
|
- [Production Readiness Blockers](docs/production-readiness.md)
|
|
797
|
+
- [Commercial And Agent Platform Direction](docs/commercial-agent-platform.md)
|
|
636
798
|
|
|
637
799
|
## Roadmap
|
|
638
800
|
|