@parmanasystems/core 1.55.0 → 1.59.0
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 +366 -94
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -7
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,24 +1,87 @@
|
|
|
1
1
|
# @parmanasystems/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Deterministic governance SDK and evaluation foundation for the Parmana Systems ecosystem.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@parmanasystems/core)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# Overview
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
`@parmanasystems/core` is the primary integration package for the Parmana deterministic governance ecosystem.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
It provides a unified governance SDK combining:
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
- deterministic policy evaluation
|
|
16
|
+
- governed execution
|
|
17
|
+
- independent verification
|
|
18
|
+
- replay-safe execution infrastructure
|
|
19
|
+
- runtime provenance validation
|
|
20
|
+
- canonical governance utilities
|
|
21
|
+
|
|
22
|
+
For most applications, this is the recommended entry point into the Parmana ecosystem.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Mental Model
|
|
27
|
+
|
|
28
|
+
```txt id="o5f0r2"
|
|
29
|
+
Signals
|
|
30
|
+
↓
|
|
31
|
+
Deterministic Evaluation
|
|
32
|
+
↓
|
|
33
|
+
Governed Decision
|
|
34
|
+
↓
|
|
35
|
+
Governed Execution
|
|
36
|
+
↓
|
|
37
|
+
Execution Attestation
|
|
38
|
+
↓
|
|
39
|
+
Independent Verification
|
|
40
|
+
|
|
41
|
+
The core package unifies the full deterministic governance lifecycle.
|
|
42
|
+
|
|
43
|
+
What this package does
|
|
44
|
+
|
|
45
|
+
@parmanasystems/core combines:
|
|
46
|
+
|
|
47
|
+
Capability Description
|
|
48
|
+
deterministic evaluation governed decision evaluation
|
|
49
|
+
governed execution replay-safe enforcement
|
|
50
|
+
verification independent proof validation
|
|
51
|
+
governance utilities canonical governance infrastructure
|
|
52
|
+
runtime lineage provenance validation
|
|
53
|
+
replay protection deterministic execution safety
|
|
54
|
+
|
|
55
|
+
This package acts as the unified developer-facing governance SDK.
|
|
56
|
+
|
|
57
|
+
When to use this package
|
|
58
|
+
|
|
59
|
+
Use this package when:
|
|
18
60
|
|
|
19
|
-
|
|
61
|
+
integrating deterministic governance into applications
|
|
62
|
+
building governed AI systems
|
|
63
|
+
implementing governed execution workflows
|
|
64
|
+
deploying deterministic execution pipelines
|
|
65
|
+
verifying execution attestations
|
|
66
|
+
building replay-safe governance infrastructure
|
|
67
|
+
adopting Parmana without managing multiple packages individually
|
|
20
68
|
|
|
21
|
-
|
|
69
|
+
Do NOT use this package when:
|
|
70
|
+
|
|
71
|
+
requiring only low-level runtime primitives
|
|
72
|
+
implementing only cryptographic infrastructure
|
|
73
|
+
building custom governance internals
|
|
74
|
+
|
|
75
|
+
In those cases use lower-level packages directly:
|
|
76
|
+
|
|
77
|
+
Package Responsibility
|
|
78
|
+
@parmanasystems/execution governed execution runtime
|
|
79
|
+
@parmanasystems/verifier independent verification
|
|
80
|
+
@parmanasystems/governance governance lifecycle
|
|
81
|
+
@parmanasystems/crypto signing infrastructure
|
|
82
|
+
Installation
|
|
83
|
+
npm install @parmanasystems/core
|
|
84
|
+
Quick Start
|
|
22
85
|
import {
|
|
23
86
|
executeFromSignals,
|
|
24
87
|
verifyAttestation,
|
|
@@ -27,94 +90,268 @@ import {
|
|
|
27
90
|
getRuntimeManifest,
|
|
28
91
|
RedisReplayStore,
|
|
29
92
|
} from "@parmanasystems/core";
|
|
93
|
+
|
|
30
94
|
import { createClient } from "redis";
|
|
31
95
|
|
|
32
|
-
const redis
|
|
96
|
+
const redis =
|
|
97
|
+
createClient();
|
|
98
|
+
|
|
33
99
|
await redis.connect();
|
|
34
100
|
|
|
35
|
-
const signer
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
{
|
|
101
|
+
const signer =
|
|
102
|
+
new LocalSigner(
|
|
103
|
+
process.env.Parmana_PRIVATE_KEY!
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const verifier =
|
|
107
|
+
new LocalVerifier(
|
|
108
|
+
process.env.Parmana_PUBLIC_KEY!
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const store =
|
|
112
|
+
new RedisReplayStore(
|
|
113
|
+
redis
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const manifest =
|
|
117
|
+
getRuntimeManifest();
|
|
118
|
+
|
|
119
|
+
const result =
|
|
120
|
+
await executeFromSignals(
|
|
121
|
+
{
|
|
122
|
+
policyId:
|
|
123
|
+
"claims-approval",
|
|
124
|
+
|
|
125
|
+
policyVersion:
|
|
126
|
+
"v1",
|
|
127
|
+
|
|
128
|
+
signals: {
|
|
129
|
+
insurance_active: true,
|
|
130
|
+
risk_score: 42,
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
signer,
|
|
56
134
|
verifier,
|
|
57
|
-
|
|
135
|
+
store
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (
|
|
139
|
+
result.status === "success"
|
|
140
|
+
&&
|
|
141
|
+
result.signature
|
|
142
|
+
) {
|
|
143
|
+
|
|
144
|
+
const verification =
|
|
145
|
+
verifyAttestation(
|
|
146
|
+
{
|
|
147
|
+
execution_id:
|
|
148
|
+
result.execution_id,
|
|
149
|
+
|
|
150
|
+
...result
|
|
151
|
+
},
|
|
152
|
+
verifier,
|
|
153
|
+
manifest
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
console.log(
|
|
157
|
+
verification.valid
|
|
58
158
|
);
|
|
59
|
-
console.log(verification.valid); // true
|
|
60
159
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
160
|
+
Core Concepts
|
|
161
|
+
Deterministic Evaluation
|
|
162
|
+
|
|
163
|
+
Governance evaluation is deterministic.
|
|
164
|
+
|
|
165
|
+
The runtime guarantees:
|
|
166
|
+
|
|
167
|
+
same signals + same policy → same governed outcome
|
|
168
|
+
|
|
169
|
+
Evaluation does not depend on:
|
|
170
|
+
|
|
171
|
+
randomness
|
|
172
|
+
mutable runtime state
|
|
173
|
+
probabilistic execution
|
|
174
|
+
timestamps
|
|
175
|
+
Signals vs Rules vs Execution
|
|
176
|
+
|
|
177
|
+
Parmana separates:
|
|
178
|
+
|
|
179
|
+
Component Responsibility
|
|
180
|
+
signals governed facts and inputs
|
|
181
|
+
rules deterministic governance logic
|
|
182
|
+
execution governed enforcement
|
|
183
|
+
|
|
184
|
+
This separation improves:
|
|
185
|
+
|
|
186
|
+
auditability
|
|
187
|
+
reproducibility
|
|
188
|
+
governance clarity
|
|
189
|
+
execution trust boundaries
|
|
190
|
+
signalsSchema
|
|
191
|
+
|
|
192
|
+
Policies define governed signal structure explicitly.
|
|
193
|
+
|
|
194
|
+
Example:
|
|
195
|
+
|
|
196
|
+
{
|
|
197
|
+
"signalsSchema": {
|
|
198
|
+
"risk_score": {
|
|
199
|
+
"type": "number"
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
Signals are:
|
|
205
|
+
|
|
206
|
+
typed
|
|
207
|
+
deterministic
|
|
208
|
+
explicitly governed
|
|
209
|
+
schema-validated
|
|
210
|
+
Governed Decisions
|
|
211
|
+
|
|
212
|
+
The evaluator produces governed outcomes:
|
|
213
|
+
|
|
214
|
+
{
|
|
215
|
+
"action": "approve",
|
|
216
|
+
"requires_override": false
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
Possible outcomes include:
|
|
220
|
+
|
|
221
|
+
Outcome Meaning
|
|
222
|
+
approve execution allowed
|
|
223
|
+
reject execution denied
|
|
224
|
+
requires_override human escalation required
|
|
225
|
+
|
|
226
|
+
The evaluator determines governance outcomes.
|
|
227
|
+
|
|
228
|
+
Execution authority is enforced separately.
|
|
229
|
+
|
|
230
|
+
execution_id
|
|
231
|
+
|
|
232
|
+
Operational execution lineage identifier.
|
|
233
|
+
|
|
234
|
+
Used for:
|
|
235
|
+
|
|
236
|
+
audit tracking
|
|
237
|
+
governance event identity
|
|
238
|
+
operational lineage
|
|
239
|
+
execution_fingerprint
|
|
240
|
+
|
|
241
|
+
Deterministic replay identity.
|
|
242
|
+
|
|
243
|
+
Replay protection operates on execution fingerprints.
|
|
244
|
+
|
|
245
|
+
Identical governed inputs produce identical execution fingerprints.
|
|
246
|
+
|
|
247
|
+
signals_hash
|
|
248
|
+
|
|
249
|
+
Canonicalized governed input proof.
|
|
250
|
+
|
|
251
|
+
Used for:
|
|
252
|
+
|
|
253
|
+
deterministic reconstruction
|
|
254
|
+
execution verification
|
|
255
|
+
audit integrity
|
|
256
|
+
replay-safe governance
|
|
257
|
+
Example Policy
|
|
258
|
+
{
|
|
259
|
+
"policyId": "loan-approval",
|
|
260
|
+
|
|
261
|
+
"version": "v1",
|
|
262
|
+
|
|
263
|
+
"signalsSchema": {
|
|
264
|
+
|
|
265
|
+
"risk_score": {
|
|
266
|
+
"type": "number"
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
"rules": [
|
|
271
|
+
|
|
272
|
+
{
|
|
273
|
+
"id": "approve-low-risk",
|
|
274
|
+
|
|
275
|
+
"condition": {
|
|
276
|
+
"all": [
|
|
277
|
+
{
|
|
278
|
+
"signal": "risk_score",
|
|
279
|
+
"less_than": 0.25
|
|
280
|
+
}
|
|
281
|
+
]
|
|
282
|
+
},
|
|
283
|
+
|
|
284
|
+
"outcome": {
|
|
285
|
+
"action": "approve",
|
|
286
|
+
"requires_override": false
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
}
|
|
291
|
+
Governance Lifecycle
|
|
292
|
+
Signals
|
|
293
|
+
↓
|
|
294
|
+
Validation
|
|
295
|
+
↓
|
|
296
|
+
Deterministic Evaluation
|
|
297
|
+
↓
|
|
298
|
+
Governed Decision
|
|
299
|
+
↓
|
|
300
|
+
Execution Token
|
|
301
|
+
↓
|
|
302
|
+
Governed Execution
|
|
303
|
+
↓
|
|
304
|
+
Execution Attestation
|
|
305
|
+
↓
|
|
306
|
+
Independent Verification
|
|
307
|
+
Major Exports
|
|
308
|
+
Governance Lifecycle
|
|
309
|
+
|
|
310
|
+
From @parmanasystems/governance
|
|
311
|
+
|
|
312
|
+
Export Description
|
|
313
|
+
createPolicy scaffold governance policy
|
|
314
|
+
upgradePolicy create new immutable policy version
|
|
315
|
+
validatePolicy validate governance policy
|
|
316
|
+
generateBundle generate governance bundle
|
|
317
|
+
definePolicy define policy in memory
|
|
318
|
+
Deterministic Execution
|
|
319
|
+
|
|
320
|
+
From @parmanasystems/execution
|
|
321
|
+
|
|
322
|
+
Export Description
|
|
323
|
+
executeFromSignals full governed execution pipeline
|
|
324
|
+
executeDecision low-level execution pipeline
|
|
325
|
+
executeSimple simplified token execution
|
|
326
|
+
resolveOverride resolve override workflow
|
|
327
|
+
evaluatePolicy deterministic policy evaluation
|
|
328
|
+
issueToken issue execution token
|
|
329
|
+
getRuntimeManifest active runtime lineage
|
|
330
|
+
LocalSigner local Ed25519 signer
|
|
331
|
+
LocalVerifier local Ed25519 verifier
|
|
332
|
+
MemoryReplayStore in-memory replay protection
|
|
333
|
+
RedisReplayStore distributed replay protection
|
|
334
|
+
Independent Verification
|
|
335
|
+
|
|
336
|
+
From @parmanasystems/verifier
|
|
337
|
+
|
|
338
|
+
Export Description
|
|
339
|
+
verifyAttestation deterministic attestation verification
|
|
340
|
+
verifyBundle governance bundle verification
|
|
341
|
+
verifyRuntime runtime lineage verification
|
|
342
|
+
verifyRuntimeCompatibility runtime compatibility validation
|
|
343
|
+
verifyExecutionRequirements execution requirement validation
|
|
344
|
+
Canonical Utilities
|
|
345
|
+
|
|
346
|
+
From @parmanasystems/bundle
|
|
347
|
+
|
|
348
|
+
import {
|
|
349
|
+
canonicalize
|
|
350
|
+
} from "@parmanasystems/core";
|
|
351
|
+
|
|
352
|
+
Provides deterministic canonical serialization.
|
|
353
|
+
|
|
354
|
+
Types
|
|
118
355
|
import type {
|
|
119
356
|
ExecutionContext,
|
|
120
357
|
ExecutionAttestation,
|
|
@@ -128,8 +365,43 @@ import type {
|
|
|
128
365
|
AsyncReplayStore,
|
|
129
366
|
ViolationReport,
|
|
130
367
|
} from "@parmanasystems/core";
|
|
131
|
-
|
|
368
|
+
Recommended Architecture
|
|
369
|
+
Application
|
|
370
|
+
↓
|
|
371
|
+
@parmanasystems/core
|
|
372
|
+
↓
|
|
373
|
+
Deterministic Governance
|
|
374
|
+
↓
|
|
375
|
+
Execution Attestation
|
|
376
|
+
↓
|
|
377
|
+
Independent Verification
|
|
378
|
+
|
|
379
|
+
For most applications, @parmanasystems/core is the recommended integration surface.
|
|
380
|
+
|
|
381
|
+
Security Model
|
|
382
|
+
|
|
383
|
+
The core governance SDK enforces:
|
|
384
|
+
|
|
385
|
+
deterministic evaluation
|
|
386
|
+
fail-closed governance
|
|
387
|
+
replay-safe execution
|
|
388
|
+
immutable attestations
|
|
389
|
+
runtime provenance validation
|
|
390
|
+
independent verification
|
|
391
|
+
governed execution boundaries
|
|
392
|
+
canonical deterministic serialization
|
|
393
|
+
|
|
394
|
+
The system is designed so that:
|
|
132
395
|
|
|
133
|
-
|
|
396
|
+
AI may recommend actions.
|
|
397
|
+
Deterministic governance controls execution authority.
|
|
398
|
+
Relationship to Other Parmana Packages
|
|
399
|
+
Package Responsibility
|
|
400
|
+
@parmanasystems/core unified governance SDK
|
|
401
|
+
@parmanasystems/execution governed execution runtime
|
|
402
|
+
@parmanasystems/verifier independent verification
|
|
403
|
+
@parmanasystems/server deployable runtime
|
|
404
|
+
@parmanasystems/sdk-client HTTP integration
|
|
405
|
+
License
|
|
134
406
|
|
|
135
|
-
Apache-2.0
|
|
407
|
+
Apache-2.0
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { signBundle } from '@parmanasystems/crypto';
|
|
|
3
3
|
export { ExecutionAttestation, ExecutionContext, ExecutionToken, INVARIANT_REGISTRY, InvariantBoundary, InvariantEntry, InvariantId, InvariantViolation, LocalSigner, LocalVerifier, MemoryReplayStore, ReplayStore, RuntimeManifest, Signer, Verifier, ViolationReport, executeDecision, executeFromSignals, getRuntimeManifest, hashInput, issueToken, signRuntimeManifest, verifyExecutionToken, verifyRuntimeManifest, violate } from '@parmanasystems/execution';
|
|
4
4
|
export { verifyAttestation, verifyBundle, verifyExecutionRequirements, verifyRuntime, verifyRuntimeCompatibility } from '@parmanasystems/verifier';
|
|
5
5
|
export { DecisionOutcome, DecisionResult } from '@parmanasystems/contracts';
|
|
6
|
-
import {
|
|
6
|
+
import { AuditOverride } from '@parmanasystems/audit-db';
|
|
7
7
|
|
|
8
8
|
interface ApproveOverrideInput {
|
|
9
9
|
execution_id: string;
|
|
@@ -11,7 +11,7 @@ interface ApproveOverrideInput {
|
|
|
11
11
|
approver_role: string;
|
|
12
12
|
reason: string;
|
|
13
13
|
}
|
|
14
|
-
declare function approveOverride(input: ApproveOverrideInput
|
|
14
|
+
declare function approveOverride(input: ApproveOverrideInput): Promise<AuditOverride>;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Serializes `value` to a stable, compact JSON string with object keys sorted
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
|
|
37
37
|
// src/override.ts
|
|
38
38
|
import crypto from "crypto";
|
|
39
|
-
async function approveOverride(input
|
|
39
|
+
async function approveOverride(input) {
|
|
40
40
|
const override_id = crypto.randomUUID();
|
|
41
41
|
const approved_at = /* @__PURE__ */ new Date();
|
|
42
42
|
const override_signature = crypto.createHash("sha256").update(
|
|
@@ -60,12 +60,6 @@ async function approveOverride(input, auditDb) {
|
|
|
60
60
|
approved_at,
|
|
61
61
|
recorded_at: approved_at
|
|
62
62
|
};
|
|
63
|
-
await auditDb.recordOverride(
|
|
64
|
-
override
|
|
65
|
-
);
|
|
66
|
-
await auditDb.markExecuted(
|
|
67
|
-
input.execution_id
|
|
68
|
-
);
|
|
69
63
|
return override;
|
|
70
64
|
}
|
|
71
65
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/override.ts","../src/canonicalize.ts","../src/invariants.ts","../src/deterministic-policy.ts","../src/validator.ts"],"sourcesContent":["// -----------------------------\r\n// Governance Lifecycle\r\n// -----------------------------\r\nexport {\r\n createPolicy,\r\n upgradePolicy,\r\n validatePolicy,\r\n generateBundle\r\n} from \"@parmanasystems/governance\";\r\n\r\nexport {\r\n signBundle\r\n} from \"@parmanasystems/crypto\";\r\n\r\n// -----------------------------\r\n// Deterministic Execution\r\n// -----------------------------\r\nexport {\r\n executeFromSignals,\r\n executeDecision,\r\n issueToken,\r\n verifyExecutionToken,\r\n getRuntimeManifest,\r\n signRuntimeManifest,\r\n verifyRuntimeManifest,\r\n LocalSigner,\r\n LocalVerifier,\r\n MemoryReplayStore\r\n} from \"@parmanasystems/execution\";\r\n\r\n// -----------------------------\r\n// Portable Verification\r\n// -----------------------------\r\nexport {\r\n verifyAttestation,\r\n verifyBundle,\r\n verifyRuntime,\r\n verifyRuntimeCompatibility,\r\n verifyExecutionRequirements\r\n} from \"@parmanasystems/verifier\";\r\n\r\n// -----------------------------\r\n// Canonical Governance Types\r\n// -----------------------------\r\nexport type {\r\n ExecutionContext,\r\n ExecutionAttestation,\r\n ExecutionToken,\r\n RuntimeManifest,\r\n Signer,\r\n Verifier,\r\n ReplayStore,\r\n} from \"@parmanasystems/execution\";\r\n\r\nexport type {\r\n RuntimeRequirements,\r\n} from \"@parmanasystems/governance\";\r\n\r\nexport type {\r\n DecisionResult,\r\n DecisionOutcome\r\n} from \"@parmanasystems/contracts\";\r\n\r\n// -----------------------------\r\n// Invariant Registry\r\n// -----------------------------\r\nexport type {\r\n InvariantBoundary,\r\n InvariantEntry,\r\n InvariantId,\r\n ViolationReport,\r\n} from \"@parmanasystems/execution\";\r\n\r\nexport {\r\n INVARIANT_REGISTRY,\r\n InvariantViolation,\r\n violate,\r\n hashInput,\r\n} from \"@parmanasystems/execution\";\r\n\r\n// -----------------------------\r\n// Override Authority\r\n// -----------------------------\r\nexport {\r\n approveOverride\r\n} from \"./override.js\";\r\n\r\nexport type {\r\n ApproveOverrideInput\r\n} from \"./override.js\";\r\n\r\n// -----------------------------\r\n// Deterministic Validation\r\n// -----------------------------\r\nexport * from \"./canonicalize.js\";\r\nexport * from \"./validator.js\";\r\nexport * from \"./invariants.js\";\r\n\r\n// -----------------------------\r\n// Validation Types\r\n// -----------------------------\r\nexport * from \"./types/envelope.js\";\r\nexport * from \"./types/payloads.js\";\r\nexport * from \"./types/validation.js\";\r\nexport * from \"./types/metadata.js\";\r\nexport * from \"./deterministic-policy.js\";\r\nexport * from \"./types/validator-config.js\";","import crypto from \"node:crypto\";\r\n\r\nimport type {\r\n AuditDb,\r\n AuditOverride\r\n} from \"@parmanasystems/audit-db\";\r\n\r\nexport interface ApproveOverrideInput {\r\n\r\n execution_id: string;\r\n\r\n approved_by: string;\r\n\r\n approver_role: string;\r\n\r\n reason: string;\r\n}\r\n\r\nexport async function approveOverride(\r\n input: ApproveOverrideInput,\r\n auditDb: AuditDb\r\n): Promise<AuditOverride> {\r\n\r\n const override_id =\r\n crypto.randomUUID();\r\n\r\n const approved_at =\r\n new Date();\r\n\r\n const override_signature =\r\n crypto\r\n .createHash(\"sha256\")\r\n .update(\r\n JSON.stringify({\r\n override_id,\r\n execution_id:\r\n input.execution_id,\r\n approved_by:\r\n input.approved_by,\r\n approver_role:\r\n input.approver_role,\r\n reason:\r\n input.reason,\r\n approved_at\r\n })\r\n )\r\n .digest(\"hex\");\r\n\r\n const override: AuditOverride = {\r\n\r\n id: 0,\r\n\r\n override_id,\r\n\r\n execution_id:\r\n input.execution_id,\r\n\r\n approved_by:\r\n input.approved_by,\r\n\r\n approver_role:\r\n input.approver_role,\r\n\r\n reason:\r\n input.reason,\r\n\r\n override_signature,\r\n\r\n approved_at,\r\n\r\n recorded_at:\r\n approved_at\r\n };\r\n\r\n await auditDb.recordOverride(\r\n override\r\n );\r\n\r\n await auditDb.markExecuted(\r\n input.execution_id\r\n );\r\n\r\n return override;\r\n}","function sortKeys(value: any): any {\r\n if (Array.isArray(value)) {\r\n return value.map(sortKeys);\r\n }\r\n\r\n if (value && typeof value === \"object\") {\r\n return Object.keys(value)\r\n .sort()\r\n .reduce((acc, key) => {\r\n acc[key] = sortKeys(value[key]);\r\n return acc;\r\n }, {} as Record<string, unknown>);\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Serializes `value` to a stable, compact JSON string with object keys sorted\r\n * recursively. Used by the core validation pipeline for determinism checks.\r\n *\r\n * Note: unlike `@parmanasystems/bundle`'s `canonicalize`, this variant uses\r\n * compact output (`JSON.stringify` without indentation) for in-memory comparisons.\r\n */\r\nexport function canonicalize(value: unknown): string {\r\n return JSON.stringify(sortKeys(value));\r\n}\r\n","/** Returns `true` when `value` is a non-empty, non-whitespace-only string. */\r\nexport function assertNonEmptyString(\r\n value: unknown\r\n): boolean {\r\n return (\r\n typeof value === \"string\" &&\r\n value.trim().length > 0\r\n );\r\n}\r\n\r\n/** Returns `true` when `value` is an array. */\r\nexport function assertArray(\r\n value: unknown\r\n): boolean {\r\n return Array.isArray(value);\r\n}\r\n\r\nfunction scanObject(\r\n value: unknown,\r\n forbiddenFields:\r\n readonly string[]\r\n): boolean {\r\n\r\n if (\r\n typeof value !== \"object\" ||\r\n value === null\r\n ) {\r\n return true;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return value.every(\r\n (item) =>\r\n scanObject(\r\n item,\r\n forbiddenFields\r\n )\r\n );\r\n }\r\n\r\n for (\r\n const [key, nested]\r\n of Object.entries(value)\r\n ) {\r\n\r\n if (\r\n forbiddenFields.includes(\r\n key\r\n )\r\n ) {\r\n return false;\r\n }\r\n\r\n if (\r\n !scanObject(\r\n nested,\r\n forbiddenFields\r\n )\r\n ) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Recursively scans `payload` and returns `false` if any object key matches\r\n * a name in `forbiddenFields`.\r\n *\r\n * Used by {@link LocalValidator} to enforce that operational-metadata fields\r\n * have not contaminated the deterministic signing scope.\r\n *\r\n * @param payload - The payload object to inspect.\r\n * @param forbiddenFields - Field names that must not appear anywhere in the payload.\r\n */\r\nexport function assertNoOperationalMetadata(\r\n payload: unknown,\r\n forbiddenFields:\r\n readonly string[]\r\n): boolean {\r\n\r\n return scanObject(\r\n payload,\r\n forbiddenFields\r\n );\r\n}\r\n","/**\r\n * Field names that must not appear inside a deterministic payload.\r\n *\r\n * These are operational-metadata fields that introduce non-determinism\r\n * (timestamps, hostnames, trace IDs, deployment context) and would break\r\n * reproducible verification if present in the signed payload scope.\r\n *\r\n * Used as the default for {@link ValidatorConfig.forbiddenDeterministicFields}.\r\n */\r\nexport const forbiddenDeterministicFields = [\r\n \"generatedAt\",\r\n \"environment\",\r\n \"host\",\r\n \"runtime\",\r\n \"traceId\"\r\n] as const;\r\n","import { canonicalize } from \"./canonicalize.js\";\r\n\r\nimport {\r\n assertNoOperationalMetadata\r\n} from \"./invariants.js\";\r\n\r\nimport {\r\n forbiddenDeterministicFields\r\n} from \"./deterministic-policy.js\";\r\n\r\nimport {\r\n ValidatorConfig\r\n} from \"./types/validator-config.js\";\r\n\r\nimport { ValidationResult } from \"./types/validation.js\";\r\n\r\nimport { SignedEnvelope } from \"./types/envelope.js\";\r\n\r\n/**\r\n * Multi-stage validator for {@link SignedEnvelope} values.\r\n *\r\n * Runs up to five sequential checks (structure → canonical → deterministic →\r\n * metadata isolation → cryptographic) and returns a detailed\r\n * {@link ValidationResult} with per-stage flags and error messages.\r\n *\r\n * **Note:** the `cryptographic` stage is not yet implemented and always returns\r\n * `false`, so `valid` is always `false`. Use `@parmanasystems/verifier` for\r\n * cryptographic attestation verification.\r\n */\r\nexport class LocalValidator {\r\n\r\n private readonly config:\r\n ValidatorConfig;\r\n\r\n /**\r\n * @param config - Optional override for {@link ValidatorConfig}.\r\n * Defaults to using {@link forbiddenDeterministicFields}.\r\n */\r\n constructor(\r\n config: ValidatorConfig = {}\r\n ) {\r\n this.config = {\r\n forbiddenDeterministicFields,\r\n ...config\r\n };\r\n }\r\n\r\n private extractDeterministicPayload(\r\n envelope: SignedEnvelope<unknown>\r\n ): unknown {\r\n return envelope.payload;\r\n }\r\n\r\n /** Returns `true` when `envelope` has `payload` (any value) and `signature` (string). */\r\n validateStructure(\r\n envelope: SignedEnvelope<unknown>\r\n ): boolean {\r\n\r\n return (\r\n typeof envelope === \"object\" &&\r\n envelope !== null &&\r\n \"payload\" in envelope &&\r\n \"signature\" in envelope &&\r\n typeof envelope.signature === \"string\"\r\n );\r\n }\r\n\r\n /** Returns `true` when `payload` can be serialized through the canonical JSON pipeline without error. */\r\n validateCanonical(\r\n payload: unknown\r\n ): boolean {\r\n\r\n try {\r\n\r\n canonicalize(payload);\r\n\r\n return true;\r\n\r\n } catch {\r\n\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Returns `true` when the canonical form of the payload alone equals the\r\n * canonical form of `{ payload }`, confirming that no metadata fields have\r\n * leaked into the deterministic signing scope.\r\n */\r\n validateMetadataIsolation(\r\n envelope: SignedEnvelope<unknown>\r\n ): boolean {\r\n\r\n try {\r\n\r\n const canonicalPayload =\r\n canonicalize(\r\n this.extractDeterministicPayload(\r\n envelope\r\n )\r\n );\r\n\r\n const canonicalEnvelope =\r\n canonicalize({\r\n payload:\r\n this.extractDeterministicPayload(\r\n envelope\r\n )\r\n });\r\n\r\n return (\r\n canonicalPayload ===\r\n canonicalEnvelope\r\n );\r\n\r\n } catch {\r\n\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Runs all five validation stages against `envelope` and returns a\r\n * {@link ValidationResult} with per-stage flags and accumulated error messages.\r\n */\r\n validate(\r\n envelope: SignedEnvelope<unknown>\r\n ): ValidationResult {\r\n\r\n const structure =\r\n this.validateStructure(\r\n envelope\r\n );\r\n\r\n const canonical =\r\n structure &&\r\n this.validateCanonical(\r\n envelope.payload\r\n );\r\n\r\n const deterministic =\r\n structure &&\r\n assertNoOperationalMetadata(\r\n envelope.payload,\r\n this.config\r\n .forbiddenDeterministicFields ??\r\n []\r\n );\r\n\r\n const metadataIsolation =\r\n structure &&\r\n this.validateMetadataIsolation(\r\n envelope\r\n );\r\n\r\n const cryptographic =\r\n false;\r\n\r\n const errors: string[] =\r\n [];\r\n\r\n if (!structure) {\r\n errors.push(\r\n \"Invalid structure.\"\r\n );\r\n }\r\n\r\n if (!canonical) {\r\n errors.push(\r\n \"Canonicalization validation failed.\"\r\n );\r\n }\r\n\r\n if (!deterministic) {\r\n errors.push(\r\n \"Operational metadata contamination detected.\"\r\n );\r\n }\r\n\r\n if (!metadataIsolation) {\r\n errors.push(\r\n \"Metadata isolation validation failed.\"\r\n );\r\n }\r\n\r\n return {\r\n valid:\r\n structure &&\r\n canonical &&\r\n deterministic &&\r\n metadataIsolation &&\r\n cryptographic,\r\n\r\n verified:\r\n cryptographic,\r\n\r\n stages: {\r\n structure,\r\n canonical,\r\n deterministic,\r\n metadataIsolation,\r\n cryptographic\r\n },\r\n\r\n errors\r\n };\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/override.ts","../src/canonicalize.ts","../src/invariants.ts","../src/deterministic-policy.ts","../src/validator.ts"],"sourcesContent":["// -----------------------------\r\n// Governance Lifecycle\r\n// -----------------------------\r\nexport {\r\n createPolicy,\r\n upgradePolicy,\r\n validatePolicy,\r\n generateBundle\r\n} from \"@parmanasystems/governance\";\r\n\r\nexport {\r\n signBundle\r\n} from \"@parmanasystems/crypto\";\r\n\r\n// -----------------------------\r\n// Deterministic Execution\r\n// -----------------------------\r\nexport {\r\n executeFromSignals,\r\n executeDecision,\r\n issueToken,\r\n verifyExecutionToken,\r\n getRuntimeManifest,\r\n signRuntimeManifest,\r\n verifyRuntimeManifest,\r\n LocalSigner,\r\n LocalVerifier,\r\n MemoryReplayStore\r\n} from \"@parmanasystems/execution\";\r\n\r\n// -----------------------------\r\n// Portable Verification\r\n// -----------------------------\r\nexport {\r\n verifyAttestation,\r\n verifyBundle,\r\n verifyRuntime,\r\n verifyRuntimeCompatibility,\r\n verifyExecutionRequirements\r\n} from \"@parmanasystems/verifier\";\r\n\r\n// -----------------------------\r\n// Canonical Governance Types\r\n// -----------------------------\r\nexport type {\r\n ExecutionContext,\r\n ExecutionAttestation,\r\n ExecutionToken,\r\n RuntimeManifest,\r\n Signer,\r\n Verifier,\r\n ReplayStore,\r\n} from \"@parmanasystems/execution\";\r\n\r\nexport type {\r\n RuntimeRequirements,\r\n} from \"@parmanasystems/governance\";\r\n\r\nexport type {\r\n DecisionResult,\r\n DecisionOutcome\r\n} from \"@parmanasystems/contracts\";\r\n\r\n// -----------------------------\r\n// Invariant Registry\r\n// -----------------------------\r\nexport type {\r\n InvariantBoundary,\r\n InvariantEntry,\r\n InvariantId,\r\n ViolationReport,\r\n} from \"@parmanasystems/execution\";\r\n\r\nexport {\r\n INVARIANT_REGISTRY,\r\n InvariantViolation,\r\n violate,\r\n hashInput,\r\n} from \"@parmanasystems/execution\";\r\n\r\n// -----------------------------\r\n// Override Authority\r\n// -----------------------------\r\nexport {\r\n approveOverride\r\n} from \"./override.js\";\r\n\r\nexport type {\r\n ApproveOverrideInput\r\n} from \"./override.js\";\r\n\r\n// -----------------------------\r\n// Deterministic Validation\r\n// -----------------------------\r\nexport * from \"./canonicalize.js\";\r\nexport * from \"./validator.js\";\r\nexport * from \"./invariants.js\";\r\n\r\n// -----------------------------\r\n// Validation Types\r\n// -----------------------------\r\nexport * from \"./types/envelope.js\";\r\nexport * from \"./types/payloads.js\";\r\nexport * from \"./types/validation.js\";\r\nexport * from \"./types/metadata.js\";\r\nexport * from \"./deterministic-policy.js\";\r\nexport * from \"./types/validator-config.js\";","import crypto from \"node:crypto\";\r\n\r\nimport type {\r\n AuditOverride\r\n} from \"@parmanasystems/audit-db\";\r\n\r\nexport interface ApproveOverrideInput {\r\n\r\n execution_id: string;\r\n\r\n approved_by: string;\r\n\r\n approver_role: string;\r\n\r\n reason: string;\r\n}\r\n\r\nexport async function approveOverride(\r\n input: ApproveOverrideInput\r\n): Promise<AuditOverride> {\r\n\r\n const override_id =\r\n crypto.randomUUID();\r\n\r\n const approved_at =\r\n new Date();\r\n\r\n const override_signature =\r\n crypto\r\n .createHash(\"sha256\")\r\n .update(\r\n JSON.stringify({\r\n override_id,\r\n execution_id:\r\n input.execution_id,\r\n approved_by:\r\n input.approved_by,\r\n approver_role:\r\n input.approver_role,\r\n reason:\r\n input.reason,\r\n approved_at\r\n })\r\n )\r\n .digest(\"hex\");\r\n\r\n const override: AuditOverride = {\r\n\r\n id: 0,\r\n\r\n override_id,\r\n\r\n execution_id:\r\n input.execution_id,\r\n\r\n approved_by:\r\n input.approved_by,\r\n\r\n approver_role:\r\n input.approver_role,\r\n\r\n reason:\r\n input.reason,\r\n\r\n override_signature,\r\n\r\n approved_at,\r\n\r\n recorded_at:\r\n approved_at\r\n };\r\n\r\n return override;\r\n}","function sortKeys(value: any): any {\r\n if (Array.isArray(value)) {\r\n return value.map(sortKeys);\r\n }\r\n\r\n if (value && typeof value === \"object\") {\r\n return Object.keys(value)\r\n .sort()\r\n .reduce((acc, key) => {\r\n acc[key] = sortKeys(value[key]);\r\n return acc;\r\n }, {} as Record<string, unknown>);\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Serializes `value` to a stable, compact JSON string with object keys sorted\r\n * recursively. Used by the core validation pipeline for determinism checks.\r\n *\r\n * Note: unlike `@parmanasystems/bundle`'s `canonicalize`, this variant uses\r\n * compact output (`JSON.stringify` without indentation) for in-memory comparisons.\r\n */\r\nexport function canonicalize(value: unknown): string {\r\n return JSON.stringify(sortKeys(value));\r\n}\r\n","/** Returns `true` when `value` is a non-empty, non-whitespace-only string. */\r\nexport function assertNonEmptyString(\r\n value: unknown\r\n): boolean {\r\n return (\r\n typeof value === \"string\" &&\r\n value.trim().length > 0\r\n );\r\n}\r\n\r\n/** Returns `true` when `value` is an array. */\r\nexport function assertArray(\r\n value: unknown\r\n): boolean {\r\n return Array.isArray(value);\r\n}\r\n\r\nfunction scanObject(\r\n value: unknown,\r\n forbiddenFields:\r\n readonly string[]\r\n): boolean {\r\n\r\n if (\r\n typeof value !== \"object\" ||\r\n value === null\r\n ) {\r\n return true;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return value.every(\r\n (item) =>\r\n scanObject(\r\n item,\r\n forbiddenFields\r\n )\r\n );\r\n }\r\n\r\n for (\r\n const [key, nested]\r\n of Object.entries(value)\r\n ) {\r\n\r\n if (\r\n forbiddenFields.includes(\r\n key\r\n )\r\n ) {\r\n return false;\r\n }\r\n\r\n if (\r\n !scanObject(\r\n nested,\r\n forbiddenFields\r\n )\r\n ) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Recursively scans `payload` and returns `false` if any object key matches\r\n * a name in `forbiddenFields`.\r\n *\r\n * Used by {@link LocalValidator} to enforce that operational-metadata fields\r\n * have not contaminated the deterministic signing scope.\r\n *\r\n * @param payload - The payload object to inspect.\r\n * @param forbiddenFields - Field names that must not appear anywhere in the payload.\r\n */\r\nexport function assertNoOperationalMetadata(\r\n payload: unknown,\r\n forbiddenFields:\r\n readonly string[]\r\n): boolean {\r\n\r\n return scanObject(\r\n payload,\r\n forbiddenFields\r\n );\r\n}\r\n","/**\r\n * Field names that must not appear inside a deterministic payload.\r\n *\r\n * These are operational-metadata fields that introduce non-determinism\r\n * (timestamps, hostnames, trace IDs, deployment context) and would break\r\n * reproducible verification if present in the signed payload scope.\r\n *\r\n * Used as the default for {@link ValidatorConfig.forbiddenDeterministicFields}.\r\n */\r\nexport const forbiddenDeterministicFields = [\r\n \"generatedAt\",\r\n \"environment\",\r\n \"host\",\r\n \"runtime\",\r\n \"traceId\"\r\n] as const;\r\n","import { canonicalize } from \"./canonicalize.js\";\r\n\r\nimport {\r\n assertNoOperationalMetadata\r\n} from \"./invariants.js\";\r\n\r\nimport {\r\n forbiddenDeterministicFields\r\n} from \"./deterministic-policy.js\";\r\n\r\nimport {\r\n ValidatorConfig\r\n} from \"./types/validator-config.js\";\r\n\r\nimport { ValidationResult } from \"./types/validation.js\";\r\n\r\nimport { SignedEnvelope } from \"./types/envelope.js\";\r\n\r\n/**\r\n * Multi-stage validator for {@link SignedEnvelope} values.\r\n *\r\n * Runs up to five sequential checks (structure → canonical → deterministic →\r\n * metadata isolation → cryptographic) and returns a detailed\r\n * {@link ValidationResult} with per-stage flags and error messages.\r\n *\r\n * **Note:** the `cryptographic` stage is not yet implemented and always returns\r\n * `false`, so `valid` is always `false`. Use `@parmanasystems/verifier` for\r\n * cryptographic attestation verification.\r\n */\r\nexport class LocalValidator {\r\n\r\n private readonly config:\r\n ValidatorConfig;\r\n\r\n /**\r\n * @param config - Optional override for {@link ValidatorConfig}.\r\n * Defaults to using {@link forbiddenDeterministicFields}.\r\n */\r\n constructor(\r\n config: ValidatorConfig = {}\r\n ) {\r\n this.config = {\r\n forbiddenDeterministicFields,\r\n ...config\r\n };\r\n }\r\n\r\n private extractDeterministicPayload(\r\n envelope: SignedEnvelope<unknown>\r\n ): unknown {\r\n return envelope.payload;\r\n }\r\n\r\n /** Returns `true` when `envelope` has `payload` (any value) and `signature` (string). */\r\n validateStructure(\r\n envelope: SignedEnvelope<unknown>\r\n ): boolean {\r\n\r\n return (\r\n typeof envelope === \"object\" &&\r\n envelope !== null &&\r\n \"payload\" in envelope &&\r\n \"signature\" in envelope &&\r\n typeof envelope.signature === \"string\"\r\n );\r\n }\r\n\r\n /** Returns `true` when `payload` can be serialized through the canonical JSON pipeline without error. */\r\n validateCanonical(\r\n payload: unknown\r\n ): boolean {\r\n\r\n try {\r\n\r\n canonicalize(payload);\r\n\r\n return true;\r\n\r\n } catch {\r\n\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Returns `true` when the canonical form of the payload alone equals the\r\n * canonical form of `{ payload }`, confirming that no metadata fields have\r\n * leaked into the deterministic signing scope.\r\n */\r\n validateMetadataIsolation(\r\n envelope: SignedEnvelope<unknown>\r\n ): boolean {\r\n\r\n try {\r\n\r\n const canonicalPayload =\r\n canonicalize(\r\n this.extractDeterministicPayload(\r\n envelope\r\n )\r\n );\r\n\r\n const canonicalEnvelope =\r\n canonicalize({\r\n payload:\r\n this.extractDeterministicPayload(\r\n envelope\r\n )\r\n });\r\n\r\n return (\r\n canonicalPayload ===\r\n canonicalEnvelope\r\n );\r\n\r\n } catch {\r\n\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Runs all five validation stages against `envelope` and returns a\r\n * {@link ValidationResult} with per-stage flags and accumulated error messages.\r\n */\r\n validate(\r\n envelope: SignedEnvelope<unknown>\r\n ): ValidationResult {\r\n\r\n const structure =\r\n this.validateStructure(\r\n envelope\r\n );\r\n\r\n const canonical =\r\n structure &&\r\n this.validateCanonical(\r\n envelope.payload\r\n );\r\n\r\n const deterministic =\r\n structure &&\r\n assertNoOperationalMetadata(\r\n envelope.payload,\r\n this.config\r\n .forbiddenDeterministicFields ??\r\n []\r\n );\r\n\r\n const metadataIsolation =\r\n structure &&\r\n this.validateMetadataIsolation(\r\n envelope\r\n );\r\n\r\n const cryptographic =\r\n false;\r\n\r\n const errors: string[] =\r\n [];\r\n\r\n if (!structure) {\r\n errors.push(\r\n \"Invalid structure.\"\r\n );\r\n }\r\n\r\n if (!canonical) {\r\n errors.push(\r\n \"Canonicalization validation failed.\"\r\n );\r\n }\r\n\r\n if (!deterministic) {\r\n errors.push(\r\n \"Operational metadata contamination detected.\"\r\n );\r\n }\r\n\r\n if (!metadataIsolation) {\r\n errors.push(\r\n \"Metadata isolation validation failed.\"\r\n );\r\n }\r\n\r\n return {\r\n valid:\r\n structure &&\r\n canonical &&\r\n deterministic &&\r\n metadataIsolation &&\r\n cryptographic,\r\n\r\n verified:\r\n cryptographic,\r\n\r\n stages: {\r\n structure,\r\n canonical,\r\n deterministic,\r\n metadataIsolation,\r\n cryptographic\r\n },\r\n\r\n errors\r\n };\r\n }\r\n}\r\n"],"mappings":";AAGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,OACK;AAKP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAKP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAkCP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;AC9EP,OAAO,YAAY;AAiBnB,eAAsB,gBACpB,OACwB;AAExB,QAAM,cACJ,OAAO,WAAW;AAEpB,QAAM,cACJ,oBAAI,KAAK;AAEX,QAAM,qBACJ,OACG,WAAW,QAAQ,EACnB;AAAA,IACC,KAAK,UAAU;AAAA,MACb;AAAA,MACA,cACE,MAAM;AAAA,MACR,aACE,MAAM;AAAA,MACR,eACE,MAAM;AAAA,MACR,QACE,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH,EACC,OAAO,KAAK;AAEjB,QAAM,WAA0B;AAAA,IAE9B,IAAI;AAAA,IAEJ;AAAA,IAEA,cACE,MAAM;AAAA,IAER,aACE,MAAM;AAAA,IAER,eACE,MAAM;AAAA,IAER,QACE,MAAM;AAAA,IAER;AAAA,IAEA;AAAA,IAEA,aACE;AAAA,EACJ;AAEA,SAAO;AACT;;;ACzEA,SAAS,SAAS,OAAiB;AACjC,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,QAAQ;AAAA,EAC3B;AAEA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,WAAO,OAAO,KAAK,KAAK,EACrB,KAAK,EACL,OAAO,CAAC,KAAK,QAAQ;AACpB,UAAI,GAAG,IAAI,SAAS,MAAM,GAAG,CAAC;AAC9B,aAAO;AAAA,IACT,GAAG,CAAC,CAA4B;AAAA,EACpC;AAEA,SAAO;AACT;AASO,SAAS,aAAa,OAAwB;AACnD,SAAO,KAAK,UAAU,SAAS,KAAK,CAAC;AACvC;;;ACzBO,SAAS,qBACd,OACS;AACT,SACE,OAAO,UAAU,YACjB,MAAM,KAAK,EAAE,SAAS;AAE1B;AAGO,SAAS,YACd,OACS;AACT,SAAO,MAAM,QAAQ,KAAK;AAC5B;AAEA,SAAS,WACP,OACA,iBAES;AAET,MACE,OAAO,UAAU,YACjB,UAAU,MACV;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM;AAAA,MACX,CAAC,SACC;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACJ;AAAA,EACF;AAEA,aACQ,CAAC,KAAK,MAAM,KACf,OAAO,QAAQ,KAAK,GACvB;AAEA,QACE,gBAAgB;AAAA,MACd;AAAA,IACF,GACA;AACA,aAAO;AAAA,IACT;AAEA,QACE,CAAC;AAAA,MACC;AAAA,MACA;AAAA,IACF,GACA;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAYO,SAAS,4BACd,SACA,iBAES;AAET,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;;;AC7EO,IAAM,+BAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACcO,IAAM,iBAAN,MAAqB;AAAA,EAET;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,YACE,SAA0B,CAAC,GAC3B;AACA,SAAK,SAAS;AAAA,MACZ;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EAEQ,4BACN,UACS;AACT,WAAO,SAAS;AAAA,EAClB;AAAA;AAAA,EAGA,kBACE,UACS;AAET,WACE,OAAO,aAAa,YACpB,aAAa,QACb,aAAa,YACb,eAAe,YACf,OAAO,SAAS,cAAc;AAAA,EAElC;AAAA;AAAA,EAGA,kBACE,SACS;AAET,QAAI;AAEF,mBAAa,OAAO;AAEpB,aAAO;AAAA,IAET,QAAQ;AAEN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,0BACE,UACS;AAET,QAAI;AAEF,YAAM,mBACJ;AAAA,QACE,KAAK;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEF,YAAM,oBACJ,aAAa;AAAA,QACX,SACE,KAAK;AAAA,UACH;AAAA,QACF;AAAA,MACJ,CAAC;AAEH,aACE,qBACA;AAAA,IAGJ,QAAQ;AAEN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SACE,UACkB;AAElB,UAAM,YACJ,KAAK;AAAA,MACH;AAAA,IACF;AAEF,UAAM,YACJ,aACA,KAAK;AAAA,MACH,SAAS;AAAA,IACX;AAEF,UAAM,gBACJ,aACA;AAAA,MACE,SAAS;AAAA,MACT,KAAK,OACF,gCACD,CAAC;AAAA,IACL;AAEF,UAAM,oBACJ,aACA,KAAK;AAAA,MACH;AAAA,IACF;AAEF,UAAM,gBACJ;AAEF,UAAM,SACJ,CAAC;AAEH,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,mBAAmB;AACtB,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OACE,aACA,aACA,iBACA,qBACA;AAAA,MAEF,UACE;AAAA,MAEF,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parmanasystems/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.59.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
],
|
|
19
19
|
"sideEffects": false,
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@parmanasystems/audit-db": "^1.
|
|
22
|
-
"@parmanasystems/bundle": "^1.
|
|
23
|
-
"@parmanasystems/crypto": "^1.
|
|
24
|
-
"@parmanasystems/execution": "^1.
|
|
25
|
-
"@parmanasystems/governance": "^1.
|
|
26
|
-
"@parmanasystems/verifier": "^1.
|
|
21
|
+
"@parmanasystems/audit-db": "^1.59.0",
|
|
22
|
+
"@parmanasystems/bundle": "^1.59.0",
|
|
23
|
+
"@parmanasystems/crypto": "^1.59.0",
|
|
24
|
+
"@parmanasystems/execution": "^1.59.0",
|
|
25
|
+
"@parmanasystems/governance": "^1.59.0",
|
|
26
|
+
"@parmanasystems/verifier": "^1.59.0"
|
|
27
27
|
},
|
|
28
28
|
"description": "Public orchestration and SDK surface for parmanasystems deterministic governance infrastructure.",
|
|
29
29
|
"license": "Apache-2.0",
|