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.
Files changed (128) hide show
  1. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/CHANGELOG.md +61 -0
  2. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/PKG-INFO +170 -8
  3. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/README.md +169 -7
  4. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/SECURITY.md +17 -3
  5. pkgwhy-1.6.0/docs/ci-templates.md +77 -0
  6. pkgwhy-1.6.0/docs/commercial-agent-platform.md +135 -0
  7. pkgwhy-1.6.0/docs/json-schema-compatibility.md +67 -0
  8. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/release-checklist.md +9 -0
  9. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/versioning-policy.md +7 -1
  10. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/pyproject.toml +1 -1
  11. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/__init__.py +1 -1
  12. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/cli.py +678 -1
  13. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/core/constants.py +3 -0
  14. pkgwhy-1.6.0/src/pkgwhy/core/decision_contract.py +165 -0
  15. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/core/models.py +417 -1
  16. pkgwhy-1.6.0/src/pkgwhy/pip_gate.py +382 -0
  17. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/policy/tool_execution.py +6 -1
  18. pkgwhy-1.6.0/src/pkgwhy/precheck.py +1217 -0
  19. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/tools.py +59 -2
  20. pkgwhy-1.6.0/src/pkgwhy/registry/trust.py +30 -0
  21. pkgwhy-1.6.0/src/pkgwhy/registry/validate.py +421 -0
  22. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/reports/audit.py +45 -0
  23. pkgwhy-1.6.0/tests/fixtures/precheck/requirements.txt +2 -0
  24. pkgwhy-1.6.0/tests/fixtures/private-tools/hello-tool/hello.py +6 -0
  25. pkgwhy-1.6.0/tests/fixtures/private-tools/hello-tool/pkgwhy.toml +18 -0
  26. pkgwhy-1.6.0/tests/test_agent_check.py +86 -0
  27. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_agent_policy.py +11 -0
  28. pkgwhy-1.6.0/tests/test_ci_templates.py +34 -0
  29. pkgwhy-1.6.0/tests/test_commercial_design_docs.py +27 -0
  30. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_json_snapshots.py +132 -1
  31. pkgwhy-1.6.0/tests/test_pip_gate.py +390 -0
  32. pkgwhy-1.6.0/tests/test_precheck.py +622 -0
  33. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_reports.py +8 -0
  34. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_runner.py +14 -0
  35. pkgwhy-1.6.0/tests/test_tool_judgement.py +295 -0
  36. pkgwhy-1.6.0/tests/test_tool_validate.py +191 -0
  37. pkgwhy-1.0.0/docs/json-schema-compatibility.md +0 -37
  38. pkgwhy-1.0.0/tests/test_tool_judgement.py +0 -110
  39. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/.gitignore +0 -0
  40. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/CONTRIBUTING.md +0 -0
  41. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/LICENSE +0 -0
  42. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/dynamic-sandbox.md +0 -0
  43. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/production-readiness.md +0 -0
  44. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/release-candidate-surface.md +0 -0
  45. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/static-rule-corpus.md +0 -0
  46. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/docs/threat-model.md +0 -0
  47. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/scripts/check_public_traces.py +0 -0
  48. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/__main__.py +0 -0
  49. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/agent/__init__.py +0 -0
  50. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/agent/judge.py +0 -0
  51. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/core/__init__.py +0 -0
  52. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dependencies/__init__.py +0 -0
  53. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dependencies/graph.py +0 -0
  54. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dependencies/reason.py +0 -0
  55. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dynamic/__init__.py +0 -0
  56. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/dynamic/analysis.py +0 -0
  57. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/explanations/__init__.py +0 -0
  58. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/explanations/explain.py +0 -0
  59. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/explanations/local_db.py +0 -0
  60. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/imports/__init__.py +0 -0
  61. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/imports/scanner.py +0 -0
  62. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/__init__.py +0 -0
  63. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/files.py +0 -0
  64. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/python_static.py +0 -0
  65. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/size.py +0 -0
  66. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/inspection/text_patterns.py +0 -0
  67. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/manifests/__init__.py +0 -0
  68. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/manifests/lockfiles.py +0 -0
  69. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/manifests/pyproject.py +0 -0
  70. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/manifests/requirements.py +0 -0
  71. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/metadata/__init__.py +0 -0
  72. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/metadata/installed.py +0 -0
  73. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/metadata/pypi.py +0 -0
  74. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/policy/__init__.py +0 -0
  75. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/policy/agent_policy.py +0 -0
  76. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/policy/audit_log.py +0 -0
  77. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/provenance/__init__.py +0 -0
  78. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/provenance/installed.py +0 -0
  79. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/__init__.py +0 -0
  80. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/local.py +0 -0
  81. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/manifest.py +0 -0
  82. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/publish.py +0 -0
  83. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/registry/run.py +0 -0
  84. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/reports/__init__.py +0 -0
  85. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/risk/__init__.py +0 -0
  86. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/risk/rules.py +0 -0
  87. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/risk/scoring.py +0 -0
  88. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/typosquat/__init__.py +0 -0
  89. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/typosquat/detector.py +0 -0
  90. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/typosquat/popular_packages.py +0 -0
  91. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/vulnerabilities/__init__.py +0 -0
  92. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/vulnerabilities/matching.py +0 -0
  93. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/src/pkgwhy/vulnerabilities/osv.py +0 -0
  94. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/extension.so +0 -0
  95. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/helper.exe +0 -0
  96. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/javascript_false_positive.js +0 -0
  97. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/javascript_signals.min.js +0 -0
  98. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/module.wasm +0 -0
  99. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/postinstall +0 -0
  100. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/pyproject.toml +0 -0
  101. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/setup.cfg +0 -0
  102. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/assets/setup.py +0 -0
  103. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/deserialisation.py +0 -0
  104. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/dynamic_execution.py +0 -0
  105. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/encoded_payloads.py +0 -0
  106. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/import_trap.py +0 -0
  107. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/process_environment_package_manager.py +0 -0
  108. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/fixtures/static_rule_corpus/python/url_credential_patterns.py +0 -0
  109. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_audit_log.py +0 -0
  110. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_cli.py +0 -0
  111. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_dependency_graph.py +0 -0
  112. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_dynamic.py +0 -0
  113. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_explanations.py +0 -0
  114. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_file_static_analysis.py +0 -0
  115. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_import_scanner.py +0 -0
  116. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_manifests.py +0 -0
  117. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_provenance.py +0 -0
  118. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_publish.py +0 -0
  119. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_python_static.py +0 -0
  120. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_registry.py +0 -0
  121. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_risk.py +0 -0
  122. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_risk_rules.py +0 -0
  123. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_size.py +0 -0
  124. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_static_rule_corpus.py +0 -0
  125. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_tool_manifest.py +0 -0
  126. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_tool_policy.py +0 -0
  127. {pkgwhy-1.0.0 → pkgwhy-1.6.0}/tests/test_typosquat.py +0 -0
  128. {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.0.0
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.0.0 is a Python supply-chain security decision-support tool 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, and the local private-registry and runner MVP.
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.0.0`.
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
- - Cached PyPI/source lookup beyond the current OSV response cache.
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. The command writes a compact local decision log under the user config directory when that directory is writable and does not install, import, or execute the package.
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 JSON Contracts
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.0.0 is a Python supply-chain security decision-support tool 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, and the local private-registry and runner MVP.
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.0.0`.
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
- - Cached PyPI/source lookup beyond the current OSV response cache.
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. The command writes a compact local decision log under the user config directory when that directory is writable and does not install, import, or execute the package.
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 JSON Contracts
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