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 +123 -0
- jep_cli-0.7.1/README.md +102 -0
- jep_cli-0.7.1/jep_cli/__init__.py +3 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/jep_cli/client.py +11 -5
- {jep_cli-0.6.1 → jep_cli-0.7.1}/jep_cli/main.py +32 -20
- jep_cli-0.7.1/jep_cli.egg-info/PKG-INFO +123 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/pyproject.toml +2 -2
- jep_cli-0.7.1/tests/test_acceptance.py +40 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/tests/test_cli.py +44 -22
- jep_cli-0.6.1/PKG-INFO +0 -141
- jep_cli-0.6.1/README.md +0 -120
- jep_cli-0.6.1/jep_cli/__init__.py +0 -3
- jep_cli-0.6.1/jep_cli.egg-info/PKG-INFO +0 -141
- jep_cli-0.6.1/tests/test_acceptance.py +0 -16
- {jep_cli-0.6.1 → jep_cli-0.7.1}/LICENSE +0 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/NOTICE.md +0 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/jep_cli.egg-info/SOURCES.txt +0 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/jep_cli.egg-info/dependency_links.txt +0 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/jep_cli.egg-info/entry_points.txt +0 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/jep_cli.egg-info/requires.txt +0 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/jep_cli.egg-info/top_level.txt +0 -0
- {jep_cli-0.6.1 → jep_cli-0.7.1}/setup.cfg +0 -0
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
|
jep_cli-0.7.1/README.md
ADDED
|
@@ -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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Small HTTP client for JEP
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
"
|
|
87
|
-
|
|
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.
|
|
92
|
-
|
|
93
|
-
result =
|
|
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("
|
|
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
|
|
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
|
|
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="
|
|
139
|
-
verify.add_argument("--
|
|
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.
|
|
8
|
-
description = "Command-line
|
|
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
|
|
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.
|
|
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
|
-
"
|
|
49
|
-
"level": 1,
|
|
47
|
+
"status": "valid",
|
|
50
48
|
"mode": "archival",
|
|
51
|
-
"profile": "jep-core-0.
|
|
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
|
-
"
|
|
61
|
-
"level": 1,
|
|
65
|
+
"status": "valid",
|
|
62
66
|
"mode": payload.get("mode", "archival"),
|
|
63
|
-
"profile": "jep-core-0.
|
|
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
|
|
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"]["
|
|
122
|
-
assert out["event"]
|
|
132
|
+
assert out["event"]["id"].startswith("urn:uuid:")
|
|
133
|
+
assert "nonce" not in out["event"]
|
|
123
134
|
|
|
124
135
|
|
|
125
|
-
def
|
|
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": "
|
|
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,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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|