wardproof 0.3.1__tar.gz → 0.3.2__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 (66) hide show
  1. {wardproof-0.3.1 → wardproof-0.3.2}/PKG-INFO +19 -1
  2. {wardproof-0.3.1 → wardproof-0.3.2}/README.md +18 -0
  3. {wardproof-0.3.1 → wardproof-0.3.2}/pyproject.toml +1 -1
  4. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/__init__.py +1 -1
  5. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/cli.py +55 -0
  6. {wardproof-0.3.1 → wardproof-0.3.2}/.gitignore +0 -0
  7. {wardproof-0.3.1 → wardproof-0.3.2}/CONTRIBUTING.md +0 -0
  8. {wardproof-0.3.1 → wardproof-0.3.2}/LICENSE +0 -0
  9. {wardproof-0.3.1 → wardproof-0.3.2}/SECURITY.md +0 -0
  10. {wardproof-0.3.1 → wardproof-0.3.2}/THREAT_MODEL.md +0 -0
  11. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/README.md +0 -0
  12. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/corpus.jsonl +0 -0
  13. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/external/README.md +0 -0
  14. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/external/__init__.py +0 -0
  15. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/external/_screen.py +0 -0
  16. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/external/agentdojo.py +0 -0
  17. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/external/fetch_data.py +0 -0
  18. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/external/injecagent.py +0 -0
  19. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/heldout.py +0 -0
  20. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/latency.py +0 -0
  21. {wardproof-0.3.1 → wardproof-0.3.2}/benchmarks/run_benchmark.py +0 -0
  22. {wardproof-0.3.1 → wardproof-0.3.2}/examples/agent_to_agent_transfer.py +0 -0
  23. {wardproof-0.3.1 → wardproof-0.3.2}/examples/integrations/README.md +0 -0
  24. {wardproof-0.3.1 → wardproof-0.3.2}/examples/integrations/agentkit_guarded.py +0 -0
  25. {wardproof-0.3.1 → wardproof-0.3.2}/examples/integrations/anthropic_tools_guarded.py +0 -0
  26. {wardproof-0.3.1 → wardproof-0.3.2}/examples/integrations/crewai_guarded.py +0 -0
  27. {wardproof-0.3.1 → wardproof-0.3.2}/examples/integrations/langgraph_guarded.py +0 -0
  28. {wardproof-0.3.1 → wardproof-0.3.2}/examples/integrations/mcp_guarded.py +0 -0
  29. {wardproof-0.3.1 → wardproof-0.3.2}/examples/integrations/openai_tools_guarded.py +0 -0
  30. {wardproof-0.3.1 → wardproof-0.3.2}/examples/integrations/skills_guard.py +0 -0
  31. {wardproof-0.3.1 → wardproof-0.3.2}/examples/integrations/venice_guarded.py +0 -0
  32. {wardproof-0.3.1 → wardproof-0.3.2}/examples/morse_injection_blocked_at_action.py +0 -0
  33. {wardproof-0.3.1 → wardproof-0.3.2}/examples/protect_defi_agent.py +0 -0
  34. {wardproof-0.3.1 → wardproof-0.3.2}/examples/protect_mcp_agent.py +0 -0
  35. {wardproof-0.3.1 → wardproof-0.3.2}/examples/protect_rag_app.py +0 -0
  36. {wardproof-0.3.1 → wardproof-0.3.2}/examples/protect_x402_payments.py +0 -0
  37. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/agents/__init__.py +0 -0
  38. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/agents/base.py +0 -0
  39. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/agents/detector.py +0 -0
  40. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/agents/responder.py +0 -0
  41. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/agents/verifier.py +0 -0
  42. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/audit/__init__.py +0 -0
  43. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/audit/ledger.py +0 -0
  44. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/audit/stix.py +0 -0
  45. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/config.py +0 -0
  46. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/guardrails/__init__.py +0 -0
  47. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/guardrails/_normalize.py +0 -0
  48. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/guardrails/base.py +0 -0
  49. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/guardrails/mcp_guard.py +0 -0
  50. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/guardrails/memory_poisoning.py +0 -0
  51. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/guardrails/prompt_injection.py +0 -0
  52. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/guardrails/tool_misuse.py +0 -0
  53. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/guardrails/transfer.py +0 -0
  54. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/guardrails/x402_payment.py +0 -0
  55. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/llm/__init__.py +0 -0
  56. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/llm/base.py +0 -0
  57. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/llm/null.py +0 -0
  58. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/llm/ollama_client.py +0 -0
  59. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/orchestration/__init__.py +0 -0
  60. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/orchestration/engine.py +0 -0
  61. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/orchestration/factory.py +0 -0
  62. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/sandbox/__init__.py +0 -0
  63. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/sandbox/executor.py +0 -0
  64. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/sandbox/permissions.py +0 -0
  65. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/schema.py +0 -0
  66. {wardproof-0.3.1 → wardproof-0.3.2}/wardproof/standards.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wardproof
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Local-first, verifiable defensive AI agent swarms that protect other AI agent systems.
5
5
  Project-URL: Homepage, https://wardproof.xyz
