jep-cli 0.6.1__tar.gz → 0.7.1__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.
jep_cli-0.7.1/PKG-INFO ADDED
@@ -0,0 +1,123 @@
1
+ Metadata-Version: 2.4
2
+ Name: jep-cli
3
+ Version: 0.7.1
4
+ Summary: Command-line client for JEP Core 0.7 with explicit legacy compatibility
5
+ Author-email: HJS Spec <signal@humanjudgment.org>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/hjs-spec/cli
8
+ Project-URL: Repository, https://github.com/hjs-spec/cli
9
+ Project-URL: Issues, https://github.com/hjs-spec/cli/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ License-File: NOTICE.md
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
20
+ Dynamic: license-file
21
+
22
+ # JEP CLI — JEP Core 0.7
23
+
24
+ Command-line client for creating and verifying current JEP Core 0.7 events
25
+ through the JEP API.
26
+
27
+ Default endpoints:
28
+
29
+ ```text
30
+ POST /v0.7/events/create
31
+ POST /v0.7/events/verify
32
+ GET /health
33
+ ```
34
+
35
+ Historical pre-0.7 handling is explicit through `--legacy`; the CLI never
36
+ retries a failed 0.7 event with a legacy decoder.
37
+
38
+ ## Status
39
+
40
+ Experimental reference client. It does not define Core semantics or determine
41
+ truth, authorization validity, legal effect, causality, or policy outcome.
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install jep-cli
47
+ ```
48
+
49
+ ## Configuration
50
+
51
+ ```bash
52
+ export JEP_API_URL=http://127.0.0.1:8000
53
+ export JEP_API_KEY=
54
+ ```
55
+
56
+ ## Create
57
+
58
+ Judgment:
59
+
60
+ ```bash
61
+ jep create \
62
+ --verb J \
63
+ --who did:example:agent-789 \
64
+ --what '{"claim":"approve","subject":"demo"}'
65
+ ```
66
+
67
+ Delegation:
68
+
69
+ ```bash
70
+ jep create \
71
+ --verb D \
72
+ --who did:example:principal \
73
+ --what '{"delegatee":"did:example:agent","scope":{"actions":["read"]}}'
74
+ ```
75
+
76
+ Termination and Verification require `--ref`. Pass a typed reference as
77
+ JSON when the target is another JEP event.
78
+
79
+ ## Verify
80
+
81
+ ```bash
82
+ jep verify event.json --mode archival
83
+ ```
84
+
85
+ 0.7 validation returns `status` plus independent `checks`, not a cumulative
86
+ Validation Level.
87
+
88
+ ## Explicit legacy verification
89
+
90
+ ```bash
91
+ jep verify old-event.json \
92
+ --legacy \
93
+ --legacy-format json-sorted-v1
94
+ ```
95
+
96
+ Legacy selection must come from known artifact context. Do not use a failed 0.7
97
+ validation as evidence that an event should be treated as 0.6.
98
+
99
+ ## JEP Core 0.7 model
100
+
101
+ - Event Identity is `(who,id)`.
102
+ - Event Hash identifies an exact signed artifact.
103
+ - Core does not require a top-level nonce.
104
+ - D requires `delegatee + scope`.
105
+ - T requires target `ref + termination_scope`.
106
+ - V requires target `ref + verification_scope + result`.
107
+ - chain and policy semantics remain outside Core.
108
+
109
+ ## Related repositories
110
+
111
+ - JEP Core: https://github.com/hjs-spec/jep-core
112
+ - JEP API: https://github.com/hjs-spec/jep-api
113
+ - Python SDK: https://github.com/hjs-spec/sdk-py
114
+ - JavaScript SDK: https://github.com/hjs-spec/sdk-js
115
+ - Go SDK: https://github.com/hjs-spec/sdk-go
116
+
117
+ ## Public draft
118
+
119
+ - https://datatracker.ietf.org/doc/draft-wang-jep-judgment-event-protocol/
120
+
121
+ ## License
122
+
123
+ MIT
@@ -0,0 +1,102 @@
1
+ # JEP CLI — JEP Core 0.7
2
+
3
+ Command-line client for creating and verifying current JEP Core 0.7 events
4
+ through the JEP API.
5
+
6
+ Default endpoints:
7
+
8
+ ```text
9
+ POST /v0.7/events/create
10
+ POST /v0.7/events/verify
11
+ GET /health
12
+ ```
13
+
14
+ Historical pre-0.7 handling is explicit through `--legacy`; the CLI never
15
+ retries a failed 0.7 event with a legacy decoder.
16
+
17
+ ## Status
18
+
19
+ Experimental reference client. It does not define Core semantics or determine
20
+ truth, authorization validity, legal effect, causality, or policy outcome.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ pip install jep-cli
26
+ ```
27
+
28
+ ## Configuration
29
+
30
+ ```bash
31
+ export JEP_API_URL=http://127.0.0.1:8000
32
+ export JEP_API_KEY=
33
+ ```
34
+
35
+ ## Create
36
+
37
+ Judgment:
38
+
39
+ ```bash
40
+ jep create \
41
+ --verb J \
42
+ --who did:example:agent-789 \
43
+ --what '{"claim":"approve","subject":"demo"}'
44
+ ```
45
+
46
+ Delegation:
47
+
48
+ ```bash
49
+ jep create \
50
+ --verb D \
51
+ --who did:example:principal \
52
+ --what '{"delegatee":"did:example:agent","scope":{"actions":["read"]}}'
53
+ ```
54
+
55
+ Termination and Verification require `--ref`. Pass a typed reference as
56
+ JSON when the target is another JEP event.
57
+
58
+ ## Verify
59
+
60
+ ```bash
61
+ jep verify event.json --mode archival
62
+ ```
63
+
64
+ 0.7 validation returns `status` plus independent `checks`, not a cumulative
65
+ Validation Level.
66
+
67
+ ## Explicit legacy verification
68
+
69
+ ```bash
70
+ jep verify old-event.json \
71
+ --legacy \
72
+ --legacy-format json-sorted-v1
73
+ ```
74
+
75
+ Legacy selection must come from known artifact context. Do not use a failed 0.7
76
+ validation as evidence that an event should be treated as 0.6.
77
+
78
+ ## JEP Core 0.7 model
79
+
80
+ - Event Identity is `(who,id)`.
81
+ - Event Hash identifies an exact signed artifact.
82
+ - Core does not require a top-level nonce.
83
+ - D requires `delegatee + scope`.
84
+ - T requires target `ref + termination_scope`.
85
+ - V requires target `ref + verification_scope + result`.
86
+ - chain and policy semantics remain outside Core.
87
+
88
+ ## Related repositories
89
+
90
+ - JEP Core: https://github.com/hjs-spec/jep-core
91
+ - JEP API: https://github.com/hjs-spec/jep-api
92
+ - Python SDK: https://github.com/hjs-spec/sdk-py
93
+ - JavaScript SDK: https://github.com/hjs-spec/sdk-js
94
+ - Go SDK: https://github.com/hjs-spec/sdk-go
95
+
96
+ ## Public draft
97
+
98
+ - https://datatracker.ietf.org/doc/draft-wang-jep-judgment-event-protocol/
99
+
100
+ ## License
101
+
102
+ MIT
@@ -0,0 +1,3 @@
1
+ """JEP CLI v0.6."""
2
+
3
+ __version__ = "0.7.1"
@@ -1,4 +1,4 @@
1
- """Small HTTP client for JEP CLI v0.6."""
1
+ """Small HTTP client for the JEP Core 0.7 CLI."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -26,10 +26,16 @@ class JEPClient:
26
26
  self.timeout = timeout
27
27
 
28
28
  def create_event(self, payload: Dict[str, Any]) -> Dict[str, Any]:
29
- return self._json("POST", "/events/create", payload)
29
+ return self._json("POST", "/v0.7/events/create", payload)
30
30
 
31
31
  def verify_event(self, payload: Dict[str, Any]) -> Dict[str, Any]:
32
- return self._json("POST", "/events/verify", payload)
32
+ return self._json("POST", "/v0.7/events/verify", payload)
33
+
34
+ def create_event_legacy(self, payload: Dict[str, Any]) -> Dict[str, Any]:
35
+ return self._json("POST", "/events/create", payload)
36
+
37
+ def verify_event_legacy(self, payload: Dict[str, Any]) -> Dict[str, Any]:
38
+ return self._json("POST", "/events/verify-legacy", payload)
33
39
 
34
40
  def health(self) -> Dict[str, Any]:
35
41
  return self._json("GET", "/health", None)
@@ -38,7 +44,7 @@ class JEPClient:
38
44
  data = None
39
45
  headers = {
40
46
  "content-type": "application/json",
41
- "user-agent": "JEP-CLI/0.6.0",
47
+ "user-agent": "JEP-CLI/0.7.1",
42
48
  }
43
49
  if self.api_key:
44
50
  headers["authorization"] = f"Bearer {self.api_key}"
@@ -57,5 +63,5 @@ class JEPClient:
57
63
  parsed = json.loads(body)
58
64
  except Exception:
59
65
  parsed = {"message": body}
60
- msg = parsed.get("message") or parsed.get("error") or body
66
+ msg = parsed.get("message") or parsed.get("detail") or parsed.get("error") or body
61
67
  raise JEPAPIError(exc.code, msg, parsed) from exc
@@ -1,4 +1,4 @@
1
- """JEP CLI v0.6 command line interface."""
1
+ """JEP Core 0.7 command line interface with explicit legacy compatibility."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -19,14 +19,19 @@ def parse_json_value(value: str) -> Any:
19
19
  if value == "-":
