@parmanasystems/core 1.51.0 → 1.56.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/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/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":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parmanasystems/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.56.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.56.0",
|
|
22
|
+
"@parmanasystems/bundle": "^1.56.0",
|
|
23
|
+
"@parmanasystems/crypto": "^1.56.0",
|
|
24
|
+
"@parmanasystems/execution": "^1.56.0",
|
|
25
|
+
"@parmanasystems/governance": "^1.56.0",
|
|
26
|
+
"@parmanasystems/verifier": "^1.56.0"
|
|
27
27
|
},
|
|
28
28
|
"description": "Public orchestration and SDK surface for parmanasystems deterministic governance infrastructure.",
|
|
29
29
|
"license": "Apache-2.0",
|