witnora 0.10.0 → 0.10.2
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.
- package/README.md +54 -9
- package/dist/assurance-contract.js +312 -0
- package/dist/assurance-loop-demo.js +245 -0
- package/dist/authorization-state-machine.js +35 -0
- package/dist/authorization-v02.js +60 -0
- package/dist/canonical-v02.js +197 -0
- package/dist/canonical.js +31 -0
- package/dist/cli.js +118 -0
- package/dist/command-help.js +76 -0
- package/dist/control-plane.js +3 -3
- package/dist/credentials.js +1 -1
- package/dist/design-partner-pilot.js +402 -0
- package/dist/design-partner-v02.js +449 -0
- package/dist/evidence-v02.js +118 -0
- package/dist/generic-eval.js +160 -0
- package/dist/github-design-partner-v02.js +399 -0
- package/dist/github-live-v02.js +45 -0
- package/dist/guided-setup.js +1 -1
- package/dist/index.js +1 -0
- package/dist/offline-verifier.js +375 -0
- package/dist/onboard.js +132 -0
- package/dist/onboarding-templates.js +3 -3
- package/dist/outcome-evaluator.js +51 -0
- package/dist/privacy-manifest.js +273 -0
- package/dist/probe-protocol-v02.js +101 -0
- package/dist/sandbox.js +1 -1
- package/dist/trust-v02.js +111 -0
- package/dist/try.js +1 -1
- package/dist/vendor/design-partner/failure-exercises.mjs +353 -0
- package/dist/vendor/onegent-runtime/browser-enforcement-runtime.d.ts +8 -0
- package/dist/vendor/onegent-runtime/browser-enforcement-runtime.d.ts.map +1 -1
- package/dist/vendor/onegent-runtime/browser-enforcement-runtime.js +43 -1
- package/dist/vendor/witnora-probe/canonical.d.ts +3 -0
- package/dist/vendor/witnora-probe/canonical.js +39 -0
- package/dist/vendor/witnora-probe/cli.d.ts +2 -0
- package/dist/vendor/witnora-probe/cli.js +36 -0
- package/dist/vendor/witnora-probe/config.d.ts +2 -0
- package/dist/vendor/witnora-probe/config.js +63 -0
- package/dist/vendor/witnora-probe/credential-resolver.d.ts +6 -0
- package/dist/vendor/witnora-probe/credential-resolver.js +17 -0
- package/dist/vendor/witnora-probe/crypto.d.ts +2 -0
- package/dist/vendor/witnora-probe/crypto.js +14 -0
- package/dist/vendor/witnora-probe/emulator.d.ts +51 -0
- package/dist/vendor/witnora-probe/emulator.js +164 -0
- package/dist/vendor/witnora-probe/index.d.ts +11 -0
- package/dist/vendor/witnora-probe/index.js +11 -0
- package/dist/vendor/witnora-probe/logger.d.ts +3 -0
- package/dist/vendor/witnora-probe/logger.js +26 -0
- package/dist/vendor/witnora-probe/metrics.d.ts +12 -0
- package/dist/vendor/witnora-probe/metrics.js +31 -0
- package/dist/vendor/witnora-probe/probe.d.ts +22 -0
- package/dist/vendor/witnora-probe/probe.js +208 -0
- package/dist/vendor/witnora-probe/request-verifier.d.ts +9 -0
- package/dist/vendor/witnora-probe/request-verifier.js +84 -0
- package/dist/vendor/witnora-probe/server.d.ts +9 -0
- package/dist/vendor/witnora-probe/server.js +85 -0
- package/dist/vendor/witnora-probe/storage.d.ts +16 -0
- package/dist/vendor/witnora-probe/storage.js +114 -0
- package/dist/vendor/witnora-probe/types.d.ts +126 -0
- package/dist/vendor/witnora-probe/types.js +2 -0
- package/dist/vendor/witnora-verifier-python/README.md +43 -0
- package/dist/vendor/witnora-verifier-python/pyproject.toml +23 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/__init__.py +33 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/canonical.py +218 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/cli.py +75 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/conformance.py +124 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/crypto.py +139 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/errors.py +15 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/event_chain.py +80 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/evidence.py +336 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/probe.py +188 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/producer.py +127 -0
- package/dist/vendor/witnora-verifier-python/src/witnora_verifier/trust.py +337 -0
- package/package.json +4 -4
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import re
|
|
5
|
+
from collections.abc import Iterable, Mapping
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from datetime import UTC, datetime
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from cryptography.hazmat.primitives import serialization
|
|
11
|
+
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
|
|
12
|
+
|
|
13
|
+
from .canonical import sha256_canonical
|
|
14
|
+
from .crypto import verify_document_signature
|
|
15
|
+
from .errors import VerificationError, require
|
|
16
|
+
|
|
17
|
+
TRUST_ROOT_VERSION = "witnora.trust_root.v0.2"
|
|
18
|
+
KEY_CERTIFICATE_VERSION = "witnora.key_certificate.v0.2"
|
|
19
|
+
REVOCATION_STATEMENT_VERSION = "witnora.key_revocation_statement.v0.2"
|
|
20
|
+
REVOCATION_JOURNAL_VERSION = "witnora.revocation_journal.v0.2"
|
|
21
|
+
|
|
22
|
+
CERTIFIED_ROLES = {
|
|
23
|
+
"source_collector",
|
|
24
|
+
"gateway_runtime",
|
|
25
|
+
"outcome_probe",
|
|
26
|
+
"resource_scope_evaluator",
|
|
27
|
+
"server_attestor",
|
|
28
|
+
"reviewer",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class PinnedTrustStore:
|
|
34
|
+
"""Caller-owned roots. Packet-carried roots are intentionally not accepted."""
|
|
35
|
+
|
|
36
|
+
roots: Mapping[str, Mapping[str, Any]]
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def from_roots(cls, roots: Iterable[Mapping[str, Any]]) -> PinnedTrustStore:
|
|
40
|
+
indexed: dict[str, Mapping[str, Any]] = {}
|
|
41
|
+
for root in roots:
|
|
42
|
+
_verify_root_shape(root)
|
|
43
|
+
root_id = str(root["rootId"])
|
|
44
|
+
require(
|
|
45
|
+
root_id not in indexed,
|
|
46
|
+
"DUPLICATE_ROOT_ID",
|
|
47
|
+
f"Root {root_id} appears more than once.",
|
|
48
|
+
)
|
|
49
|
+
indexed[root_id] = dict(root)
|
|
50
|
+
require(
|
|
51
|
+
bool(indexed),
|
|
52
|
+
"PINNED_ROOT_REQUIRED",
|
|
53
|
+
"At least one out-of-band pinned root is required.",
|
|
54
|
+
)
|
|
55
|
+
return cls(indexed)
|
|
56
|
+
|
|
57
|
+
def get(self, root_id: str) -> Mapping[str, Any]:
|
|
58
|
+
root = self.roots.get(root_id)
|
|
59
|
+
require(
|
|
60
|
+
root is not None,
|
|
61
|
+
"UNPINNED_ROOT",
|
|
62
|
+
f"Root {root_id} is not pinned by the verifier caller.",
|
|
63
|
+
)
|
|
64
|
+
return root
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def parse_timestamp(value: Any, field: str) -> datetime:
|
|
68
|
+
require(
|
|
69
|
+
isinstance(value, str), "INVALID_TIMESTAMP", f"{field} must be an RFC 3339 UTC timestamp."
|
|
70
|
+
)
|
|
71
|
+
require(
|
|
72
|
+
bool(re.fullmatch(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?Z", value)),
|
|
73
|
+
"INVALID_TIMESTAMP",
|
|
74
|
+
f"{field} must use UTC Z notation with at most millisecond precision.",
|
|
75
|
+
)
|
|
76
|
+
try:
|
|
77
|
+
parsed = datetime.fromisoformat(value[:-1] + "+00:00")
|
|
78
|
+
except ValueError as exc:
|
|
79
|
+
raise VerificationError("INVALID_TIMESTAMP", f"{field} is not a real timestamp.") from exc
|
|
80
|
+
return parsed.astimezone(UTC)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def root_fingerprint(public_key_pem: str) -> str:
|
|
84
|
+
key = _load_ed25519_public_key(public_key_pem)
|
|
85
|
+
der = key.public_bytes(
|
|
86
|
+
serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo
|
|
87
|
+
)
|
|
88
|
+
return hashlib.sha256(der).hexdigest()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def verify_key_certificate(
|
|
92
|
+
certificate: Mapping[str, Any],
|
|
93
|
+
trust_store: PinnedTrustStore,
|
|
94
|
+
*,
|
|
95
|
+
expected_role: str,
|
|
96
|
+
tenant_ref: str,
|
|
97
|
+
project_ref: str,
|
|
98
|
+
environment: str,
|
|
99
|
+
at: datetime | str,
|
|
100
|
+
revocation_journal: Mapping[str, Any] | None = None,
|
|
101
|
+
) -> Mapping[str, Any]:
|
|
102
|
+
require(
|
|
103
|
+
certificate.get("protocolVersion") == KEY_CERTIFICATE_VERSION,
|
|
104
|
+
"CERTIFICATE_VERSION_UNSUPPORTED",
|
|
105
|
+
"Key certificate is not v0.2.",
|
|
106
|
+
)
|
|
107
|
+
role = str(certificate.get("role", ""))
|
|
108
|
+
require(
|
|
109
|
+
role in CERTIFIED_ROLES, "CERTIFICATE_ROLE_UNKNOWN", f"Unknown certificate role {role!r}."
|
|
110
|
+
)
|
|
111
|
+
require(
|
|
112
|
+
role == expected_role,
|
|
113
|
+
"CERTIFICATE_ROLE_MISMATCH",
|
|
114
|
+
f"Expected role {expected_role}, received {role}.",
|
|
115
|
+
)
|
|
116
|
+
root = trust_store.get(str(certificate.get("issuerRootId", "")))
|
|
117
|
+
_verify_root_shape(root)
|
|
118
|
+
require(
|
|
119
|
+
role in root.get("allowedRoles", []),
|
|
120
|
+
"ROOT_ROLE_DENIED",
|
|
121
|
+
"Pinned root does not authorize this role.",
|
|
122
|
+
)
|
|
123
|
+
require(
|
|
124
|
+
certificate.get("tenantRef") == tenant_ref
|
|
125
|
+
and certificate.get("projectRef") == project_ref
|
|
126
|
+
and certificate.get("environment") == environment,
|
|
127
|
+
"CERTIFICATE_SCOPE_MISMATCH",
|
|
128
|
+
"Certificate tenant, project, or environment scope does not match.",
|
|
129
|
+
)
|
|
130
|
+
event_at = parse_timestamp(at, "eventAt") if isinstance(at, str) else _utc(at)
|
|
131
|
+
not_before = parse_timestamp(certificate.get("notBefore"), "certificate.notBefore")
|
|
132
|
+
not_after = parse_timestamp(certificate.get("notAfter"), "certificate.notAfter")
|
|
133
|
+
require(
|
|
134
|
+
not_before <= event_at <= not_after,
|
|
135
|
+
"CERTIFICATE_INACTIVE",
|
|
136
|
+
"Certificate is outside its validity interval.",
|
|
137
|
+
)
|
|
138
|
+
root_not_before = parse_timestamp(root.get("notBefore"), "root.notBefore")
|
|
139
|
+
root_not_after = parse_timestamp(root.get("notAfter"), "root.notAfter")
|
|
140
|
+
require(
|
|
141
|
+
root_not_before <= event_at <= root_not_after,
|
|
142
|
+
"ROOT_INACTIVE",
|
|
143
|
+
"Pinned root is outside its validity interval.",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
body = {
|
|
147
|
+
key: value
|
|
148
|
+
for key, value in certificate.items()
|
|
149
|
+
if key not in {"certificateDigest", "signature"}
|
|
150
|
+
}
|
|
151
|
+
require(
|
|
152
|
+
certificate.get("certificateDigest") == sha256_canonical(body),
|
|
153
|
+
"CERTIFICATE_DIGEST_MISMATCH",
|
|
154
|
+
"Certificate digest does not match its canonical body.",
|
|
155
|
+
)
|
|
156
|
+
signed = {**body, "certificateDigest": certificate["certificateDigest"]}
|
|
157
|
+
verify_document_signature(
|
|
158
|
+
signed, str(certificate.get("signature", "")), str(root.get("publicKeyPem", ""))
|
|
159
|
+
)
|
|
160
|
+
_load_ed25519_public_key(str(certificate.get("publicKeyPem", "")))
|
|
161
|
+
|
|
162
|
+
if revocation_journal is not None:
|
|
163
|
+
verify_revocation_journal(revocation_journal, trust_store)
|
|
164
|
+
assert_not_revoked(certificate, revocation_journal, event_at)
|
|
165
|
+
return root
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def verify_revocation_journal(journal: Mapping[str, Any], trust_store: PinnedTrustStore) -> None:
|
|
169
|
+
require(
|
|
170
|
+
journal.get("protocolVersion") == REVOCATION_JOURNAL_VERSION,
|
|
171
|
+
"REVOCATION_JOURNAL_VERSION_UNSUPPORTED",
|
|
172
|
+
"Revocation journal is not v0.2.",
|
|
173
|
+
)
|
|
174
|
+
root_id = str(journal.get("rootId", ""))
|
|
175
|
+
root = trust_store.get(root_id)
|
|
176
|
+
statements = journal.get("statements")
|
|
177
|
+
require(
|
|
178
|
+
isinstance(statements, list),
|
|
179
|
+
"REVOCATION_JOURNAL_INVALID",
|
|
180
|
+
"Revocation statements must be an array.",
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
previous_checkpoint: str | None = None
|
|
184
|
+
seen_subjects: set[tuple[int, str]] = set()
|
|
185
|
+
for index, statement in enumerate(statements):
|
|
186
|
+
require(
|
|
187
|
+
isinstance(statement, dict),
|
|
188
|
+
"REVOCATION_STATEMENT_INVALID",
|
|
189
|
+
"Revocation statement must be an object.",
|
|
190
|
+
)
|
|
191
|
+
require(
|
|
192
|
+
statement.get("protocolVersion") == REVOCATION_STATEMENT_VERSION,
|
|
193
|
+
"REVOCATION_STATEMENT_VERSION_UNSUPPORTED",
|
|
194
|
+
"Revocation statement is not v0.2.",
|
|
195
|
+
)
|
|
196
|
+
require(
|
|
197
|
+
statement.get("sequence") == index + 1,
|
|
198
|
+
"REVOCATION_SEQUENCE_INVALID",
|
|
199
|
+
f"Expected revocation sequence {index + 1}.",
|
|
200
|
+
)
|
|
201
|
+
require(
|
|
202
|
+
statement.get("previousJournalDigest") == previous_checkpoint,
|
|
203
|
+
"REVOCATION_CHAIN_BROKEN",
|
|
204
|
+
"Revocation journal continuity is invalid.",
|
|
205
|
+
)
|
|
206
|
+
require(
|
|
207
|
+
statement.get("issuerRootId") == root_id,
|
|
208
|
+
"REVOCATION_ISSUER_MISMATCH",
|
|
209
|
+
"Revocation statement issuer differs from the journal root.",
|
|
210
|
+
)
|
|
211
|
+
require(
|
|
212
|
+
isinstance(statement.get("retroactive"), bool),
|
|
213
|
+
"REVOCATION_RETROACTIVE_INVALID",
|
|
214
|
+
"retroactive must be boolean.",
|
|
215
|
+
)
|
|
216
|
+
parse_timestamp(statement.get("effectiveAt"), "revocation.effectiveAt")
|
|
217
|
+
body = {
|
|
218
|
+
key: value
|
|
219
|
+
for key, value in statement.items()
|
|
220
|
+
if key not in {"statementDigest", "signature"}
|
|
221
|
+
}
|
|
222
|
+
require(
|
|
223
|
+
statement.get("statementDigest") == sha256_canonical(body),
|
|
224
|
+
"REVOCATION_DIGEST_MISMATCH",
|
|
225
|
+
"Revocation statement digest is invalid.",
|
|
226
|
+
)
|
|
227
|
+
signed = {**body, "statementDigest": statement["statementDigest"]}
|
|
228
|
+
verify_document_signature(
|
|
229
|
+
signed, str(statement.get("signature", "")), str(root.get("publicKeyPem", ""))
|
|
230
|
+
)
|
|
231
|
+
subject_key = (int(statement["sequence"]), str(statement.get("revokedId", "")))
|
|
232
|
+
require(
|
|
233
|
+
subject_key not in seen_subjects,
|
|
234
|
+
"REVOCATION_DUPLICATE_ENTRY",
|
|
235
|
+
"Duplicate revocation entry detected.",
|
|
236
|
+
)
|
|
237
|
+
seen_subjects.add(subject_key)
|
|
238
|
+
previous_checkpoint = sha256_canonical(statements[: index + 1])
|
|
239
|
+
|
|
240
|
+
expected_checkpoint = (
|
|
241
|
+
previous_checkpoint if previous_checkpoint is not None else sha256_canonical([])
|
|
242
|
+
)
|
|
243
|
+
require(
|
|
244
|
+
journal.get("checkpointDigest") == expected_checkpoint,
|
|
245
|
+
"REVOCATION_CHECKPOINT_MISMATCH",
|
|
246
|
+
"Revocation checkpoint digest is invalid.",
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def assert_not_revoked(
|
|
251
|
+
certificate: Mapping[str, Any], journal: Mapping[str, Any], event_at: datetime
|
|
252
|
+
) -> None:
|
|
253
|
+
for statement in journal.get("statements", []):
|
|
254
|
+
if statement.get("revokedId") not in {
|
|
255
|
+
certificate.get("certificateId"),
|
|
256
|
+
certificate.get("subjectKeyId"),
|
|
257
|
+
}:
|
|
258
|
+
continue
|
|
259
|
+
effective_at = parse_timestamp(statement.get("effectiveAt"), "revocation.effectiveAt")
|
|
260
|
+
if statement.get("retroactive") is True or event_at >= effective_at:
|
|
261
|
+
raise VerificationError(
|
|
262
|
+
"CERTIFICATE_REVOKED", "Certificate was revoked for the event time."
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def assert_revocation_journal_extends(
|
|
267
|
+
packet_journal: Mapping[str, Any], latest_journal: Mapping[str, Any]
|
|
268
|
+
) -> None:
|
|
269
|
+
require(
|
|
270
|
+
packet_journal.get("rootId") == latest_journal.get("rootId"),
|
|
271
|
+
"REVOCATION_ROOT_MISMATCH",
|
|
272
|
+
"Packet and latest revocation journals use different roots.",
|
|
273
|
+
)
|
|
274
|
+
packet_statements = packet_journal.get("statements")
|
|
275
|
+
latest_statements = latest_journal.get("statements")
|
|
276
|
+
require(
|
|
277
|
+
isinstance(packet_statements, list) and isinstance(latest_statements, list),
|
|
278
|
+
"REVOCATION_JOURNAL_INVALID",
|
|
279
|
+
"Revocation statements must be arrays.",
|
|
280
|
+
)
|
|
281
|
+
require(
|
|
282
|
+
len(latest_statements) >= len(packet_statements)
|
|
283
|
+
and latest_statements[: len(packet_statements)] == packet_statements,
|
|
284
|
+
"REVOCATION_ROLLBACK_DETECTED",
|
|
285
|
+
"Latest revocation journal does not extend the packet checkpoint.",
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def _verify_root_shape(root: Mapping[str, Any]) -> None:
|
|
290
|
+
require(
|
|
291
|
+
root.get("protocolVersion") == TRUST_ROOT_VERSION,
|
|
292
|
+
"ROOT_VERSION_UNSUPPORTED",
|
|
293
|
+
"Pinned root is not v0.2.",
|
|
294
|
+
)
|
|
295
|
+
require(
|
|
296
|
+
root.get("algorithm") == "Ed25519",
|
|
297
|
+
"ROOT_ALGORITHM_UNSUPPORTED",
|
|
298
|
+
"Pinned root must use Ed25519.",
|
|
299
|
+
)
|
|
300
|
+
require(
|
|
301
|
+
isinstance(root.get("rootId"), str) and bool(root["rootId"]),
|
|
302
|
+
"ROOT_ID_MISSING",
|
|
303
|
+
"Pinned root ID is required.",
|
|
304
|
+
)
|
|
305
|
+
roles = root.get("allowedRoles")
|
|
306
|
+
require(
|
|
307
|
+
isinstance(roles, list) and all(role in CERTIFIED_ROLES for role in roles),
|
|
308
|
+
"ROOT_ROLES_INVALID",
|
|
309
|
+
"Pinned root roles are invalid.",
|
|
310
|
+
)
|
|
311
|
+
fingerprint = root_fingerprint(str(root.get("publicKeyPem", "")))
|
|
312
|
+
require(
|
|
313
|
+
root.get("rootFingerprint") == fingerprint,
|
|
314
|
+
"ROOT_FINGERPRINT_MISMATCH",
|
|
315
|
+
"Pinned root fingerprint does not match its public key.",
|
|
316
|
+
)
|
|
317
|
+
not_before = parse_timestamp(root.get("notBefore"), "root.notBefore")
|
|
318
|
+
not_after = parse_timestamp(root.get("notAfter"), "root.notAfter")
|
|
319
|
+
require(
|
|
320
|
+
not_after > not_before,
|
|
321
|
+
"ROOT_VALIDITY_INVALID",
|
|
322
|
+
"Pinned root validity interval is invalid.",
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def _load_ed25519_public_key(public_key_pem: str) -> Ed25519PublicKey:
|
|
327
|
+
try:
|
|
328
|
+
key = serialization.load_pem_public_key(public_key_pem.encode("ascii"))
|
|
329
|
+
except (ValueError, TypeError, UnicodeError) as exc:
|
|
330
|
+
raise VerificationError("INVALID_PUBLIC_KEY", "Public key PEM is invalid.") from exc
|
|
331
|
+
require(isinstance(key, Ed25519PublicKey), "INVALID_PUBLIC_KEY", "Public key must be Ed25519.")
|
|
332
|
+
return key
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def _utc(value: datetime) -> datetime:
|
|
336
|
+
require(value.tzinfo is not None, "INVALID_TIMESTAMP", "Datetime must be timezone-aware.")
|
|
337
|
+
return value.astimezone(UTC)
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "witnora",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "Independent assurance for covered agent action paths across models and frameworks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"homepage": "https://witnora.com/",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/Kakarottoooo/
|
|
10
|
+
"url": "git+https://github.com/Kakarottoooo/witnora.git",
|
|
11
11
|
"directory": "packages/witnora-cli"
|
|
12
12
|
},
|
|
13
13
|
"bugs": {
|
|
14
|
-
"url": "https://github.com/Kakarottoooo/
|
|
14
|
+
"url": "https://github.com/Kakarottoooo/witnora/issues"
|
|
15
15
|
},
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"package.json"
|
|
52
52
|
],
|
|
53
53
|
"scripts": {
|
|
54
|
-
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json && tsc -p tsconfig.onegent-vendor.json && tsc -p tsconfig.sdk-vendor.json",
|
|
54
|
+
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json && tsc -p tsconfig.onegent-vendor.json && tsc -p tsconfig.sdk-vendor.json && tsc -p tsconfig.probe-vendor.json && node scripts/vendor-design-partner-assets.mjs",
|
|
55
55
|
"prepack": "npm run build",
|
|
56
56
|
"test": "vitest run tests",
|
|
57
57
|
"demo:report": "node dist/cli.js report --mcpbench ../../examples/reports/passing/results.json --out .witnora/demo --subject demo-agent"
|