20
20
  return json.load(sys.stdin)
21
21
 
22
- path = Path(value)
23
- if path.exists() and path.is_file():
24
- return json.loads(path.read_text(encoding="utf-8"))
25
-
26
22
  try:
27
23
  return json.loads(value)
28
24
  except json.JSONDecodeError:
29
- return value
25
+ pass
26
+ # Inline event JSON may be longer than the filesystem filename limit.
27
+ path = Path(value)
28
+ try:
29
+ is_file = path.is_file()
30
+ except OSError:
31
+ is_file = False
32
+ if is_file:
33
+ return json.loads(path.read_text(encoding="utf-8"))
34
+ return value
30
35
 
31
36
 
32
37
  def parse_ext_items(items: list[str]) -> Dict[str, Any]:
@@ -72,7 +77,8 @@ def cmd_create(args: argparse.Namespace) -> int:
72
77
  if args.ext_crit:
73
78
  payload["ext_crit"] = args.ext_crit
74
79
 
75
- result = build_client(args).create_event(payload)
80
+ client = build_client(args)
81
+ result = client.create_event_legacy(payload) if args.legacy else client.create_event(payload)
76
82
  print_json(result)
77
83
  return 0
78
84
 
@@ -81,18 +87,21 @@ def cmd_verify(args: argparse.Namespace) -> int:
81
87
  event = parse_json_value(args.event)