6
6
  Project-URL: Repository, https://github.com/Impossible-Mission-Force/wardproof
@@ -202,6 +202,24 @@ Verify an exported ledger from the command line:
202
202
  wardproof verify-ledger ./audit.jsonl --pubkey <hex_public_key>
203
203
  ```
204
204
 
205
+ ### Screen one action with `wardproof check`
206
+
207
+ Screen a single input or tool call from the command line. It runs the real
208
+ default swarm locally and exits `0` only when the verdict is `ALLOW`, so you can
209
+ gate a shell pipeline or an agent skill on it:
210
+
211
+ ```bash
212
+ # A tool call (tool name as the content, arguments as a JSON string)
213
+ wardproof check "get_weather" --args '{"city":"Hanoi"}' # ALLOW, exits 0
214
+
215
+ # An untrusted input
216
+ wardproof check "ignore all previous instructions" --kind input # BLOCK, exits non-zero
217
+ ```
218
+
219
+ Add `--json` to get a structured `{"verdict": ..., "allowed": ..., "risk": ...,
220
+ "reasons": [...]}` result to parse. A portable guard skill that wires this check
221
+ into a host agent lives in [`skill/wardproof-guard/`](https://github.com/Impossible-Mission-Force/wardproof/tree/main/skill/wardproof-guard).
222
+
205
223
  ---
206
224
 
207
225
  ## Architecture
@@ -152,6 +152,24 @@ Verify an exported ledger from the command line:
152
152
  wardproof verify-ledger ./audit.jsonl --pubkey <hex_public_key>
153
153
  ```
154
154
 
