refactor(domain): own digest and prefixed identifier shapes in one module (#547)

This commit is contained in:
morluto
2026-10-05 17:29:20 +08:00
committed by GitHub
parent 828395d510
commit ea58834940
56 changed files with 314 additions and 162 deletions
+2 -1
View File
@@ -23,6 +23,7 @@ import {
type PermissionGrant,
} from "../domain/permissionPolicy.js";
import { err, ok, type Result } from "../domain/result.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const grantSchema = z.object({
grant_id: z.string().min(1),
@@ -39,7 +40,7 @@ const grantSchema = z.object({
});
const storeSchema = z.object({
project_id: z.string().regex(/^project_[a-f0-9]{64}$/u),
project_id: prefixedDigestSchema("project"),
project_root: z.string(),
grants: z.array(grantSchema),
});
+2 -1
View File
@@ -19,6 +19,7 @@ import {
closeBinaryInputSchema,
} from "./sessionLifecycleInputs.js";
import { binarySessionInputSchema } from "./sessionStatusContract.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
/** Return the current canonical Evidence bundle inline. */
export const getEvidenceBundleInputSchema = z.strictObject({});
@@ -58,7 +59,7 @@ export const listUnknownsInputSchema = z.strictObject({
/** Exact residual-unknown identity to revalidate. */
export const verifyUnknownResolutionInputSchema = z.strictObject({
unknown_id: z.string().regex(/^unk_[a-f0-9]{64}$/u),
unknown_id: prefixedDigestSchema("unk"),
});
export {
+2 -1
View File
@@ -14,6 +14,7 @@ import {
type ProviderRejectionCode,
} from "./providerSelection.js";
import { analysisErrorProjectionSchema } from "./errorSchemas.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
/** Inline result with its complete Evidence record. */
export const inlineEvidenceRecordSchema = evidenceEnvelopeSchema.omit({
@@ -23,7 +24,7 @@ export const inlineEvidenceRecordSchema = evidenceEnvelopeSchema.omit({
export const evidenceResultOf = (schema: z.ZodType) =>
z.strictObject({
result: schema,
evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
evidence_id: prefixedDigestSchema("ev"),
evidence: inlineEvidenceRecordSchema,
});
+1 -2
View File
@@ -4,8 +4,7 @@ import canonicalize from "canonicalize";
import { z } from "zod";
import { jsonObjectSchema, type JsonValue } from "./jsonValue.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
import { digestSchema } from "./../domain/digests.js";
/** Concrete provider identity committed by an analysis profile. */
export const committedProviderSchema = z.object({
+3 -2
View File
@@ -26,8 +26,9 @@ import {
jsonValueSchema,
type JsonValue,
} from "./jsonValue.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const architectureSchema = z.enum(["x86", "x86_64", "arm", "arm64"]);
const formatSchema = z.enum([
"analysis-database",
@@ -86,7 +87,7 @@ const bindingSchema = z
});
});
const entrySchema = z.object({
query_id: z.string().regex(/^query_[a-f0-9]{64}$/u),
query_id: prefixedDigestSchema("query"),
operation: z.string().min(1),
parameters: jsonObjectSchema,
execution: z.object({
+5 -4
View File
@@ -5,13 +5,14 @@ import { z } from "zod";
import { parseArtifactInventoryEvidence } from "./artifactInventoryEvidence.js";
import { evidenceSchema } from "./evidence.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const pathSchema = z.string().min(1);
const componentSchema = z.strictObject({
path: pathSchema,
artifact_id: z.string().regex(/^art_[a-f0-9]{64}$/u),
artifact_id: prefixedDigestSchema("art"),
sha256: digestSchema,
format: z.string().min(1),
});
@@ -23,7 +24,7 @@ export const androidApplicationProjectionInputSchema = z.strictObject({
/** Deterministic, execution-free Android application inventory projection. */
export const androidApplicationProjectionResultSchema = z.strictObject({
projection_id: z.string().regex(/^adp_[a-f0-9]{64}$/u),
projection_id: prefixedDigestSchema("adp"),
root_sha256: digestSchema,
root_format: z.literal("apk"),
source_evidence_ids: z.array(evidenceIdSchema).min(1),
+5 -4
View File
@@ -5,14 +5,15 @@ import { z } from "zod";
import { parseArtifactInventoryEvidence } from "./artifactInventoryEvidence.js";
import { evidenceSchema } from "./evidence.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const pathSchema = z.string().min(1);
const componentSchema = z.strictObject({
path: pathSchema,
artifact_id: z.string().regex(/^art_[a-f0-9]{64}$/u),
artifact_id: prefixedDigestSchema("art"),
sha256: digestSchema,
format: z.string().min(1),
});
@@ -24,7 +25,7 @@ export const appleApplicationProjectionInputSchema = z.strictObject({
/** Deterministic, execution-free Apple application inventory projection. */
export const appleApplicationProjectionResultSchema = z.strictObject({
projection_id: z.string().regex(/^aap_[a-f0-9]{64}$/u),
projection_id: prefixedDigestSchema("aap"),
root_sha256: digestSchema,
root_format: z.literal("ipa"),
source_evidence_ids: z.array(evidenceIdSchema).min(1),
+4 -3
View File
@@ -11,8 +11,9 @@ import {
parseArtifactInventoryEvidence,
type InventorySet,
} from "./artifactInventoryEvidence.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const comparisonStatusSchema = z.enum([
"unchanged",
"added",
@@ -73,8 +74,8 @@ const artifactChangeSchema = z.object({
/** Deterministic artifact comparison with every change returned inline. */
export const artifactComparisonResultSchema = z.object({
status: comparisonStatusSchema,
left_manifest_id: z.string().regex(/^agm_[a-f0-9]{64}$/u),
right_manifest_id: z.string().regex(/^agm_[a-f0-9]{64}$/u),
left_manifest_id: prefixedDigestSchema("agm"),
right_manifest_id: prefixedDigestSchema("agm"),
summary: z.object({
unchanged: z.number().int().min(0),
added: z.number().int().min(0),
+7 -6
View File
@@ -1,12 +1,13 @@
import { z } from "zod";
import { prefixedDigestSchema } from "./../domain/digests.js";
const sha256Schema = z.string().regex(/^[a-f0-9]{64}$/u);
const artifactIdSchema = z.string().regex(/^art_[a-f0-9]{64}$/u);
const occurrenceIdSchema = z.string().regex(/^occ_[a-f0-9]{64}$/u);
const edgeIdSchema = z.string().regex(/^edge_[a-f0-9]{64}$/u);
const manifestIdSchema = z.string().regex(/^agm_[a-f0-9]{64}$/u);
const extractionIdSchema = z.string().regex(/^aex_[a-f0-9]{64}$/u);
const contradictionIdSchema = z.string().regex(/^ic_[a-f0-9]{64}$/u);
const artifactIdSchema = prefixedDigestSchema("art");
const occurrenceIdSchema = prefixedDigestSchema("occ");
const edgeIdSchema = prefixedDigestSchema("edge");
const manifestIdSchema = prefixedDigestSchema("agm");
const extractionIdSchema = prefixedDigestSchema("aex");
const contradictionIdSchema = prefixedDigestSchema("ic");
const boundedRelativePathSchema = z
.string()
.min(1)
+13 -12
View File
@@ -9,13 +9,14 @@ import {
} from "./artifactGraph.js";
import { evidenceSchema, parseEvidence, type Evidence } from "./evidence.js";
import { jsonValueSchema } from "./jsonValue.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const textSchema = z.string().min(1);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const artifactIdSchema = z.string().regex(/^art_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const artifactIdSchema = prefixedDigestSchema("art");
const inspectionObservationSchema = z.strictObject({
observation_id: z.string().regex(/^aio_[a-f0-9]{64}$/u),
observation_id: prefixedDigestSchema("aio"),
kind: z.enum(["root-manifest", "artifact", "occurrence", "integrity"]),
subject: textSchema,
value: jsonValueSchema,
@@ -23,7 +24,7 @@ const inspectionObservationSchema = z.strictObject({
});
const inspectionRelationshipSchema = z.strictObject({
relationship_id: z.string().regex(/^air_[a-f0-9]{64}$/u),
relationship_id: prefixedDigestSchema("air"),
relation: z.enum([
"contains",
"extracts",
@@ -35,13 +36,13 @@ const inspectionRelationshipSchema = z.strictObject({
]),
source_artifact_id: artifactIdSchema,
target_artifact_id: artifactIdSchema,
occurrence_id: z.string().regex(/^occ_[a-f0-9]{64}$/u),
occurrence_id: prefixedDigestSchema("occ"),
logical_path: textSchema.nullable(),
evidence_id: evidenceIdSchema,
});
const inspectionHypothesisSchema = z.strictObject({
hypothesis_id: z.string().regex(/^aih_[a-f0-9]{64}$/u),
hypothesis_id: prefixedDigestSchema("aih"),
statement: textSchema,
confidence: z.enum(["medium", "low"]),
basis_evidence_ids: z.array(evidenceIdSchema).min(1),
@@ -49,9 +50,9 @@ const inspectionHypothesisSchema = z.strictObject({
});
const inspectionContradictionSchema = z.strictObject({
contradiction_id: z.string().regex(/^aic_[a-f0-9]{64}$/u),
contradiction_id: prefixedDigestSchema("aic"),
statement: textSchema,
occurrence_id: z.string().regex(/^occ_[a-f0-9]{64}$/u),
occurrence_id: prefixedDigestSchema("occ"),
declared_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
observed_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
evidence_id: evidenceIdSchema,
@@ -69,7 +70,7 @@ const nextProbeSchema = z.strictObject({
});
const unexploredBranchSchema = z.strictObject({
branch_id: z.string().regex(/^aib_[a-f0-9]{64}$/u),
branch_id: prefixedDigestSchema("aib"),
reason: z.enum(["format-specific-analysis-required", "unknown-format"]),
detail: textSchema,
next_probe: nextProbeSchema.nullable(),
@@ -78,9 +79,9 @@ const unexploredBranchSchema = z.strictObject({
/** Provider-neutral inspection result with its atomic source Evidence. */
export const artifactInspectionResultSchema = z.strictObject({
inspection_id: z.string().regex(/^ai_[a-f0-9]{64}$/u),
inspection_id: prefixedDigestSchema("ai"),
subject: z.strictObject({
manifest_id: z.string().regex(/^agm_[a-f0-9]{64}$/u),
manifest_id: prefixedDigestSchema("agm"),
root_artifact_id: artifactIdSchema,
root_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
root_format: textSchema,
@@ -88,7 +89,7 @@ export const artifactInspectionResultSchema = z.strictObject({
substeps: z
.array(
z.strictObject({
substep_id: z.string().regex(/^ais_[a-f0-9]{64}$/u),
substep_id: prefixedDigestSchema("ais"),
operation: z.literal("inventory_artifact"),
status: z.literal("completed"),
evidence_id: evidenceIdSchema,
+2 -1
View File
@@ -3,6 +3,7 @@ import { z } from "zod";
import { browserCompletenessSchema } from "./browserCompleteness.js";
import { webTextArtifactSchema } from "./webContentArtifact.js";
import { jsonShapeSchema } from "./jsonShape.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const browserVersionSchema = z.object({
product: z.string(),
@@ -96,7 +97,7 @@ const browserScriptSchema = z.object({
source: browserScriptSourceSchema,
});
const browserResourceSchema = z.object({
resource_key: z.string().regex(/^res_[a-f0-9]{64}$/u),
resource_key: prefixedDigestSchema("res"),
url: z.string(),
origin: z.string().nullable(),
type: z.string(),
+1 -1
View File
@@ -5,8 +5,8 @@ import { z } from "zod";
import { emptyArraySchema } from "./emptyArraySchema.js";
import { sanitizedBrowserUrlSchema } from "./browserObservation.js";
import { webScreenshotArtifactSchema } from "./webScreenshot.js";
import { digestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const textArtifactSchema = z
.strictObject({
sha256: digestSchema,
+3 -2
View File
@@ -8,9 +8,10 @@ import {
type EvidenceBundle,
} from "./evidenceBundle.js";
import type { ResidualUnknown } from "./residualUnknown.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const classificationSchema = z.enum([
"added",
"removed",
+2 -1
View File
@@ -2,6 +2,7 @@ import { z } from "zod";
import { emptyArraySchema } from "./emptyArraySchema.js";
import { evidenceSchema } from "./evidence.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const addressSchema = z
.string()
@@ -16,7 +17,7 @@ const inputAddressSchema = z
.replace(/%[0-9a-fA-F]{2}/gu, (escape) => escape.toUpperCase());
return `${space}0x${BigInt(address.slice(separator)).toString(16)}`;
});
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
/** Normalize a hexadecimal offset while preserving its optional address space. */
export const parseCallPathAddress = (input: unknown): string =>
+2 -1
View File
@@ -9,8 +9,9 @@ import {
PROCESS_COMPARISON_DIMENSIONS,
processCaptureComparisonSchema,
} from "./processCapture.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
/** Input for aggregating existing comparison Evidence. */
export const changedBehaviorInputSchema = z.object({
+3 -2
View File
@@ -8,9 +8,10 @@ import {
evidenceCompletionRecordSchema,
type EvidenceCompletionLedger,
} from "./evidenceCompletionLedger.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const identifierSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._-]*$/u);
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const identitySchema = z.strictObject({
id: identifierSchema,
version: z.string().min(1),
@@ -110,7 +111,7 @@ const manifestClaimSchema = reportClaimSchema.omit({
evidence_ids: true,
});
const completionManifestObjectSchema = z.strictObject({
manifest_id: z.string().regex(/^ecm_[a-f0-9]{64}$/u),
manifest_id: prefixedDigestSchema("ecm"),
verifier: identitySchema,
environment: environmentSchema,
skill_digests: z.array(skillDigestSchema).min(1),
+2 -1
View File
@@ -6,8 +6,9 @@ import { z } from "zod";
import { evidenceEnvelopeSchema } from "./evidence.js";
import { evidenceBundleSchema } from "./evidenceBundle.js";
import { err, ok, type Result } from "./result.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const conformancePackageIdSchema = z.string().regex(/^cp_[a-f0-9]{64}$/u);
const conformancePackageIdSchema = prefixedDigestSchema("cp");
const scenarioIdSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._-]*$/u);
+67
View File
@@ -0,0 +1,67 @@
import { describe, expect, it } from "vitest";
import {
digestSchema,
isDigest,
isPrefixedDigest,
prefixedDigestSchema,
SHA256_PATTERN,
} from "./digests.js";
const DIGEST = "a".repeat(64);
const OTHER_DIGEST = "b".repeat(64);
describe("digest shapes", () => {
it("accepts a lowercase hex sha256", () => {
expect(digestSchema.parse(DIGEST)).toBe(DIGEST);
expect(isDigest(DIGEST)).toBe(true);
});
it.each([
["uppercase", DIGEST.toUpperCase()],
["too short", "a".repeat(63)],
["too long", "a".repeat(65)],
["non-hex", "g".repeat(64)],
["prefixed", `ev_${DIGEST}`],
])("rejects a %s digest", (_label, value) => {
expect(digestSchema.safeParse(value).success).toBe(false);
expect(isDigest(value)).toBe(false);
});
it("rejects non-string values", () => {
for (const value of [null, undefined, 42, {}, []])
expect(isDigest(value)).toBe(false);
});
it("keeps identifier families apart", () => {
expect(prefixedDigestSchema("ev").parse(`ev_${DIGEST}`)).toBe(
`ev_${DIGEST}`,
);
// The point of the prefix: an identifier from one family must not satisfy
// another, or a mis-pasted id would resolve to the wrong object.
expect(prefixedDigestSchema("ev").safeParse(`art_${DIGEST}`).success).toBe(
false,
);
expect(prefixedDigestSchema("ev").safeParse(DIGEST).success).toBe(false);
expect(isPrefixedDigest(`ev_${DIGEST}`, "ev")).toBe(true);
expect(isPrefixedDigest(`ev_${DIGEST}`, "art")).toBe(false);
});
it("distinguishes nested prefixes from their common ancestor", () => {
// `jag_node_` must not validate as `jag_` even though it starts with it.
expect(
prefixedDigestSchema("jag").safeParse(`jag_node_${DIGEST}`).success,
).toBe(false);
expect(prefixedDigestSchema("jag_node").parse(`jag_node_${DIGEST}`)).toBe(
`jag_node_${DIGEST}`,
);
expect(prefixedDigestSchema("jag").parse(`jag_${OTHER_DIGEST}`)).toBe(
`jag_${OTHER_DIGEST}`,
);
});
it("exposes the pattern for callers that cannot use zod", () => {
expect(SHA256_PATTERN.test(DIGEST)).toBe(true);
expect(SHA256_PATTERN.test(DIGEST.toUpperCase())).toBe(false);
});
});
+42
View File
@@ -0,0 +1,42 @@
import { z } from "zod";
/**
* Canonical digest and identifier shapes.
*
* These were previously a hand-copied regex in ~30 modules: 32 local
* `digestSchema` definitions plus a distinct literal for each of roughly
* thirty `prefix_hash` identifier families. Nothing kept them in step, so a
* change to what counts as a digest had to be found and repeated by hand.
*
* One owner means the shape is stated once, and a new identifier family
* cannot accidentally invent its own spelling of "lowercase sha256".
*/
/** Lowercase hex SHA-256, as every digest in the system is emitted. */
export const SHA256_PATTERN = /^[a-f0-9]{64}$/u;
/** A bare artifact/content digest. */
export const digestSchema = z.string().regex(SHA256_PATTERN);
/**
* A namespaced identifier: `<prefix>_<64 lowercase hex>`. Prefixes keep
* identifiers from different families apart at a glance and make a
* mis-pasted identifier from another family fail validation rather than
* resolve to the wrong object.
*/
export const prefixedDigestSchema = (prefix: string): z.ZodString =>
z
.string()
.regex(
new RegExp(`^${prefix}_[a-f0-9]{64}$`, "u"),
`Expected a ${prefix}_ prefixed lowercase sha256 digest`,
);
/** True when `value` is a bare digest. */
export const isDigest = (value: unknown): value is string =>
typeof value === "string" && SHA256_PATTERN.test(value);
/** True when `value` is a digest carrying `prefix`. */
export const isPrefixedDigest = (value: unknown, prefix: string): boolean =>
typeof value === "string" &&
prefixedDigestSchema(prefix).safeParse(value).success;
+3 -2
View File
@@ -3,6 +3,7 @@ import { z } from "zod";
import { browserCompletenessSchema } from "./browserCompleteness.js";
import { browserEndpointSchema } from "./browserObservation.js";
import { webTextArtifactSchema } from "./webContentArtifact.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const approvedElectronInput = {
cdp_endpoint: browserEndpointSchema,
@@ -102,7 +103,7 @@ export const electronPageInspectionSchema = z.object({
total: z.number().int().min(0),
items: z.array(
z.object({
script_key: z.string().regex(/^electron_script_[a-f0-9]{64}$/u),
script_key: prefixedDigestSchema("electron_script"),
frame_id: z.string().nullable().default(null),
file_path: z.string(),
cdp_hash: z.string(),
@@ -115,7 +116,7 @@ export const electronPageInspectionSchema = z.object({
}),
resources: z.array(
z.object({
resource_key: z.string().regex(/^electron_resource_[a-f0-9]{64}$/u),
resource_key: prefixedDigestSchema("electron_resource"),
file_path: z.string(),
type: z.string(),
mime_type: z.string(),
+4 -3
View File
@@ -9,8 +9,9 @@ import {
} from "./analysisProfile.js";
import type { BinaryTarget } from "./binaryTarget.js";
import { jsonValueSchema, type JsonValue } from "./jsonValue.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
/** Provider identity schema shared by evidence-bearing persistence formats. */
export const providerSchema = z.object({
id: z.string().min(1),
@@ -82,7 +83,7 @@ const executionEnvironmentSchema = z.object({
const evidenceBaseSchema = z
.object({
evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
evidence_id: prefixedDigestSchema("ev"),
subject: subjectSchema.nullable(),
provider: providerSchema,
predicate_type: z.string().min(1),
@@ -95,7 +96,7 @@ const evidenceBaseSchema = z
environment: executionEnvironmentSchema.nullable(),
limitations: z.array(z.string()),
locations: z.array(evidenceLocationSchema),
evidence_links: z.array(z.string().regex(/^ev_[a-f0-9]{64}$/u)),
evidence_links: z.array(prefixedDigestSchema("ev")),
})
.strict();
+3 -2
View File
@@ -2,8 +2,9 @@ import { createHash } from "node:crypto";
import canonicalize from "canonicalize";
import { z } from "zod";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const claimIdSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._-]*$/u);
/** Terminal outcome recorded for one verifier claim. */
@@ -33,7 +34,7 @@ const completionSummarySchema = z.strictObject({
});
const completionLedgerObjectSchema = z.strictObject({
ledger_id: z.string().regex(/^ecl_[a-f0-9]{64}$/u),
ledger_id: prefixedDigestSchema("ecl"),
records: z.array(evidenceCompletionRecordSchema).min(1),
summary: completionSummarySchema,
});
+3 -2
View File
@@ -1,5 +1,7 @@
import { z } from "zod";
import { evidenceSchema } from "./evidence.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const comparisonStatusSchema = z.enum([
"unchanged",
@@ -17,8 +19,7 @@ const dimensionNameSchema = z.enum([
"strings_names",
"cfg",
]);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
/** Inputs for explicit function-to-function comparison. */
export const functionComparisonInputSchema = z.strictObject({
+3 -2
View File
@@ -4,9 +4,10 @@ import { z } from "zod";
import { javascriptApplicationGraphSchema } from "./javascriptApplicationGraph.js";
import { javaScriptSemanticGraphSchema } from "./javascriptSemanticGraph.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const countSchema = z.number().int().min(0);
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
/** Public target-free request for static JavaScript application analysis. */
export const analyzeJavaScriptApplicationInputSchema = z.strictObject({
@@ -61,7 +62,7 @@ export const javascriptApplicationAnalysisResultSchema = z
input_path: z.string().min(1),
format: z.enum(["asar", "directory"]),
root_artifact_sha256: digestSchema,
inventory_manifest_id: z.string().regex(/^agm_[a-f0-9]{64}$/u),
inventory_manifest_id: prefixedDigestSchema("agm"),
inventory_graph_sha256: digestSchema,
graph: javascriptApplicationGraphSchema,
summary: electronBoundarySummarySchema,
@@ -1,6 +1,7 @@
import { z } from "zod";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const boundedTextSchema = z.string().min(1);
const boundedKeySchema = z.string().min(1);
const unsafePathSegments = new Set(["", ".", ".."]);
@@ -68,7 +69,7 @@ const unavailableFactSchema = z.strictObject({
const availableArtifactSchema = z
.strictObject({
available: z.literal(true),
artifact_id: z.string().regex(/^art_[a-f0-9]{64}$/u),
artifact_id: prefixedDigestSchema("art"),
sha256: digestSchema,
})
.superRefine((artifact, context) => {
@@ -265,7 +266,7 @@ const applicationGraphEvidenceBaseSchema = z.strictObject({
extractor: applicationExtractorSchema,
coverage: applicationCoverageSchema,
limitations: z.array(boundedTextSchema),
evidence_ids: z.array(z.string().regex(/^ev_[a-f0-9]{64}$/u)),
evidence_ids: z.array(prefixedDigestSchema("ev")),
});
type EvidenceValue = z.infer<typeof applicationGraphEvidenceBaseSchema>;
@@ -6,6 +6,7 @@ import {
applicationNodeIdentitySchema,
} from "./javascriptApplicationEvidenceSchemas.js";
import { jsonValueSchema } from "./jsonValue.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const boundedTextSchema = z.string().min(1);
@@ -84,7 +85,7 @@ const applicationNodeObservationInputSchema = z.strictObject({
/** One immutable, evidence-bearing observation attached to an entity. */
export const applicationNodeObservationSchema =
applicationNodeObservationInputSchema.extend({
observation_id: z.string().regex(/^jag_observation_[a-f0-9]{64}$/u),
observation_id: prefixedDigestSchema("jag_observation"),
identifier_strategy: z.strictObject({
strategy: z.literal("semantic-content-sha256"),
stability: z.literal("observation-exact"),
@@ -100,7 +101,7 @@ export const applicationNodeInputSchema = z.strictObject({
/** One stable application entity with one or more bounded observations. */
export const applicationNodeSchema = z.strictObject({
node_id: z.string().regex(/^jag_node_[a-f0-9]{64}$/u),
node_id: prefixedDigestSchema("jag_node"),
kind: applicationNodeKindSchema,
identity: applicationNodeIdentitySchema,
observations: z.array(applicationNodeObservationSchema).min(1),
@@ -108,8 +109,8 @@ export const applicationNodeSchema = z.strictObject({
/** One directed relationship before its semantic identifier is derived. */
export const applicationEdgeInputSchema = z.strictObject({
source_node_id: z.string().regex(/^jag_node_[a-f0-9]{64}$/u),
target_node_id: z.string().regex(/^jag_node_[a-f0-9]{64}$/u),
source_node_id: prefixedDigestSchema("jag_node"),
target_node_id: prefixedDigestSchema("jag_node"),
relation: applicationRelationSchema,
properties: applicationPropertiesSchema,
evidence: applicationGraphEvidenceSchema,
@@ -117,7 +118,7 @@ export const applicationEdgeInputSchema = z.strictObject({
/** One directed, evidence-bearing application relationship. */
export const applicationEdgeSchema = applicationEdgeInputSchema.extend({
edge_id: z.string().regex(/^jag_edge_[a-f0-9]{64}$/u),
edge_id: prefixedDigestSchema("jag_edge"),
identifier_strategy: z.strictObject({
strategy: z.literal("semantic-content-sha256"),
stability: z.literal("relationship-exact"),
@@ -127,7 +128,7 @@ export const applicationEdgeSchema = applicationEdgeInputSchema.extend({
/** Graph content before its top-level semantic identifier is derived. */
export const javascriptApplicationGraphInputSchema = z.strictObject({
schema: z.literal("JavaScriptApplicationGraph"),
root_node_ids: z.array(z.string().regex(/^jag_node_[a-f0-9]{64}$/u)).min(1),
root_node_ids: z.array(prefixedDigestSchema("jag_node")).min(1),
nodes: z.array(applicationNodeSchema).min(1),
edges: z.array(applicationEdgeSchema),
coverage: applicationCoverageSchema,
@@ -137,7 +138,7 @@ export const javascriptApplicationGraphInputSchema = z.strictObject({
/** Strict stored shape for a JavaScript Application Graph. */
export const javascriptApplicationGraphRecordSchema =
javascriptApplicationGraphInputSchema.extend({
graph_id: z.string().regex(/^jag_[a-f0-9]{64}$/u),
graph_id: prefixedDigestSchema("jag"),
});
/** Immutable entity in a JavaScript Application Graph. */
@@ -4,9 +4,10 @@ import { emptyArraySchema } from "./emptyArraySchema.js";
import { evidenceSchema } from "./evidence.js";
import { javascriptApplicationGraphSchema } from "./javascriptApplicationGraph.js";
import { JAVASCRIPT_APPLICATION_NODE_KINDS } from "./javascriptApplicationGraphSchemas.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const nodeIdSchema = z.string().regex(/^jag_node_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const nodeIdSchema = prefixedDigestSchema("jag_node");
const textSchema = z.string().min(1);
/** Two authenticated application versions and their native observations. */
@@ -93,7 +94,7 @@ const rightAmbiguousMatchSchema = z.strictObject({
});
const comparisonItemContextShape = {
item_id: z.string().regex(/^javc_item_[a-f0-9]{64}$/u),
item_id: prefixedDigestSchema("javc_item"),
node_kind: z.enum(JAVASCRIPT_APPLICATION_NODE_KINDS),
dimensions: z.array(
z.enum([
@@ -158,15 +159,15 @@ const comparisonCoverageSchema = z.strictObject({
/** Tiered module/entity matching plus its complete cross-version change graph. */
export const applicationVersionComparisonResultSchema = z
.strictObject({
comparison_id: z.string().regex(/^javc_[a-f0-9]{64}$/u),
comparison_id: prefixedDigestSchema("javc"),
left: z.strictObject({
evidence_id: evidenceIdSchema,
graph_id: z.string().regex(/^jag_[a-f0-9]{64}$/u),
graph_id: prefixedDigestSchema("jag"),
root_artifact_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
}),
right: z.strictObject({
evidence_id: evidenceIdSchema,
graph_id: z.string().regex(/^jag_[a-f0-9]{64}$/u),
graph_id: prefixedDigestSchema("jag"),
root_artifact_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
}),
summary: z.strictObject({
@@ -1,8 +1,7 @@
import { createHash } from "node:crypto";
import { z } from "zod";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
import { digestSchema } from "./../domain/digests.js";
export const javascriptExportInstrumentationInputSchema = z.strictObject({
artifact_path: z.string().min(1),
@@ -1,10 +1,11 @@
import { z } from "zod";
import { evidenceSchema } from "./evidence.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const graphIdSchema = z.string().regex(/^jag_[a-f0-9]{64}$/u);
const nodeIdSchema = z.string().regex(/^jag_node_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const graphIdSchema = prefixedDigestSchema("jag");
const nodeIdSchema = prefixedDigestSchema("jag_node");
const textSchema = z.string().min(1);
const selectorTextSchema = textSchema;
const semanticPrimitiveSchema = z.union([
@@ -229,7 +230,7 @@ const discriminantSchema = z.strictObject({
});
const comparisonChangeSchema = z.strictObject({
change_id: z.string().regex(/^jesc_change_[a-f0-9]{64}$/u),
change_id: prefixedDigestSchema("jesc_change"),
status: z.enum(["added", "removed", "changed", "unknown"]),
path: jsonPointerSchema,
discriminant: discriminantSchema.nullable(),
@@ -243,7 +244,7 @@ const comparisonChangeSchema = z.strictObject({
/** Static export-return comparison with explicit unknown semantics. */
export const javaScriptExportShapeComparisonResultSchema = z.strictObject({
comparison_id: z.string().regex(/^jesc_[a-f0-9]{64}$/u),
comparison_id: prefixedDigestSchema("jesc"),
left: selectorResultSchema,
right: selectorResultSchema,
summary: z.strictObject({
+8 -7
View File
@@ -2,11 +2,12 @@ import { z } from "zod";
import { evidenceSchema, providerSchema } from "./evidence.js";
import { javascriptApplicationGraphSchema } from "./javascriptApplicationGraph.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const nodeIdSchema = z.string().regex(/^jag_node_[a-f0-9]{64}$/u);
const edgeIdSchema = z.string().regex(/^jag_edge_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const nodeIdSchema = prefixedDigestSchema("jag_node");
const edgeIdSchema = prefixedDigestSchema("jag_edge");
const boundedTextSchema = z.string().min(1);
/** Literal starting point for one application feature trace. */
@@ -51,7 +52,7 @@ const seedMatchSchema = z.strictObject({
});
const tracePathSchema = z.strictObject({
path_id: z.string().regex(/^jatp_[a-f0-9]{64}$/u),
path_id: prefixedDigestSchema("jatp"),
start_node_id: nodeIdSchema,
end_node_id: nodeIdSchema,
end_kind: z.string().min(1),
@@ -83,9 +84,9 @@ const nativeHandoffSchema = z.strictObject({
/** Evidence-preserving complete reachable subgraph and native-analysis handoffs. */
export const applicationFeatureTraceResultSchema = z.strictObject({
trace_id: z.string().regex(/^jatr_[a-f0-9]{64}$/u),
trace_id: prefixedDigestSchema("jatr"),
source_evidence_id: evidenceIdSchema,
source_graph_id: z.string().regex(/^jag_[a-f0-9]{64}$/u),
source_graph_id: prefixedDigestSchema("jag"),
seed: applicationFeatureSeedSchema,
direction: z.enum(["outgoing", "incoming", "both"]),
seed_matches: z.array(seedMatchSchema),
+1 -1
View File
@@ -1,8 +1,8 @@
import { z } from "zod";
import { evidenceEnvelopeSchema } from "./evidence.js";
import { digestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const absolutePathSchema = z.string().startsWith("/");
const aliasSchema = z
.string()
+2 -1
View File
@@ -1,6 +1,7 @@
import { z } from "zod";
import { browserEndpointSchema } from "./browserObservation.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const observationTextSchema = z.string().min(1);
@@ -102,7 +103,7 @@ export type JavaScriptRuntimeTargetList = z.infer<
>;
const javascriptRuntimeScriptSchema = z.strictObject({
script_key: z.string().regex(/^v8_script_[a-f0-9]{64}$/u),
script_key: prefixedDigestSchema("v8_script"),
location: javascriptRuntimeLocationSchema,
execution_context_key: z.string().nullable(),
cdp_hash: z.string().nullable(),
@@ -8,10 +8,11 @@ import {
compareCodePoints,
javascriptApplicationGraphSchema,
} from "./javascriptApplicationGraph.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const nodeIdSchema = z.string().regex(/^jag_node_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const nodeIdSchema = prefixedDigestSchema("jag_node");
const boundedTextSchema = z.string().min(1);
const safePrefixSchema = z
.string()
@@ -137,10 +138,10 @@ export const reconcileJavaScriptRuntimeInputSchema = z
});
const layerSummarySchema = z.strictObject({
layer_id: z.string().regex(/^jrl_[a-f0-9]{64}$/u),
layer_id: prefixedDigestSchema("jrl"),
role: z.enum(["application", "cache", "assets"]),
evidence_id: evidenceIdSchema,
graph_id: z.string().regex(/^jag_[a-f0-9]{64}$/u),
graph_id: prefixedDigestSchema("jag"),
root_artifact_sha256: digestSchema,
input_path: z.string().min(1),
format: z.enum(["asar", "directory"]),
@@ -178,7 +179,7 @@ const reconciliationReasonSchema = z.enum([
]);
const reconciliationItemShape = {
reconciliation_id: z.string().regex(/^jrr_item_[a-f0-9]{64}$/u),
reconciliation_id: prefixedDigestSchema("jrr_item"),
entity_kind: z.enum(["target", "frame", "script", "worker"]),
runtime_evidence_id: evidenceIdSchema,
runtime_node_id: nodeIdSchema,
@@ -196,7 +197,7 @@ const reconciliationItemShape = {
candidate_static_count: z.number().int().min(0),
candidate_static_nodes: z.array(
z.strictObject({
static_layer_id: z.string().regex(/^jrl_[a-f0-9]{64}$/u),
static_layer_id: prefixedDigestSchema("jrl"),
static_node_id: nodeIdSchema,
}),
),
@@ -204,7 +205,7 @@ const reconciliationItemShape = {
const reconciliationItemSchema = z.union([
z.strictObject({
...reconciliationItemShape,
static_layer_id: z.string().regex(/^jrl_[a-f0-9]{64}$/u),
static_layer_id: prefixedDigestSchema("jrl"),
static_node_id: nodeIdSchema,
status: z.literal("matched"),
}),
@@ -217,7 +218,7 @@ const reconciliationItemSchema = z.union([
]);
const staticLoadStateSchema = z.strictObject({
static_layer_id: z.string().regex(/^jrl_[a-f0-9]{64}$/u),
static_layer_id: prefixedDigestSchema("jrl"),
static_node_id: nodeIdSchema,
kind: z.enum(["javascript-asset", "javascript-chunk", "javascript-module"]),
status: z.enum([
@@ -238,7 +239,7 @@ const staticLoadStateSchema = z.strictObject({
/** Deterministic static/passive-runtime reconciliation with a combined JAG. */
export const javascriptRuntimeReconciliationResultSchema = z.strictObject({
reconciliation_id: z.string().regex(/^jrr_[a-f0-9]{64}$/u),
reconciliation_id: prefixedDigestSchema("jrr"),
static_layers: z.array(layerSummarySchema).min(1),
runtime_captures: z.array(captureSummarySchema).min(1),
graph: javascriptApplicationGraphSchema,
+7 -6
View File
@@ -2,10 +2,11 @@ import { z } from "zod";
import { applicationGraphEvidenceSchema } from "./javascriptApplicationEvidenceSchemas.js";
import { jsonValueSchema } from "./jsonValue.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const boundedTextSchema = z.string().min(1);
const semanticNodeIdSchema = z.string().regex(/^jsrg_node_[a-f0-9]{64}$/u);
const semanticNodeIdSchema = prefixedDigestSchema("jsrg_node");
const semanticRelationIdSchema = z
.string()
.regex(/^jsrg_relation_[a-f0-9]{64}$/u);
@@ -203,7 +204,7 @@ export const javaScriptSemanticNodeInputSchema = z.strictObject({
kind: z.enum(JAVASCRIPT_SEMANTIC_NODE_KINDS),
identity: semanticNodeIdentitySchema,
function_node_id: semanticNodeIdSchema.nullable(),
application_node_ids: z.array(z.string().regex(/^jag_node_[a-f0-9]{64}$/u)),
application_node_ids: z.array(prefixedDigestSchema("jag_node")),
label: z.string().min(1).nullable(),
properties: semanticPropertiesSchema,
evidence: applicationGraphEvidenceSchema,
@@ -300,7 +301,7 @@ export const javaScriptSemanticFingerprintInputSchema = z.strictObject({
/** One canonical function fingerprint record. */
export const javaScriptSemanticFingerprintSchema =
javaScriptSemanticFingerprintInputSchema.extend({
fingerprint_id: z.string().regex(/^jsrg_fingerprint_[a-f0-9]{64}$/u),
fingerprint_id: prefixedDigestSchema("jsrg_fingerprint"),
fingerprint_sha256: digestSchema,
});
@@ -331,7 +332,7 @@ const graphCoverageSchema = z.strictObject({
export const javaScriptSemanticGraphInputSchema = z.strictObject({
schema: z.literal("JavaScriptSemanticRelationGraph"),
root_artifact_sha256: digestSchema,
application_graph_id: z.string().regex(/^jag_[a-f0-9]{64}$/u),
application_graph_id: prefixedDigestSchema("jag"),
root_node_ids: z.array(semanticNodeIdSchema).min(1),
nodes: z.array(javaScriptSemanticNodeSchema).min(1),
relations: z.array(javaScriptSemanticRelationSchema),
@@ -344,7 +345,7 @@ export const javaScriptSemanticGraphInputSchema = z.strictObject({
/** Stored JavaScript Semantic Relation Graph. */
export const javaScriptSemanticGraphRecordSchema =
javaScriptSemanticGraphInputSchema.extend({
graph_id: z.string().regex(/^jsrg_[a-f0-9]{64}$/u),
graph_id: prefixedDigestSchema("jsrg"),
});
/** Canonical semantic node. */
+6 -5
View File
@@ -8,9 +8,10 @@ import {
javaScriptSemanticUnknownSchema,
} from "./javascriptSemanticGraphSchemas.js";
import { jsonValueSchema } from "./jsonValue.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const semanticNodeIdSchema = z.string().regex(/^jsrg_node_[a-f0-9]{64}$/u);
const semanticNodeIdSchema = prefixedDigestSchema("jsrg_node");
const literalSeedSchema = z.strictObject({
kind: z.literal("literal"),
@@ -32,7 +33,7 @@ export const javaScriptSemanticQuerySeedSchema = z.discriminatedUnion("kind", [
}),
z.strictObject({
kind: z.literal("application-node"),
node_id: z.string().regex(/^jag_node_[a-f0-9]{64}$/u),
node_id: prefixedDigestSchema("jag_node"),
}),
literalSeedSchema,
z.strictObject({
@@ -87,8 +88,8 @@ export const javaScriptSemanticQueryInputSchema = z.strictObject({
/** Deterministic semantic trace result. */
export const javaScriptSemanticQueryResultSchema = z.strictObject({
query_id: z.string().regex(/^jsrq_[a-f0-9]{64}$/u),
source_graph_id: z.string().regex(/^jsrg_[a-f0-9]{64}$/u),
query_id: prefixedDigestSchema("jsrq"),
source_graph_id: prefixedDigestSchema("jsrg"),
seed: javaScriptSemanticQuerySeedSchema,
direction: javaScriptSemanticQueryInputSchema.shape.direction,
status: z.enum(["found", "no-match", "ambiguous", "partial", "unsupported"]),
+2 -1
View File
@@ -5,8 +5,9 @@ import {
javaScriptSemanticQueryInputSchema,
javaScriptSemanticQueryResultSchema,
} from "./javascriptSemanticQuerySchemas.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
/** Authenticated application Evidence plus one bounded semantic query. */
export const traceJavaScriptSemanticsInputSchema = z.strictObject({
+4 -3
View File
@@ -30,9 +30,10 @@ import {
addBoundaryNodes,
addMemberNodes,
} from "./managedApplicationGraphNodes.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const textSchema = z.string().min(1);
/** Authenticated managed Evidence records projected into the application graph. */
@@ -57,7 +58,7 @@ export const projectManagedApplicationGraphInputSchema = z
/** Managed-code projection result containing a validated application graph. */
export const managedApplicationGraphResultSchema = z.strictObject({
projection_id: z.string().regex(/^magp_[a-f0-9]{64}$/u),
projection_id: prefixedDigestSchema("magp"),
root_artifact_sha256: digestSchema,
source_evidence: z.strictObject({
managed_artifact_evidence_id: evidenceIdSchema.nullable(),
+1 -1
View File
@@ -1,6 +1,6 @@
import { z } from "zod";
import { digestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const tokenSchema = z.string().regex(/^0x[0-9a-f]{8}$/u);
const offsetSchema = z.number().int().min(0);
+6 -5
View File
@@ -18,9 +18,10 @@ import {
buildMethodItems,
} from "./managedMemberComparisonItems.js";
import { keyMembers, sha256 } from "./managedMemberComparisonMatch.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const tokenSchema = z.string().regex(/^0x[0-9a-f]{8}$/u);
const boundedTextSchema = z.string().min(1);
@@ -120,7 +121,7 @@ const comparisonItemContextShape = {
const methodComparisonItemSchema = comparisonItemSchema(
{
...comparisonItemContextShape,
item_id: z.string().regex(/^mmc_method_[a-f0-9]{64}$/u),
item_id: prefixedDigestSchema("mmc_method"),
dimensions: z.array(
z.enum([
"signature",
@@ -139,14 +140,14 @@ const methodComparisonItemSchema = comparisonItemSchema(
const fieldComparisonItemSchema = comparisonItemSchema(
{
...comparisonItemContextShape,
item_id: z.string().regex(/^mmc_field_[a-f0-9]{64}$/u),
item_id: prefixedDigestSchema("mmc_field"),
},
memberIdentitySchema.omit({ normalized_il_sha256: true }),
);
/** Obfuscation-resistant, execution-free managed member comparison. */
export const managedMemberComparisonResultSchema = z.strictObject({
comparison_id: z.string().regex(/^mmc_[a-f0-9]{64}$/u),
comparison_id: prefixedDigestSchema("mmc"),
algorithm: z.strictObject({
name: z.literal("rea-managed-member-comparison"),
token_identity: z.literal("build-local"),
@@ -3,9 +3,10 @@ import { z } from "zod";
import { emptyArraySchema } from "./emptyArraySchema.js";
import { evidenceSchema } from "./evidence.js";
import { cliMetadataGuidSchema } from "./managedArtifact.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const tokenSchema = z.string().regex(/^0x[0-9a-f]{8}$/u);
const textSchema = z.string().min(1);
@@ -22,7 +23,7 @@ const nativeSymbolSchema = z.strictObject({
export type NativeSymbol = z.infer<typeof nativeSymbolSchema>;
const pinvokeVerificationContextShape = {
item_id: z.string().regex(/^mnv_pinvoke_[a-f0-9]{64}$/u),
item_id: prefixedDigestSchema("mnv_pinvoke"),
managed: z.strictObject({
token: tokenSchema,
member_token: tokenSchema.nullable(),
@@ -126,7 +127,7 @@ const verificationCoverageSchema = z.strictObject({
/** Provider-neutral managed/native verification result. */
export const managedNativeVerificationResultSchema = z
.strictObject({
verification_id: z.string().regex(/^mnv_[a-f0-9]{64}$/u),
verification_id: prefixedDigestSchema("mnv"),
algorithm: z.strictObject({
name: z.literal("rea-managed-native-verification"),
token_identity: z.literal("build-local"),
+4 -3
View File
@@ -10,9 +10,10 @@ import {
type ManagedMemberInspection,
} from "./managedArtifact.js";
import type { JsonValue } from "./jsonValue.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const tokenSchema = z.string().regex(/^0x[0-9a-f]{8}$/u);
const textSchema = z.string().min(1);
@@ -78,7 +79,7 @@ const importedMethodSchema = z.strictObject({
});
export const managedReconstructionImportResultSchema = z.strictObject({
reconstruction_id: z.string().regex(/^mre_[a-f0-9]{64}$/u),
reconstruction_id: prefixedDigestSchema("mre"),
phase: z.literal("reconstruction-import"),
executed: z.literal(false),
static_observation: z.strictObject({
+4 -3
View File
@@ -9,9 +9,10 @@ import {
managedMemberInspectionSchema,
} from "./managedArtifact.js";
import type { JsonValue } from "./jsonValue.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const tokenSchema = z.string().regex(/^0x[0-9a-f]{8}$/u);
const boundedTextSchema = z.string().min(1);
@@ -56,7 +57,7 @@ export const managedRuntimeCorrelationInputSchema = z.strictObject({
});
export const managedRuntimeCorrelationResultSchema = z.strictObject({
correlation_id: z.string().regex(/^mrc_[a-f0-9]{64}$/u),
correlation_id: prefixedDigestSchema("mrc"),
phase: z.literal("admission-plan"),
executed: z.literal(false),
authority_model: z.strictObject({
+1 -1
View File
@@ -11,8 +11,8 @@ import {
} from "./javascriptExportInstrumentation.js";
import { runtimeCharacterizationPlanSchema } from "./runtimeCharacterization.js";
import { evidenceRecordSchema } from "./evidence.js";
import { digestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const nodeCharacterizationExpectedEffectSchema = z.enum([
"pure",
"observation-only",
+3 -2
View File
@@ -12,9 +12,10 @@ import {
recommendedReconstructionProbes,
type ReconstructionEvaluationContext,
} from "./reconstructionCoverageEvaluation.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const stableIdSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._:/-]{0,199}$/u);
const boundedTextSchema = z.string().trim().min(1);
@@ -1,9 +1,10 @@
import { z } from "zod";
import { evidenceBundleSchema } from "./evidenceBundle.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const stableIdSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._:/-]*$/u);
const textSchema = z.string().trim().min(1);
@@ -235,7 +236,7 @@ const countBySchema = <Schema extends z.ZodType>(
export const reconstructionObligationLedgerSchema = z.strictObject({
schema: z.literal("ReconstructionObligationLedger"),
ledger_id: z.string().regex(/^rol_[a-f0-9]{64}$/u),
ledger_id: prefixedDigestSchema("rol"),
closure_digest: digestSchema,
status: z.enum(["ready", "open", "failed", "unknown"]),
coverage: z.strictObject({
+4 -3
View File
@@ -2,9 +2,10 @@ import { z } from "zod";
import { evidenceBundleSchema } from "./evidenceBundle.js";
import { reconstructionObligationLedgerSchema } from "./reconstructionObligationLedgerSchemas.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const stableIdSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._:/-]*$/u);
const boundedTextSchema = z.string().trim().min(1);
@@ -244,7 +245,7 @@ const findingSchema = z.strictObject({
export const reconstructionReadinessReportSchema = z.strictObject({
schema: z.literal("ReconstructionReadinessReport"),
report_id: z.string().regex(/^rr_[a-f0-9]{64}$/u),
report_id: prefixedDigestSchema("rr"),
source_digest: digestSchema,
report_digest: digestSchema,
status: readinessStatusSchema,
+2 -1
View File
@@ -31,12 +31,13 @@ import {
} from "./reconstructionUnknowns.js";
import type { ResidualUnknown } from "./residualUnknown.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
export {
reconstructionVerificationInputSchema,
reconstructionVerificationResultSchema,
} from "./reconstructionVerificationSchemas.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
export type { ReconstructionVerificationResult } from "./reconstructionVerificationSchemas.js";
const providers = {
@@ -1,8 +1,9 @@
import { z } from "zod";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const unknownIdSchema = z.string().regex(/^unk_[a-f0-9]{64}$/u);
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const unknownIdSchema = prefixedDigestSchema("unk");
const claimIdSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._-]*$/u);
const titleSchema = z.string().trim().min(1);
const verificationStatusSchema = z.enum(["pass", "fail", "unknown"]);
+3 -2
View File
@@ -5,7 +5,8 @@ import canonicalize from "canonicalize";
import { z } from "zod";
import { compareUnicodeCodePoints } from "./unicodeCodePointOrder.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const boundedTextSchema = z.string().min(1);
const relativePathSchema = z
.string()
@@ -200,7 +201,7 @@ const historicalSourceGraphInputSchema = z.strictObject({
const historicalSourceManifestBaseSchema = z.strictObject({
schema: z.literal("HistoricalSourceManifest"),
authority: z.literal("historical-reference"),
manifest_id: z.string().regex(/^hsm_[a-f0-9]{64}$/u),
manifest_id: prefixedDigestSchema("hsm"),
graph_sha256: digestSchema,
root_sha256: digestSchema,
inventory_state: z.enum(["complete", "partial", "unknown"]),
+3 -2
View File
@@ -2,9 +2,10 @@ import { createHash } from "node:crypto";
import canonicalize from "canonicalize";
import { z } from "zod";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const unknownIdSchema = z.string().regex(/^unk_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const unknownIdSchema = prefixedDigestSchema("unk");
const text = z.string().trim().min(1);
const environmentRequirementSchema = z.object({
id: z.string().min(1).nullable(),
+1 -1
View File
@@ -2,8 +2,8 @@ import { createHash } from "node:crypto";
import canonicalize from "canonicalize";
import { z } from "zod";
import { digestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const stableIdSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9._:/-]*$/u);
const runtimeIdentitySchema = z.strictObject({
+5 -4
View File
@@ -5,9 +5,10 @@ import { z } from "zod";
import { parseArtifactInventoryEvidence } from "./artifactInventoryEvidence.js";
import { evidenceSchema } from "./evidence.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const runtimeFamilySchema = z.enum([
"android",
"apple",
@@ -18,7 +19,7 @@ const runtimeFamilySchema = z.enum([
]);
const observationSchema = z.strictObject({
path: z.string().min(1),
artifact_id: z.string().regex(/^art_[a-f0-9]{64}$/u),
artifact_id: prefixedDigestSchema("art"),
sha256: digestSchema,
format: z.string().min(1),
});
@@ -54,7 +55,7 @@ const runtimeIdentificationInputSchema = z.strictObject({
/** Provider-neutral runtime identification with explicit tooling availability. */
export const runtimeIdentificationResultSchema = z.strictObject({
identification_id: z.string().regex(/^rid_[a-f0-9]{64}$/u),
identification_id: prefixedDigestSchema("rid"),
root_sha256: digestSchema,
root_format: z.string().min(1),
source_evidence_ids: z.array(evidenceIdSchema).min(1),
@@ -3,10 +3,11 @@ import { z } from "zod";
import { evidenceSchema } from "./evidence.js";
import { JAVASCRIPT_APPLICATION_NODE_KINDS } from "./javascriptApplicationGraphSchemas.js";
import { historicalSourceGraphSchema } from "./referenceSourceGraph.js";
import { digestSchema } from "./../domain/digests.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const nodeIdSchema = z.string().regex(/^jag_node_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const nodeIdSchema = prefixedDigestSchema("jag_node");
const textSchema = z.string().min(1);
export const SOURCE_TO_BUNDLE_SIGNAL_WEIGHTS = [
@@ -49,7 +50,7 @@ const sourceToBundleCandidateSchema = z.strictObject({
});
const sourceToBundleItemSchema = z.strictObject({
mapping_id: z.string().regex(/^stbc_item_[a-f0-9]{64}$/u),
mapping_id: prefixedDigestSchema("stbc_item"),
source_path: textSchema,
source_sha256: digestSchema.nullable(),
source_language: textSchema.nullable(),
@@ -70,14 +71,14 @@ const sourceToBundleItemSchema = z.strictObject({
/** Deterministic, evidence-bearing historical-source to shipped-bundle comparison. */
export const sourceToBundleComparisonResultSchema = z.strictObject({
comparison_id: z.string().regex(/^stbc_[a-f0-9]{64}$/u),
comparison_id: prefixedDigestSchema("stbc"),
reference: z.strictObject({
root_sha256: digestSchema,
inventory_state: z.enum(["complete", "partial", "unknown"]),
}),
application: z.strictObject({
evidence_id: evidenceIdSchema,
graph_id: z.string().regex(/^jag_[a-f0-9]{64}$/u),
graph_id: prefixedDigestSchema("jag"),
root_artifact_sha256: digestSchema,
}),
scoring: z.strictObject({
+1 -2
View File
@@ -7,6 +7,7 @@ import {
type SourceToBundleCandidate,
type SourceToBundleSignal,
} from "./sourceToBundleComparisonSchemas.js";
import { isDigest } from "./digests.js";
type SourceFile = Extract<
HistoricalSourceGraph["entries"][number],
@@ -310,7 +311,5 @@ const addIndexValue = (
index.set(key, values);
};
const isDigest = (value: string): boolean => /^[a-f0-9]{64}$/u.test(value);
const compareText = (left: string, right: string): number =>
left < right ? -1 : left > right ? 1 : 0;
+3 -2
View File
@@ -11,8 +11,9 @@ import {
comparisonStatusSchema,
processCaptureComparisonSchema,
} from "./processCapture.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const evidenceIdSchema = prefixedDigestSchema("ev");
const functionDimensionSchema = z.enum([
"identity",
"pseudocode",
@@ -92,7 +93,7 @@ export const staticRuntimeCorrelationInputSchema = z
.strict();
const correlationItemSchema = z.object({
correlation_id: z.string().regex(/^cor_[a-f0-9]{64}$/u),
correlation_id: prefixedDigestSchema("cor"),
static: z.object({
comparison_evidence_id: evidenceIdSchema,
selector: staticSelectorSchema,
+2 -1
View File
@@ -6,6 +6,7 @@ import {
browserEndpointSchema,
} from "./browserObservation.js";
import { jsonShapeSchema } from "./jsonShape.js";
import { prefixedDigestSchema } from "./../domain/digests.js";
/** Input for passive discovery of page-registered WebMCP tools. */
export const discoverWebMcpToolsInputSchema = z.strictObject({
@@ -27,7 +28,7 @@ const browserVersionSchema = z.object({
});
const webMcpToolSchema = z.object({
tool_key: z.string().regex(/^webmcp_[a-f0-9]{64}$/u),
tool_key: prefixedDigestSchema("webmcp"),
name: z.string(),
description: z.string(),
frame_id: z.string(),