82
88
  if not isinstance(event, dict):
83
89
  raise ValueError("event must be JSON object or path to JSON event file")
84
- payload = {
85
- "event": event,
86
- "mode": args.mode,
87
- "consume_nonce": args.consume_nonce,
88
- }
90
+ client = build_client(args)
91
+ if args.legacy:
92
+ payload = {"event": event, "format": args.legacy_format}
93
+ result = client.verify_event_legacy(payload)
94
+ print_json(result)
95
+ return 0 if result.get("valid") is True else 2
96
+
97
+ payload = {"event": event, "mode": args.mode}
89
98
  if args.expected_audience:
90
99
  payload["expected_audience"] = args.expected_audience
91
- if args.mode == "acceptance" and not args.expected_audience:
92
- raise ValueError("acceptance mode requires --expected-audience")
93
- result = build_client(args).verify_event(payload)
100
+ if args.max_age_seconds is not None:
101
+ payload["max_age_seconds"] = args.max_age_seconds
102
+ result = client.verify_event(payload)
94
103
  print_json(result)
95
- return 0 if result.get("valid") is True else 2
104
+ return 0 if result.get("status") == "valid" else 2
96
105
 
97
106
 
98
107
  def cmd_health(args: argparse.Namespace) -> int:
@@ -112,7 +121,7 @@ def cmd_extract_event(args: argparse.Namespace) -> int:
112
121
  def build_parser() -> argparse.ArgumentParser:
113
122
  parser = argparse.ArgumentParser(
114
123
  prog="jep",
115
- description="JEP CLI v0.6 for creating and verifying JEP-Core events through the JEP API.",
124
+ description="JEP CLI for JEP Core 0.7. Legacy pre-0.7 paths require explicit flags.",
116
125
  )
117
126
  parser.add_argument("--base-url", default="", help="JEP API base URL. Default: JEP_API_URL or http://127.0.0.1:8000")
118
127
  parser.add_argument("--api-key", default="", help="API key. Default: JEP_API_KEY")
@@ -125,18 +134,21 @@ def build_parser() -> argparse.ArgumentParser:
125
134
  create.add_argument("--who", default="", help="Actor identifier")
126
135
  create.add_argument("--what", required=True, help="JSON value, string, file path, or '-' for stdin")
127
136
  create.add_argument("--aud", default="", help="Audience / validation context")
128
- create.add_argument("--ref", default="", help="Reference event hash")
137
+ create.add_argument("--ref", default="", help="Reference JSON, string, or file path")
129
138
  create.add_argument("--ttl-minutes", type=int, default=None, help="Optional TTL extension in minutes")
130
139
  create.add_argument("--digest-only-who", action="store_true", help="Request digest-only privacy extension")
131
140
  create.add_argument("--ext", action="append", default=[], help="Extension key=json_or_string. May be repeated")
132
141
  create.add_argument("--ext-crit", action="append", default=[], help="Critical extension URI. May be repeated")
142
+ create.add_argument("--legacy", action="store_true", help="Use explicit pre-0.7 create endpoint")
133
143
  create.set_defaults(func=cmd_create)
134
144
 
135
145
  verify = sub.add_parser("verify", help="Verify a JEP event")
136
146
  verify.add_argument("event", help="Event JSON object, event JSON file path, or '-' for stdin")
137
147
  verify.add_argument("--mode", default="archival", choices=["archival", "acceptance"], help="Validation mode")
138
- verify.add_argument("--expected-audience", default="", help="Required receiving audience for acceptance")
139
- verify.add_argument("--consume-nonce", action="store_true", help="Ask verifier to consume nonce")
148
+ verify.add_argument("--expected-audience", default="", help="Optional audience required by the selected acceptance profile")
149
+ verify.add_argument("--max-age-seconds", type=int, default=None, help="Optional profile freshness window")
150
+ verify.add_argument("--legacy", action="store_true", help="Use explicit pre-0.7 legacy verifier")
151
+ verify.add_argument("--legacy-format", default="json-sorted-v1", choices=["json-sorted-v1", "hf-space-v06"], help="Historical decoder format; used only with --legacy")
140
152
  verify.set_defaults(func=cmd_verify)
141
153
 
142
154
  health = sub.add_parser("health", help="Check JEP API health")