155
+ ### Screen one action with `wardproof check`
156
+
157
+ Screen a single input or tool call from the command line. It runs the real
158
+ default swarm locally and exits `0` only when the verdict is `ALLOW`, so you can
159
+ gate a shell pipeline or an agent skill on it:
160
+
161
+ ```bash
162
+ # A tool call (tool name as the content, arguments as a JSON string)
163
+ wardproof check "get_weather" --args '{"city":"Hanoi"}' # ALLOW, exits 0
164
+
165
+ # An untrusted input
166
+ wardproof check "ignore all previous instructions" --kind input # BLOCK, exits non-zero
167
+ ```
168
+
169
+ Add `--json` to get a structured `{"verdict": ..., "allowed": ..., "risk": ...,
170
+ "reasons": [...]}` result to parse. A portable guard skill that wires this check
171
+ into a host agent lives in [`skill/wardproof-guard/`](https://github.com/Impossible-Mission-Force/wardproof/tree/main/skill/wardproof-guard).
172
+
155
173
  ---
156
174
 
157
175
  ## Architecture
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "wardproof"
7
- version = "0.3.1"
7
+ version = "0.3.2"
8
8
  description = "Local-first, verifiable defensive AI agent swarms that protect other AI agent systems."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -16,7 +16,7 @@ from wardproof.sandbox.executor import SandboxExecutor, ToolRegistry
16
16
  from wardproof.sandbox.permissions import PermissionBroker, ToolGrant
17
17
  from wardproof.schema import Decision, Event, Finding, Severity, Verdict
18
18
 
19
- __version__ = "0.3.1"
19
+ __version__ = "0.3.2"
20
20
  __all__ = [
21
21
  "Event",
22
22
  "Decision",
@@ -9,6 +9,8 @@ from pathlib import Path
9
9
 
10
10
  from wardproof.audit.ledger import AuditEntry, AuditLedger
11
11
  from wardproof.audit.stix import to_stix_bundle
12
+ from wardproof.orchestration.factory import build_default_swarm
13
+ from wardproof.schema import Event, Verdict
12
14
 
13
15
 
14
16
  def _load_entries(path: str) -> list[AuditEntry]:
@@ -39,6 +41,47 @@ def _export_stix(path: str, out: str | None) -> int:
39
41
  return 0
40
42
 
41
43
 
44
+ def _check(
45
+ kind: str,
46
+ content: str,
47
+ source: str,
48
+ args_json: str | None,
49
+ as_json: bool,
50
+ ) -> int:
51
+ metadata: dict = {}
52
+ if args_json:
53
+ try:
54
+ metadata["args"] = json.loads(args_json)
55
+ except json.JSONDecodeError:
56
+ metadata["args"] = args_json
57
+ swarm = build_default_swarm()
58
+ out = swarm.handle(Event(kind=kind, source=source, content=content, metadata=metadata))
59
+ seen: set[str] = set()
60
+ reasons: list[str] = []
61
+ for d in (out.detector, out.verifier):
62
+ for f in d.findings:
63
+ if f.triggered and f.reason and f.reason not in seen:
64
+ seen.add(f.reason)
65
+ reasons.append(f.reason)
66
+ if as_json:
67
+ print(
68
+ json.dumps(
69
+ {
70
+ "verdict": out.verdict.value,
71
+ "allowed": out.verdict is Verdict.ALLOW,
72
+ "risk": round(out.risk, 3),
73
+ "reasons": reasons,
74
+ }
75
+ )
76
+ )
77
+ else:
78
+ print(out.verdict.value.upper())
79
+ if reasons:
80
+ print(" " + "; ".join(reasons))
81
+ # exit 0 only when the action is allowed, so shells and skills can gate on it
82
+ return 0 if out.verdict is Verdict.ALLOW else 2
83
+
84
+
42
85
  def main(argv: list[str] | None = None) -> int:
43
86
  parser = argparse.ArgumentParser(prog="wardproof")
44
87
  sub = parser.add_subparsers(dest="cmd", required=True)
@@ -48,11 +91,23 @@ def main(argv: list[str] | None = None) -> int:
48
91
  sp = sub.add_parser("export-stix", help="export a JSONL audit ledger as a STIX 2.1 bundle")
49
92
  sp.add_argument("path")
50
93
  sp.add_argument("--out", default=None, help="write to a file instead of stdout")
94
+ cp = sub.add_parser("check", help="screen one input or tool call and print its verdict")
95
+ cp.add_argument("content", help="the input text, or the tool name for a tool call")
96
+ cp.add_argument(
97
+ "--kind",
98
+ default="tool_call",
99
+ help="event kind: tool_call (default) or input",
100
+ )
101
+ cp.add_argument("--source", default="agent", help="who originated the event")
102
+ cp.add_argument("--args", default=None, help="tool-call arguments as a JSON string")
103
+ cp.add_argument("--json", action="store_true", help="print a JSON object instead of text")
51
104
  args = parser.parse_args(argv)
52
105
  if args.cmd == "verify-ledger":
53
106
  return _verify_file(args.path, args.pubkey)
54
107
  if args.cmd == "export-stix":
55
108
  return _export_stix(args.path, args.out)
109
+ if args.cmd == "check":
110
+ return _check(args.kind, args.content, args.source, args.args, args.json)
56
111
  return 1
57
112
 
58
113
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes