/* Facilitates integrity policy management and schema file generation for path validation within the system. Do not perform raw content parsing or validation beyond JSON schema definitions. Do not manage the orchestration of transport or configuration for policy files. RFC-1097: step 6 — compass.migrate codemod run Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order. RFC-1097: sweep — werkstatt-engine clean Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics. */ /** * Integrity policy management and path matching. * Defines include/exclude patterns and JSON schemas for validation. */ import { pathExists } from "./fs.ts"; import { readJsonFile, writeJsonFile } from "./json.ts"; import { policyPath, schemaDir } from "./paths.ts"; import type { IntegrityPolicy } from "./types.ts"; function escapeRegex(input: string): string { return input.replace(/[|\\{}()[\]^$+?.]/g, "\\$&"); } function globToRegExp(pattern: string): RegExp { const normalized = pattern.replace(/\\/g, "/"); const placeholder = "__DOUBLE_STAR__"; const source = escapeRegex(normalized) .replace(/\*\*/g, placeholder) .replace(/\*/g, "[^/]*") .replace(new RegExp(placeholder, "g"), ".*"); return new RegExp(`^${source}$`); } const BOOTSTRAP_POLICY = { $schemaVersion: 1, hashAlgorithm: "sha256", include: [ "src/**", "public/**", "*.json", "**/*.json", "*.ts", "**/*.ts", "*.js", "**/*.js", "*.astro", "**/*.astro", "*.md", "**/*.md", "*.mdx", "**/*.mdx", ], exclude: [ ".git/**", "node_modules/**", ".astro/**", "dist/**", ".idea/**", ".vscode/**", ".integrity/**", "spec/**", "todo/**", ], moveDetection: { enableHeuristics: false, similarityThreshold: 0.85, maxDeletedCandidateAgeHours: 72, }, history: { keepDeletedLog: true, keepBuildHistory: true, }, } satisfies IntegrityPolicy; const BOOTSTRAP_SCHEMAS = { "policy.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://example.local/integrity/policy.schema.json", type: "object", additionalProperties: false, required: ["$schemaVersion", "hashAlgorithm", "include", "exclude", "moveDetection", "history"], properties: { $schemaVersion: { const: 1 }, hashAlgorithm: { const: "sha256" }, include: { type: "array", items: { type: "string", minLength: 1 } }, exclude: { type: "array", items: { type: "string", minLength: 1 } }, moveDetection: { type: "object", additionalProperties: false, required: ["enableHeuristics", "similarityThreshold", "maxDeletedCandidateAgeHours"], properties: { enableHeuristics: { type: "boolean" }, similarityThreshold: { type: "number", minimum: 0, maximum: 1 }, maxDeletedCandidateAgeHours: { type: "integer", minimum: 0 }, }, }, history: { type: "object", additionalProperties: false, required: ["keepDeletedLog", "keepBuildHistory"], properties: { keepDeletedLog: { type: "boolean" }, keepBuildHistory: { type: "boolean" }, }, }, }, }, "entities.by-id.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://example.local/integrity/entities.by-id.schema.json", type: "object", propertyNames: { type: "string", pattern: "^[0-9a-fA-F-]{36}$" }, additionalProperties: { type: "object", additionalProperties: false, required: [ "currentPath", "createdAt", "updatedAt", "revision", "contentHash", "gitSha", "status", ], properties: { currentPath: { type: "string", minLength: 1 }, firstPath: { type: "string", minLength: 1 }, createdAt: { type: "string", format: "date-time" }, updatedAt: { type: "string", format: "date-time" }, revision: { type: "integer", minimum: 1 }, contentHash: { type: "string", pattern: "^sha256:[0-9a-fA-F]{64}$" }, gitSha: { type: "string", minLength: 1 }, status: { enum: ["active", "deleted"] }, moves: { type: "array", items: { type: "object", additionalProperties: false, required: ["from", "to", "detectedAt", "confidence", "method"], properties: { from: { type: "string", minLength: 1 }, to: { type: "string", minLength: 1 }, detectedAt: { type: "string", format: "date-time" }, confidence: { type: "number", minimum: 0, maximum: 1 }, method: { enum: ["same-hash", "heuristic"] }, }, }, }, }, }, }, "paths.current.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://example.local/integrity/paths.current.schema.json", type: "object", propertyNames: { type: "string", minLength: 1 }, additionalProperties: { type: "string", pattern: "^[0-9a-fA-F-]{36}$" }, }, "deleted-log.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://example.local/integrity/deleted-log.schema.json", type: "array", items: { type: "object", additionalProperties: false, required: ["entityId", "lastPath", "deletedAt", "lastRevision", "lastHash"], properties: { entityId: { type: "string", pattern: "^[0-9a-fA-F-]{36}$" }, lastPath: { type: "string", minLength: 1 }, deletedAt: { type: "string", format: "date-time" }, lastRevision: { type: "integer", minimum: 1 }, lastHash: { type: "string", pattern: "^sha256:[0-9a-fA-F]{64}$" }, }, }, }, "manifest.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://example.local/integrity/manifest.schema.json", type: "object", additionalProperties: false, required: ["$schemaVersion", "directory", "generatedAt", "files"], properties: { $schemaVersion: { const: 1 }, directory: { type: "string", minLength: 1 }, generatedAt: { type: "string", format: "date-time" }, files: { type: "object", propertyNames: { type: "string", minLength: 1 }, additionalProperties: { type: "object", additionalProperties: false, required: [ "entityId", "createdAt", "updatedAt", "revision", "contentHash", "gitSha", "status", ], properties: { entityId: { type: "string", pattern: "^[0-9a-fA-F-]{36}$" }, createdAt: { type: "string", format: "date-time" }, updatedAt: { type: "string", format: "date-time" }, revision: { type: "integer", minimum: 1 }, contentHash: { type: "string", pattern: "^sha256:[0-9a-fA-F]{64}$" }, gitSha: { type: "string", minLength: 1 }, status: { enum: ["active", "deleted"] }, }, }, }, }, }, "outputs.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://example.local/integrity/outputs.schema.json", type: "object", additionalProperties: false, required: ["buildId", "outputs"], properties: { buildId: { type: "string", minLength: 1 }, outputs: { type: "object", propertyNames: { type: "string", minLength: 1 }, additionalProperties: { type: "string", pattern: "^sha256:[0-9a-fA-F]{64}$", }, }, }, }, "build-provenance.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://example.local/integrity/build-provenance.schema.json", type: "object", additionalProperties: false, required: [ "buildId", "sourceRepo", "sourceCommit", "builder", "buildStartedAt", "buildFinishedAt", "inputsDigest", "outputsDigest", ], properties: { buildId: { type: "string", minLength: 1 }, sourceRepo: { type: "string", minLength: 1 }, sourceCommit: { type: "string", minLength: 1 }, builder: { type: "string", minLength: 1 }, buildStartedAt: { type: "string", format: "date-time" }, buildFinishedAt: { type: "string", format: "date-time" }, inputsDigest: { type: "string", pattern: "^sha256:[0-9a-fA-F]{64}$", }, outputsDigest: { type: "string", pattern: "^sha256:[0-9a-fA-F]{64}$", }, }, }, } as const; async function ensureSchemaFiles(cwd: string): Promise { const root = schemaDir(cwd); for (const [fileName, schema] of Object.entries(BOOTSTRAP_SCHEMAS)) { const filePath = `${root}/${fileName}`; if (await pathExists(filePath)) { continue; } await writeJsonFile(filePath, schema); } } export async function ensurePolicyFile(cwd: string): Promise { const filePath = policyPath(cwd); await ensureSchemaFiles(cwd); if (await pathExists(filePath)) { return readJsonFile(filePath); } await writeJsonFile(filePath, BOOTSTRAP_POLICY); return BOOTSTRAP_POLICY; } export async function loadPolicy(cwd: string): Promise { return ensurePolicyFile(cwd); } export function isManagedPath(repoPath: string, policy: IntegrityPolicy): boolean { const normalized = repoPath.replace(/\\/g, "/"); const excluded = policy.exclude.some((pattern) => globToRegExp(pattern).test(normalized)); if (excluded) return false; return policy.include.some((pattern) => globToRegExp(pattern).test(normalized)); }