@@ -0,0 +1,123 @@
1
+ Metadata-Version: 2.4
2
+ Name: jep-cli
3
+ Version: 0.7.1
4
+ Summary: Command-line client for JEP Core 0.7 with explicit legacy compatibility
5
+ Author-email: HJS Spec <signal@humanjudgment.org>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/hjs-spec/cli
8
+ Project-URL: Repository, https://github.com/hjs-spec/cli
9
+ Project-URL: Issues, https://github.com/hjs-spec/cli/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ License-File: NOTICE.md
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
20
+ Dynamic: license-file
21
+
22
+ # JEP CLI — JEP Core 0.7
23
+
24
+ Command-line client for creating and verifying current JEP Core 0.7 events
25
+ through the JEP API.
26
+
27
+ Default endpoints:
28
+
29
+ ```text
30
+ POST /v0.7/events/create
31
+ POST /v0.7/events/verify
32
+ GET /health
33
+ ```
34
+
35
+ Historical pre-0.7 handling is explicit through `--legacy`; the CLI never
36
+ retries a failed 0.7 event with a legacy decoder.
37
+
38
+ ## Status
39
+
40
+ Experimental reference client. It does not define Core semantics or determine
41
+ truth, authorization validity, legal effect, causality, or policy outcome.
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install jep-cli
47
+ ```
48
+
49
+ ## Configuration
50
+
51
+ ```bash
52
+ export JEP_API_URL=http://127.0.0.1:8000
53
+ export JEP_API_KEY=
54
+ ```
55
+
56
+ ## Create
57
+
58
+ Judgment:
59
+
60
+ ```bash
61
+ jep create \
62
+ --verb J \
63
+ --who did:example:agent-789 \
64
+ --what '{"claim":"approve","subject":"demo"}'
65
+ ```
66
+
67
+ Delegation:
68
+
69
+ ```bash
70
+ jep create \
71
+ --verb D \
72
+ --who did:example:principal \
73
+ --what '{"delegatee":"did:example:agent","scope":{"actions":["read"]}}'
74
+ ```
75
+
76
+ Termination and Verification require `--ref`. Pass a typed reference as
77
+ JSON when the target is another JEP event.
78
+
79
+ ## Verify
80
+
81
+ ```bash
82
+ jep verify event.json --mode archival
83
+ ```
84
+
85
+ 0.7 validation returns `status` plus independent `checks`, not a cumulative
86
+ Validation Level.
87
+
88
+ ## Explicit legacy verification
89
+
90
+ ```bash
91
+ jep verify old-event.json \
92
+ --legacy \
93
+ --legacy-format json-sorted-v1
94
+ ```
95
+
96
+ Legacy selection must come from known artifact context. Do not use a failed 0.7
97
+ validation as evidence that an event should be treated as 0.6.
98
+
99
+ ## JEP Core 0.7 model
100
+
101
+ - Event Identity is `(who,id)`.
102
+ - Event Hash identifies an exact signed artifact.
103
+ - Core does not require a top-level nonce.
104
+ - D requires `delegatee + scope`.
105
+ - T requires target `ref + termination_scope`.
106
+ - V requires target `ref + verification_scope + result`.
107
+ - chain and policy semantics remain outside Core.
108
+
109
+ ## Related repositories
110
+
111
+ - JEP Core: https://github.com/hjs-spec/jep-core
112
+ - JEP API: https://github.com/hjs-spec/jep-api
113
+ - Python SDK: https://github.com/hjs-spec/sdk-py
114
+ - JavaScript SDK: https://github.com/hjs-spec/sdk-js
115
+ - Go SDK: https://github.com/hjs-spec/sdk-go
116
+
117
+ ## Public draft
118
+
119
+ - https://datatracker.ietf.org/doc/draft-wang-jep-judgment-event-protocol/
120
+
121
+ ## License
122
+
123
+ MIT
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jep-cli"
7
- version = "0.6.1"
8
- description = "Command-line tool for creating and verifying JEP v0.6 events through the JEP API"
7
+ version = "0.7.1"
8
+ description = "Command-line client for JEP Core 0.7 with explicit legacy compatibility"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
11
11
  authors = [
@@ -0,0 +1,40 @@
1
+ from jep_cli import main as module
2
+
3
+
4
+ def test_acceptance_does_not_require_core_audience(monkeypatch, capsys):
5
+ class FakeClient:
6
+ def verify_event(self, payload):
7
+ assert payload["mode"] == "acceptance"
8
+ assert "expected_audience" not in payload
9
+ return {
10
+ "status": "valid",
11
+ "mode": "acceptance",
12
+ "profile": "jep-core-0.7",
13
+ "checks": {"syntax": "pass", "cryptographic": "pass", "event_identity": "pass"},
14
+ "acceptance": {"outcome": "accepted", "effect_applied": True},
15
+ }
16
+
17
+ monkeypatch.setattr(module, "build_client", lambda args: FakeClient())
18
+ code = module.main([
19
+ "verify",
20
+ '{"jep":"1","id":"urn:uuid:x","verb":"J","who":"a","when":1,"what":{"claim":"x"},"sig":"s"}',
21
+ "--mode", "acceptance",
22
+ ])
23
+ assert code == 0
24
+ assert '"status": "valid"' in capsys.readouterr().out
25
+
26
+
27
+ def test_failure_and_indeterminate_return_nonzero(monkeypatch):
28
+ for status in ("invalid", "indeterminate"):
29
+ class Client:
30
+ def verify_event(self, payload):
31
+ assert payload["expected_audience"] == "receiver"
32
+ return {"status": status}
33
+ monkeypatch.setattr(module, "build_client", lambda args: Client())
34
+ assert module.main(["verify", '{}', "--mode", "acceptance", "--expected-audience", "receiver"]) == 2
35
+
36
+
37
+ def test_large_inline_event_is_not_treated_as_a_filename():
38
+ import json
39
+ event = {"what": {"claim": "x" * 4096}}
40
+ assert module.parse_json_value(json.dumps(event)) == event
@@ -1,4 +1,4 @@
1
- """Tests for JEP CLI v0.6."""
1
+ """Tests for the JEP Core 0.7 CLI."""
2
2
 
3
3
  import json
4
4
  import threading
@@ -20,52 +20,64 @@ class Handler(BaseHTTPRequestHandler):
20
20
 
21
21
  def do_GET(self):
22
22
  if self.path == "/health":
23
- self._json(200, {"ok": True, "profile": "jep-core-0.6"})
23
+ self._json(200, {"ok": True, "profile": "jep-core-0.7"})
24
24
  else:
25
25
  self._json(404, {"message": "not found"})
26
26
 
27
27
  def do_POST(self):
28
28
  length = int(self.headers.get("content-length", "0"))
29
29
  payload = json.loads(self.rfile.read(length) or b"{}")
30
- if self.path == "/events/create":
30
+ if self.path == "/v0.7/events/create":
31
31
  event = {
32
32
  "jep": "1",
33
+ "id": "urn:uuid:11111111-1111-4111-8111-111111111111",
33
34
  "verb": payload["verb"],
34
35
  "who": payload.get("who", "did:example:agent"),
35
36
  "when": 1234567890,
36
37
  "what": payload.get("what"),
37
- "nonce": "nonce-1",
38
- "aud": payload.get("aud"),
39
- "ref": payload.get("ref"),
40
- "ext": payload.get("ext"),
41
- "ext_crit": payload.get("ext_crit"),
42
38
  "sig": "header..sig",
43
39
  }
40
+ for name in ("aud", "ref", "ext", "ext_crit"):
41
+ if payload.get(name) is not None:
42
+ event[name] = payload[name]
44
43
  self._json(200, {
45
44
  "event": event,
46
45
  "event_hash": "sha256:abc",
47
46
  "validation": {
48
- "valid": True,
49
- "level": 1,
47
+ "status": "valid",
50
48
  "mode": "archival",
51
- "profile": "jep-core-0.6",
49
+ "profile": "jep-core-0.7",
50
+ "event_identity": {"who": event["who"], "id": event["id"]},
52
51
  "event_hash": "sha256:abc",
52
+ "checks": {
53
+ "syntax": "pass",
54
+ "cryptographic": "pass",
55
+ "event_identity": "pass",
56
+ },
53
57
  "warnings": [],
54
58
  "errors": [],
55
59
  }
56
60
  })
57
61
  return
58
- if self.path == "/events/verify":
62
+ if self.path == "/v0.7/events/verify":
63
+ event = payload["event"]
59
64
  self._json(200, {
60
- "valid": True,
61
- "level": 1,
65
+ "status": "valid",
62
66
  "mode": payload.get("mode", "archival"),
63
- "profile": "jep-core-0.6",
67
+ "profile": "jep-core-0.7",
68
+ "event_identity": {"who": event["who"], "id": event["id"]},
64
69
  "event_hash": "sha256:def",
70
+ "checks": {"syntax": "pass", "cryptographic": "pass", "event_identity": "pass"},
65
71
  "warnings": [],
66
72
  "errors": [],
67
73
  })
68
74
  return
75
+ if self.path == "/events/create":
76
+ self._json(200, {"event": {"jep": "1", "verb": payload["verb"], "nonce": "legacy"}, "event_hash": "sha256:legacy"})
77
+ return
78
+ if self.path == "/events/verify-legacy":
79
+ self._json(200, {"valid": True, "format": payload["format"], "errors": []})
80
+ return
69
81
  self._json(404, {"message": "not found"})
70
82
 
71
83
  def log_message(self, *args):
@@ -105,7 +117,7 @@ def test_health(api_server, capsys):
105
117
  assert '"ok": true' in out
106
118
 
107
119
 
108
- def test_create(api_server, capsys):
120
+ def test_create_07(api_server, capsys):
109
121
  code = main([
110
122
  "--base-url", api_server,
111
123
  "create",
@@ -113,23 +125,22 @@ def test_create(api_server, capsys):
113
125
  "--who", "did:example:agent",
114
126
  "--what", '{"claim":"approve"}',
115
127
  "--ext", 'https://example.org/profile={"name":"demo"}',
116
- "--ext-crit", "https://example.org/profile",
117
128
  ])
118
129
  out = json.loads(capsys.readouterr().out)
119
130
  assert code == 0
120
131
  assert out["event_hash"] == "sha256:abc"
121
- assert out["event"]["verb"] == "J"
122
- assert out["event"]["ext"]["https://example.org/profile"]["name"] == "demo"
132
+ assert out["event"]["id"].startswith("urn:uuid:")
133
+ assert "nonce" not in out["event"]
123
134
 
124
135
 
125
- def test_verify(api_server, capsys, tmp_path):
136
+ def test_verify_07(api_server, capsys, tmp_path):
126
137
  event = {
127
138
  "jep": "1",
139
+ "id": "urn:uuid:11111111-1111-4111-8111-111111111111",
128
140
  "verb": "J",
129
141
  "who": "did:example:agent",
130
142
  "when": 123,
131
- "what": "sha256:abc",
132
- "nonce": "nonce-1",
143
+ "what": {"claim": "approve"},
133
144
  "sig": "header..sig",
134
145
  }
135
146
  p = tmp_path / "event.json"
@@ -137,6 +148,17 @@ def test_verify(api_server, capsys, tmp_path):
137
148
  code = main(["--base-url", api_server, "verify", str(p)])
138
149
  out = json.loads(capsys.readouterr().out)
139
150
  assert code == 0
151
+ assert out["status"] == "valid"
152
+ assert out["profile"] == "jep-core-0.7"
153
+
154
+
155
+ def test_legacy_is_explicit(api_server, capsys, tmp_path):
156
+ event = {"jep": "1", "verb": "J", "who": "legacy", "nonce": "n", "sig": "x"}
157
+ p = tmp_path / "legacy.json"
158
+ p.write_text(json.dumps(event))
159
+ code = main(["--base-url", api_server, "verify", str(p), "--legacy", "--legacy-format", "json-sorted-v1"])
160
+ out = json.loads(capsys.readouterr().out)
161
+ assert code == 0
140
162
  assert out["valid"] is True
141
163
 
142
164
 
jep_cli-0.6.1/PKG-INFO DELETED
@@ -1,141 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: jep-cli
3
- Version: 0.6.1
4
- Summary: Command-line tool for creating and verifying JEP v0.6 events through the JEP API
5
- Author-email: HJS Spec <signal@humanjudgment.org>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/hjs-spec/cli
8
- Project-URL: Repository, https://github.com/hjs-spec/cli
9
- Project-URL: Issues, https://github.com/hjs-spec/cli/issues
10
- Classifier: Development Status :: 3 - Alpha
11
- Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: MIT License
13
- Classifier: Programming Language :: Python :: 3
14
- Requires-Python: >=3.9
15
- Description-Content-Type: text/markdown
16
- License-File: LICENSE
17
- License-File: NOTICE.md
18
- Provides-Extra: dev
19
- Requires-Dist: pytest>=7.0.0; extra == "dev"
20
- Dynamic: license-file
21
-
22
- # JEP CLI v0.6
23
-
24
- Command-line tool for creating and verifying JEP v0.6 events through the JEP API.
25
-
26
- This CLI targets:
27
-
28
- ```text
29
- POST /events/create
30
- POST /events/verify
31
- GET /health
32
- ```
33
-
34
- It is aligned with:
35
-
36
- - `draft-wang-jep-judgment-event-protocol-06`
37
- - `draft-wang-jep-profiles-00`
38
- - `draft-wang-jep-conformance-00`
39
- - `hjs-spec/jep-api`
40
-
41
- ## Status
42
-
43
- Experimental implementation seed.
44
-
45
- This CLI does not define new JEP-Core semantics and does not determine legal liability, factual truth, regulatory compliance, or complete-log availability.
46
-
47
- ## Installation
48
-
49
- ```bash
50
- pip install -e ".[dev]"
51
- ```
52
-
53
- ## Configuration
54
-
55
- Use flags:
56
-
57
- ```bash
58
- jep --base-url http://127.0.0.1:8000 health
59
- ```
60
-
61
- Or environment variables:
62
-
63
- ```bash
64
- export JEP_API_URL=http://127.0.0.1:8000
65
- export JEP_API_KEY=
66
- ```
67
-
68
- ## Commands
69
-
70
- ### Health
71
-
72
- ```bash
73
- jep health
74
- ```
75
-
76
- ### Create a Judgment event
77
-
78
- ```bash
79
- jep create \
80
- --verb J \
81
- --who did:example:agent-789 \
82
- --what '{"claim":"approve","subject":"demo"}' \
83
- --aud https://api.example.org
84
- ```
85
-
86
- ### Create with extensions
87
-
88
- ```bash
89
- jep create \
90
- --verb J \
91
- --who did:example:agent-789 \
92
- --what '{"claim":"approve"}' \
93
- --ext 'https://example.org/profile={"name":"demo"}' \
94
- --ext-crit https://example.org/profile
95
- ```
96
-
97
- ### Verify an event from a file
98
-
99
- ```bash
100
- jep verify event.json --mode archival
101
- ```
102
-
103
- ### Pipe create response into verify
104
-
105
- ```bash
106
- jep create --verb J --who did:example:agent --what '{"claim":"approve"}' > response.json
107
- jep extract-event response.json > event.json
108
- jep verify event.json
109
- ```
110
-
111
- ## Input Rules
112
-
113
- `--what` and event arguments may be:
114
-
115
- - inline JSON;
116
- - a plain string;
117
- - a file path;
118
- - `-` for stdin.
119
-
120
- ## Related Repositories
121
-
122
- - JEP v0.6: https://github.com/hjs-spec/jep-v06
123
- - JEP API v0.6: https://github.com/hjs-spec/jep-api
124
- - JEP Python SDK v0.6: https://github.com/hjs-spec/jep-sdk-py
125
- - JEP Go SDK v0.6: https://github.com/hjs-spec/jep-sdk-go
126
- - HJS v0.5: https://github.com/hjs-spec/hjs-05
127
- - JAC v0.5: https://github.com/hjs-spec/jac-agent-02
128
-
129
- ## Public Drafts
130
-
131
- - JEP-Core: https://datatracker.ietf.org/doc/draft-wang-jep-judgment-event-protocol/
132
- - JEP-Profiles: https://datatracker.ietf.org/doc/draft-wang-jep-profiles/
133
- - JEP-Conformance: https://datatracker.ietf.org/doc/draft-wang-jep-conformance/
134
-
135
- ## License
136
-
137
- MIT
138
-
139
- ## Runtime and verification notes
140
-
141
- See [HARDENING.md](HARDENING.md) for supported behavior, regression checks, and compatibility boundaries.
jep_cli-0.6.1/README.md DELETED
@@ -1,120 +0,0 @@
1
- # JEP CLI v0.6
2
-
3
- Command-line tool for creating and verifying JEP v0.6 events through the JEP API.
4
-
5
- This CLI targets:
6
-
7
- ```text
8
- POST /events/create
9
- POST /events/verify
10
- GET /health
11
- ```
12
-
13
- It is aligned with:
14
-
15
- - `draft-wang-jep-judgment-event-protocol-06`
16
- - `draft-wang-jep-profiles-00`
17
- - `draft-wang-jep-conformance-00`
18
- - `hjs-spec/jep-api`
19
-
20
- ## Status
21
-
22
- Experimental implementation seed.
23
-
24
- This CLI does not define new JEP-Core semantics and does not determine legal liability, factual truth, regulatory compliance, or complete-log availability.
25
-
26
- ## Installation
27
-
28
- ```bash
29
- pip install -e ".[dev]"
30
- ```
31
-
32
- ## Configuration
33
-
34
- Use flags:
35
-
36
- ```bash
37
- jep --base-url http://127.0.0.1:8000 health
38
- ```
39
-
40
- Or environment variables:
41
-
42
- ```bash
43
- export JEP_API_URL=http://127.0.0.1:8000
44
- export JEP_API_KEY=
45
- ```
46
-
47
- ## Commands
48
-
49
- ### Health
50
-
51
- ```bash
52
- jep health
53
- ```
54
-
55
- ### Create a Judgment event
56
-
57
- ```bash
58
- jep create \
59
- --verb J \
60
- --who did:example:agent-789 \
61
- --what '{"claim":"approve","subject":"demo"}' \
62
- --aud https://api.example.org
63
- ```
64
-
65
- ### Create with extensions
66
-
67
- ```bash
68
- jep create \
69
- --verb J \
70
- --who did:example:agent-789 \
71
- --what '{"claim":"approve"}' \
72
- --ext 'https://example.org/profile={"name":"demo"}' \
73
- --ext-crit https://example.org/profile
74
- ```
75
-
76
- ### Verify an event from a file
77
-
78
- ```bash
79
- jep verify event.json --mode archival
80
- ```
81
-
82
- ### Pipe create response into verify
83
-
84
- ```bash
85
- jep create --verb J --who did:example:agent --what '{"claim":"approve"}' > response.json
86
- jep extract-event response.json > event.json
87
- jep verify event.json
88
- ```
89
-
90
- ## Input Rules
91
-
92
- `--what` and event arguments may be:
93
-
94
- - inline JSON;
95
- - a plain string;
96
- - a file path;
97
- - `-` for stdin.
98
-
99
- ## Related Repositories
100
-
101
- - JEP v0.6: https://github.com/hjs-spec/jep-v06
102
- - JEP API v0.6: https://github.com/hjs-spec/jep-api
103
- - JEP Python SDK v0.6: https://github.com/hjs-spec/jep-sdk-py
104
- - JEP Go SDK v0.6: https://github.com/hjs-spec/jep-sdk-go
105
- - HJS v0.5: https://github.com/hjs-spec/hjs-05
106
- - JAC v0.5: https://github.com/hjs-spec/jac-agent-02
107
-
108
- ## Public Drafts
109
-
110
- - JEP-Core: https://datatracker.ietf.org/doc/draft-wang-jep-judgment-event-protocol/
111
- - JEP-Profiles: https://datatracker.ietf.org/doc/draft-wang-jep-profiles/
112
- - JEP-Conformance: https://datatracker.ietf.org/doc/draft-wang-jep-conformance/
113
-
114
- ## License
115
-
116
- MIT
117
-
118
- ## Runtime and verification notes
119
-
120
- See [HARDENING.md](HARDENING.md) for supported behavior, regression checks, and compatibility boundaries.
@@ -1,3 +0,0 @@
1
- """JEP CLI v0.6."""
2
-
3
- __version__ = "0.6.0"
@@ -1,141 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: jep-cli
3
- Version: 0.6.1
4
- Summary: Command-line tool for creating and verifying JEP v0.6 events through the JEP API
5
- Author-email: HJS Spec <signal@humanjudgment.org>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/hjs-spec/cli
8
- Project-URL: Repository, https://github.com/hjs-spec/cli
9
- Project-URL: Issues, https://github.com/hjs-spec/cli/issues
10
- Classifier: Development Status :: 3 - Alpha
11
- Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: MIT License
13
- Classifier: Programming Language :: Python :: 3
14
- Requires-Python: >=3.9
15
- Description-Content-Type: text/markdown
16
- License-File: LICENSE
17
- License-File: NOTICE.md
18
- Provides-Extra: dev
19
- Requires-Dist: pytest>=7.0.0; extra == "dev"
20
- Dynamic: license-file
21
-
22
- # JEP CLI v0.6
23
-
24
- Command-line tool for creating and verifying JEP v0.6 events through the JEP API.
25
-
26
- This CLI targets:
27
-
28
- ```text
29
- POST /events/create
30
- POST /events/verify
31
- GET /health
32
- ```
33
-
34
- It is aligned with:
35
-
36
- - `draft-wang-jep-judgment-event-protocol-06`
37
- - `draft-wang-jep-profiles-00`
38
- - `draft-wang-jep-conformance-00`
39
- - `hjs-spec/jep-api`
40
-
41
- ## Status
42
-
43
- Experimental implementation seed.
44
-
45
- This CLI does not define new JEP-Core semantics and does not determine legal liability, factual truth, regulatory compliance, or complete-log availability.
46
-
47
- ## Installation
48
-
49
- ```bash
50
- pip install -e ".[dev]"
51
- ```
52
-
53
- ## Configuration
54
-
55
- Use flags:
56
-
57
- ```bash
58
- jep --base-url http://127.0.0.1:8000 health
59
- ```
60
-
61
- Or environment variables:
62
-
63
- ```bash
64
- export JEP_API_URL=http://127.0.0.1:8000
65
- export JEP_API_KEY=
66
- ```
67
-
68
- ## Commands
69
-
70
- ### Health
71
-
72
- ```bash
73
- jep health
74
- ```
75
-
76
- ### Create a Judgment event
77
-
78
- ```bash
79
- jep create \
80
- --verb J \
81
- --who did:example:agent-789 \
82
- --what '{"claim":"approve","subject":"demo"}' \
83
- --aud https://api.example.org
84
- ```
85
-
86
- ### Create with extensions
87
-
88
- ```bash
89
- jep create \
90
- --verb J \
91
- --who did:example:agent-789 \
92
- --what '{"claim":"approve"}' \
93
- --ext 'https://example.org/profile={"name":"demo"}' \
94
- --ext-crit https://example.org/profile
95
- ```
96
-
97
- ### Verify an event from a file
98
-
99
- ```bash
100
- jep verify event.json --mode archival
101
- ```
102
-
103
- ### Pipe create response into verify
104
-
105
- ```bash
106
- jep create --verb J --who did:example:agent --what '{"claim":"approve"}' > response.json
107
- jep extract-event response.json > event.json
108
- jep verify event.json
109
- ```
110
-
111
- ## Input Rules
112
-
113
- `--what` and event arguments may be:
114
-
115
- - inline JSON;
116
- - a plain string;
117
- - a file path;
118
- - `-` for stdin.
119
-
120
- ## Related Repositories
121
-
122
- - JEP v0.6: https://github.com/hjs-spec/jep-v06
123
- - JEP API v0.6: https://github.com/hjs-spec/jep-api
124
- - JEP Python SDK v0.6: https://github.com/hjs-spec/jep-sdk-py
125
- - JEP Go SDK v0.6: https://github.com/hjs-spec/jep-sdk-go
126
- - HJS v0.5: https://github.com/hjs-spec/hjs-05
127
- - JAC v0.5: https://github.com/hjs-spec/jac-agent-02
128
-
129
- ## Public Drafts
130
-
131
- - JEP-Core: https://datatracker.ietf.org/doc/draft-wang-jep-judgment-event-protocol/
132
- - JEP-Profiles: https://datatracker.ietf.org/doc/draft-wang-jep-profiles/
133
- - JEP-Conformance: https://datatracker.ietf.org/doc/draft-wang-jep-conformance/
134
-
135
- ## License
136
-
137
- MIT
138
-
139
- ## Runtime and verification notes
140
-
141
- See [HARDENING.md](HARDENING.md) for supported behavior, regression checks, and compatibility boundaries.
@@ -1,16 +0,0 @@
1
- import json
2
- from jep_cli import main as module
3
-
4
-
5
- def test_acceptance_requires_expected_audience(capsys):
6
- assert module.main(["verify", '{"jep":"1"}', "--mode", "acceptance"]) == 1
7
- assert "expected-audience" in capsys.readouterr().err
8
-
9
-
10
- def test_verification_failure_returns_nonzero(monkeypatch):
11
- class Client:
12
- def verify_event(self, payload):
13
- assert payload["expected_audience"] == "receiver"
14
- return {"valid": False}
15
- monkeypatch.setattr(module, "build_client", lambda args: Client())
16
- assert module.main(["verify", '{}', "--mode", "acceptance", "--expected-audience", "receiver"]) == 2
File without changes
File without changes
File without changes