@peac/policy-kit 0.10.9 → 0.10.11
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/LICENSE +1 -1
- package/dist/index.cjs +1356 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +1270 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +19 -6
- package/dist/compiler.js +0 -304
- package/dist/compiler.js.map +0 -1
- package/dist/enforce.js +0 -309
- package/dist/enforce.js.map +0 -1
- package/dist/enforcement-profiles.js +0 -293
- package/dist/enforcement-profiles.js.map +0 -1
- package/dist/evaluate.js +0 -258
- package/dist/evaluate.js.map +0 -1
- package/dist/generated/profiles.js +0 -212
- package/dist/generated/profiles.js.map +0 -1
- package/dist/index.js +0 -120
- package/dist/index.js.map +0 -1
- package/dist/loader.js +0 -245
- package/dist/loader.js.map +0 -1
- package/dist/profiles.js +0 -368
- package/dist/profiles.js.map +0 -1
- package/dist/types.js +0 -348
- package/dist/types.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/loader.ts","../src/evaluate.ts","../src/compiler.ts","../src/generated/profiles.ts","../src/profiles.ts","../src/enforce.ts","../src/enforcement-profiles.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * PEAC Policy Kit Types\n *\n * Deterministic policy format for CAL semantics.\n * Version: peac-policy/0.1\n *\n * Design principles:\n * - No scripting, no dynamic code\n * - Deterministic, auditable, side-effect free\n * - First-match-wins rule semantics\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\nimport {\n ControlPurposeSchema,\n ControlLicensingModeSchema,\n ControlDecisionSchema,\n SubjectTypeSchema,\n} from '@peac/schema';\n\n/**\n * Policy format version\n */\nexport const POLICY_VERSION = 'peac-policy/0.1';\n\n/**\n * Subject type (re-export from schema)\n */\nexport type SubjectType = z.infer<typeof SubjectTypeSchema>;\n\n/**\n * Control purpose (re-export from schema)\n */\nexport type ControlPurpose = z.infer<typeof ControlPurposeSchema>;\n\n/**\n * Control licensing mode (re-export from schema)\n */\nexport type ControlLicensingMode = z.infer<typeof ControlLicensingModeSchema>;\n\n/**\n * Control decision (re-export from schema)\n */\nexport type ControlDecision = z.infer<typeof ControlDecisionSchema>;\n\n/**\n * Subject matcher - criteria for matching a subject\n *\n * All fields are optional (omitted = any/wildcard).\n * When multiple fields are present, all must match (AND logic).\n */\nexport const SubjectMatcherSchema = z\n .object({\n /** Match by subject type(s) - single type or array */\n type: z.union([SubjectTypeSchema, z.array(SubjectTypeSchema)]).optional(),\n\n /** Match by label(s) - subject must have ALL specified labels */\n labels: z.array(z.string().min(1)).optional(),\n\n /** Match by subject ID pattern (exact match or prefix with *) */\n id: z.string().min(1).optional(),\n })\n .strict();\n\nexport type SubjectMatcher = z.infer<typeof SubjectMatcherSchema>;\n\n/**\n * Policy rule - a single rule in the policy\n *\n * Evaluated in order; first match wins.\n */\nexport const PolicyRuleSchema = z\n .object({\n /** Rule name (for debugging/auditing) */\n name: z.string().min(1),\n\n /** Subject matcher (omit for any subject) */\n subject: SubjectMatcherSchema.optional(),\n\n /** Purpose(s) this rule applies to - single purpose or array */\n purpose: z.union([ControlPurposeSchema, z.array(ControlPurposeSchema)]).optional(),\n\n /** Licensing mode(s) this rule applies to */\n licensing_mode: z\n .union([ControlLicensingModeSchema, z.array(ControlLicensingModeSchema)])\n .optional(),\n\n /** Decision if rule matches */\n decision: ControlDecisionSchema,\n\n /** Reason for decision (for audit trail) */\n reason: z.string().optional(),\n })\n .strict();\n\nexport type PolicyRule = z.infer<typeof PolicyRuleSchema>;\n\n/**\n * Policy defaults - fallback values when no rule matches\n */\nexport const PolicyDefaultsSchema = z\n .object({\n /** Default decision when no rule matches */\n decision: ControlDecisionSchema,\n\n /** Default reason for audit trail */\n reason: z.string().optional(),\n })\n .strict();\n\nexport type PolicyDefaults = z.infer<typeof PolicyDefaultsSchema>;\n\n/**\n * Complete policy document\n */\nexport const PolicyDocumentSchema = z\n .object({\n /** Policy format version */\n version: z.literal(POLICY_VERSION),\n\n /** Policy name/description (optional) */\n name: z.string().optional(),\n\n /** Default decision (required) */\n defaults: PolicyDefaultsSchema,\n\n /** Rules evaluated in order (first match wins) */\n rules: z.array(PolicyRuleSchema),\n })\n .strict();\n\nexport type PolicyDocument = z.infer<typeof PolicyDocumentSchema>;\n\n/**\n * Evaluation context - input to policy evaluation\n */\nexport interface EvaluationContext {\n /** Subject information */\n subject?: {\n /** Subject ID */\n id?: string;\n\n /** Subject type */\n type?: SubjectType;\n\n /** Subject labels */\n labels?: string[];\n };\n\n /** Purpose of access */\n purpose?: ControlPurpose;\n\n /** Licensing mode */\n licensing_mode?: ControlLicensingMode;\n}\n\n/**\n * Evaluation result\n */\nexport interface EvaluationResult {\n /** Decision from evaluation */\n decision: ControlDecision;\n\n /** Name of matched rule (undefined if default applied) */\n matched_rule?: string;\n\n /** Reason for decision */\n reason?: string;\n\n /** Whether default was applied (no rule matched) */\n is_default: boolean;\n}\n\n// -----------------------------------------------------------------------------\n// Rate Limiting (v0.9.23+)\n// -----------------------------------------------------------------------------\n\n/**\n * Structured rate limit configuration.\n *\n * Uses `window_seconds` for future-proofing (avoids enum lock-in).\n * CLI parses human-friendly strings like \"100/hour\" to this format.\n *\n * @example\n * ```typescript\n * const limit: RateLimitConfig = {\n * limit: 100,\n * window_seconds: 3600, // 1 hour\n * burst: 10,\n * partition: 'agent',\n * };\n * ```\n */\nexport const RateLimitConfigSchema = z\n .object({\n /** Maximum requests allowed in the window */\n limit: z.number().int().positive(),\n\n /** Window size in seconds (e.g., 3600 for 1 hour) */\n window_seconds: z.number().int().positive(),\n\n /** Optional burst allowance above the limit */\n burst: z.number().int().nonnegative().optional(),\n\n /** How to partition rate limits (default: per-agent) */\n partition: z.union([z.enum(['agent', 'ip', 'account']), z.string().min(1)]).optional(),\n })\n .strict();\n\nexport type RateLimitConfig = z.infer<typeof RateLimitConfigSchema>;\n\n/**\n * Parse a human-friendly rate limit string to RateLimitConfig.\n *\n * @example\n * ```typescript\n * parseRateLimit('100/hour'); // { limit: 100, window_seconds: 3600 }\n * parseRateLimit('1000/day'); // { limit: 1000, window_seconds: 86400 }\n * parseRateLimit('10/minute'); // { limit: 10, window_seconds: 60 }\n * ```\n */\nexport function parseRateLimit(input: string): RateLimitConfig {\n const match = input.match(/^(\\d+)\\/(second|minute|hour|day)$/i);\n if (!match) {\n throw new Error(\n `Invalid rate limit format: \"${input}\". Expected format: \"100/hour\", \"1000/day\", etc.`\n );\n }\n\n const limit = parseInt(match[1], 10);\n const unit = match[2].toLowerCase();\n\n const windowMap: Record<string, number> = {\n second: 1,\n minute: 60,\n hour: 3600,\n day: 86400,\n };\n\n return {\n limit,\n window_seconds: windowMap[unit],\n };\n}\n\n/**\n * Format a RateLimitConfig to human-friendly string.\n */\nexport function formatRateLimit(config: RateLimitConfig): string {\n const { limit, window_seconds } = config;\n\n if (window_seconds === 1) return `${limit}/second`;\n if (window_seconds === 60) return `${limit}/minute`;\n if (window_seconds === 3600) return `${limit}/hour`;\n if (window_seconds === 86400) return `${limit}/day`;\n\n return `${limit}/${window_seconds}s`;\n}\n\n// -----------------------------------------------------------------------------\n// Decision Requirements (v0.9.23+)\n// -----------------------------------------------------------------------------\n\n/**\n * Requirements for 'review' decision (challenge-required semantics).\n *\n * When decision is 'review' and requirements are not met:\n * - Enforcement returns a challenge response (e.g., HTTP 402)\n * - Client provides proof (e.g., PEAC receipt)\n * - On valid proof, access is granted\n *\n * This differs from 'deny' which is unconditional rejection.\n *\n * @example\n * ```typescript\n * const rule: PolicyRule = {\n * name: 'inference-needs-receipt',\n * purpose: 'inference',\n * decision: 'review',\n * requirements: { receipt: true },\n * };\n * ```\n */\nexport const DecisionRequirementsSchema = z\n .object({\n /** Require a valid PEAC receipt */\n receipt: z.boolean().optional(),\n\n // Extensible: add more requirements as needed\n // attestation?: boolean;\n // kyc?: boolean;\n })\n .strict();\n\nexport type DecisionRequirements = z.infer<typeof DecisionRequirementsSchema>;\n\n// -----------------------------------------------------------------------------\n// Profile System (v0.9.23+)\n// -----------------------------------------------------------------------------\n\n/**\n * Profile parameter definition.\n *\n * Defines a configurable parameter for a profile.\n */\nexport const ProfileParameterSchema = z\n .object({\n /** Human-readable description */\n description: z.string().min(1),\n\n /** Whether this parameter is required */\n required: z.boolean().optional(),\n\n /** Default value if not provided */\n default: z.union([z.string(), z.number(), z.boolean()]).optional(),\n\n /** Example value for documentation */\n example: z.string().optional(),\n\n /** Validation type for the parameter */\n validate: z.enum(['email', 'url', 'rate_limit']).optional(),\n })\n .strict();\n\nexport type ProfileParameter = z.infer<typeof ProfileParameterSchema>;\n\n/**\n * Profile definition.\n *\n * A profile is a pre-configured policy template for a specific use case\n * (e.g., news publisher, SaaS docs, open source project).\n *\n * Profiles are compiled to TypeScript at build time for:\n * - Type safety\n * - No runtime YAML/fs dependencies\n * - Deterministic output\n *\n * @example\n * ```typescript\n * const profile: ProfileDefinition = {\n * id: 'news-media',\n * name: 'News Media Publisher',\n * description: 'Policy for news and media publishers...',\n * policy: { ... },\n * parameters: {\n * contact: { description: 'Contact email', required: true, validate: 'email' },\n * rate_limit: { description: 'Rate limit', default: '100/hour', validate: 'rate_limit' },\n * },\n * defaults: {\n * requirements: { receipt: true },\n * },\n * };\n * ```\n */\nexport const ProfileDefinitionSchema = z\n .object({\n /** Unique profile identifier (e.g., 'news-media') */\n id: z\n .string()\n .min(1)\n .regex(/^[a-z][a-z0-9-]*$/),\n\n /** Human-readable profile name */\n name: z.string().min(1),\n\n /** Multi-line description of the profile */\n description: z.string().min(1),\n\n /** Base policy document */\n policy: PolicyDocumentSchema,\n\n /** Configurable parameters */\n parameters: z.record(z.string(), ProfileParameterSchema),\n\n /** Default values for profile instances */\n defaults: z\n .object({\n /** Default requirements for 'review' decisions */\n requirements: DecisionRequirementsSchema.optional(),\n\n /** Default rate limit */\n rate_limit: RateLimitConfigSchema.optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nexport type ProfileDefinition = z.infer<typeof ProfileDefinitionSchema>;\n\n// -----------------------------------------------------------------------------\n// Policy Constraints (v0.9.24+)\n// -----------------------------------------------------------------------------\n\n/**\n * Policy constraints for rate limiting and budget control.\n *\n * These constraints are ADVISORY - enforcement happens at the edge/application layer.\n * PEAC receipts capture what constraints were DECLARED, not whether they were enforced.\n *\n * @example\n * ```typescript\n * const constraints: PolicyConstraints = {\n * rate_limit: { window_s: 3600, max: 100 },\n * budget: { max_requests: 1000 },\n * };\n * ```\n */\nexport const PolicyConstraintsSchema = z\n .object({\n /** Rate limit configuration */\n rate_limit: z\n .object({\n /** Window size in seconds */\n window_s: z.number().int().positive(),\n /** Maximum requests allowed in the window */\n max: z.number().int().positive(),\n /** Retry-After header value in seconds (optional) */\n retry_after_s: z.number().int().positive().optional(),\n })\n .strict()\n .optional(),\n\n /** Budget constraints */\n budget: z\n .object({\n /** Maximum tokens allowed */\n max_tokens: z.number().int().positive().optional(),\n /** Maximum requests allowed */\n max_requests: z.number().int().positive().optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nexport type PolicyConstraints = z.infer<typeof PolicyConstraintsSchema>;\n\n// -----------------------------------------------------------------------------\n// Enforcement Profiles (v0.9.24+)\n// -----------------------------------------------------------------------------\n\n/**\n * Enforcement profile for purpose handling.\n *\n * Defines how undeclared or unknown purposes are handled at the enforcement layer.\n * These are distinct from use-case profiles (api-provider, news-media, etc.).\n *\n * Three canonical profiles:\n * - `strict`: Deny undeclared purposes (regulated data, private APIs)\n * - `balanced`: Review + constraints for undeclared purposes (general web, default)\n * - `open`: Allow undeclared purposes with recording (public content, research)\n */\nexport type EnforcementProfileId = 'strict' | 'balanced' | 'open';\n\n/**\n * Enforcement profile definition.\n *\n * Specifies how to handle requests with undeclared, unknown, or missing purposes.\n */\nexport const EnforcementProfileSchema = z\n .object({\n /** Profile identifier */\n id: z.enum(['strict', 'balanced', 'open']),\n\n /** Human-readable name */\n name: z.string().min(1),\n\n /** Description of when to use this profile */\n description: z.string().min(1),\n\n /** Decision for requests with no purpose declared (missing header) */\n undeclared_decision: z.enum(['allow', 'deny', 'review']),\n\n /** Decision for requests with unknown purpose tokens */\n unknown_decision: z.enum(['allow', 'deny', 'review']),\n\n /** Purpose reason to record when undeclared/unknown is processed */\n purpose_reason: z.enum([\n 'allowed',\n 'constrained',\n 'denied',\n 'downgraded',\n 'undeclared_default',\n 'unknown_preserved',\n ]),\n\n /** Default constraints to apply for 'review' decisions */\n default_constraints: PolicyConstraintsSchema.optional(),\n\n /** Whether receipts are required for allowed requests */\n receipts: z.enum(['required', 'optional', 'omit']),\n })\n .strict();\n\nexport type EnforcementProfile = z.infer<typeof EnforcementProfileSchema>;\n","/**\n * PEAC Policy Kit Loader\n *\n * Loads and validates policy documents from YAML or JSON.\n * No network calls - file system only.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'yaml';\nimport { ZodError } from 'zod';\nimport { PolicyDocument, PolicyDocumentSchema, POLICY_VERSION } from './types';\n\n/**\n * Policy load error\n */\nexport class PolicyLoadError extends Error {\n constructor(\n message: string,\n public readonly cause?: Error | ZodError\n ) {\n super(message);\n this.name = 'PolicyLoadError';\n }\n}\n\n/**\n * Policy validation error with details\n */\nexport class PolicyValidationError extends PolicyLoadError {\n constructor(\n message: string,\n public readonly issues: ZodError['issues']\n ) {\n super(message);\n this.name = 'PolicyValidationError';\n }\n}\n\n/**\n * Parse policy from string content\n *\n * @param content - YAML or JSON string\n * @param format - Optional format hint ('yaml' | 'json'), auto-detected if not provided\n * @returns Validated policy document\n * @throws PolicyLoadError on parse failure\n * @throws PolicyValidationError on schema validation failure\n */\nexport function parsePolicy(content: string, format?: 'yaml' | 'json'): PolicyDocument {\n let parsed: unknown;\n\n try {\n if (format === 'json') {\n parsed = JSON.parse(content);\n } else if (format === 'yaml') {\n parsed = yaml.parse(content);\n } else {\n // Auto-detect: try JSON first (faster), fall back to YAML\n try {\n parsed = JSON.parse(content);\n } catch {\n parsed = yaml.parse(content);\n }\n }\n } catch (err) {\n throw new PolicyLoadError(\n `Failed to parse policy: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n );\n }\n\n return validatePolicy(parsed);\n}\n\n/**\n * Validate a parsed policy object\n *\n * @param obj - Parsed policy object (from YAML/JSON)\n * @returns Validated policy document\n * @throws PolicyValidationError on schema validation failure\n */\nexport function validatePolicy(obj: unknown): PolicyDocument {\n try {\n return PolicyDocumentSchema.parse(obj);\n } catch (err) {\n if (err instanceof ZodError) {\n const issues = err.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');\n throw new PolicyValidationError(`Policy validation failed: ${issues}`, err.issues);\n }\n throw new PolicyLoadError(\n `Policy validation failed: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n );\n }\n}\n\n/**\n * Load policy from file\n *\n * @param filePath - Path to policy file (.yaml, .yml, or .json)\n * @returns Validated policy document\n * @throws PolicyLoadError on file read or parse failure\n * @throws PolicyValidationError on schema validation failure\n */\nexport function loadPolicy(filePath: string): PolicyDocument {\n const ext = path.extname(filePath).toLowerCase();\n let format: 'yaml' | 'json' | undefined;\n\n if (ext === '.json') {\n format = 'json';\n } else if (ext === '.yaml' || ext === '.yml') {\n format = 'yaml';\n }\n\n let content: string;\n try {\n content = fs.readFileSync(filePath, 'utf-8');\n } catch (err) {\n throw new PolicyLoadError(\n `Failed to read policy file: ${err instanceof Error ? err.message : String(err)}`,\n err instanceof Error ? err : undefined\n );\n }\n\n return parsePolicy(content, format);\n}\n\n/**\n * Check if a policy file exists and is readable\n *\n * @param filePath - Path to policy file\n * @returns true if file exists and is readable\n */\nexport function policyFileExists(filePath: string): boolean {\n try {\n fs.accessSync(filePath, fs.constants.R_OK);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Create a minimal example policy document\n *\n * Useful for scaffolding new policy files.\n */\nexport function createExamplePolicy(): PolicyDocument {\n return {\n version: POLICY_VERSION,\n name: 'Example Policy',\n defaults: {\n decision: 'deny',\n reason: 'No matching rule found',\n },\n rules: [\n {\n name: 'allow-subscribed-crawl',\n subject: {\n type: 'human',\n labels: ['subscribed'],\n },\n purpose: 'crawl',\n licensing_mode: 'subscription',\n decision: 'allow',\n reason: 'Subscribed users can crawl',\n },\n {\n name: 'allow-verified-agents-inference',\n subject: {\n type: 'agent',\n labels: ['verified'],\n },\n purpose: ['inference', 'ai_input'],\n licensing_mode: 'pay_per_inference',\n decision: 'allow',\n reason: 'Verified agents can run inference with payment',\n },\n {\n name: 'review-org-train',\n subject: {\n type: 'org',\n },\n purpose: 'train',\n decision: 'review',\n reason: 'Training requests from organizations require review',\n },\n ],\n };\n}\n\n/**\n * Serialize policy to YAML string\n *\n * @param policy - Policy document to serialize\n * @returns YAML string\n */\nexport function serializePolicyYaml(policy: PolicyDocument): string {\n return yaml.stringify(policy, {\n lineWidth: 100,\n defaultKeyType: 'PLAIN',\n defaultStringType: 'QUOTE_DOUBLE',\n });\n}\n\n/**\n * Serialize policy to JSON string\n *\n * @param policy - Policy document to serialize\n * @param pretty - Pretty-print with indentation (default: true)\n * @returns JSON string\n */\nexport function serializePolicyJson(policy: PolicyDocument, pretty = true): string {\n return JSON.stringify(policy, null, pretty ? 2 : undefined);\n}\n","/**\n * PEAC Policy Kit Evaluation\n *\n * Deterministic policy evaluation for CAL semantics.\n * First-match-wins rule semantics.\n *\n * @packageDocumentation\n */\n\nimport {\n PolicyDocument,\n PolicyRule,\n SubjectMatcher,\n EvaluationContext,\n EvaluationResult,\n ControlPurpose,\n ControlLicensingMode,\n SubjectType,\n} from './types';\n\n/**\n * Check if a value matches a single-or-array pattern\n *\n * @param value - Value to check\n * @param pattern - Single value or array of values\n * @returns true if value matches pattern\n */\nfunction matchesSingleOrArray<T>(value: T | undefined, pattern: T | T[] | undefined): boolean {\n // If no pattern specified, match anything\n if (pattern === undefined) {\n return true;\n }\n\n // If no value and pattern exists, no match\n if (value === undefined) {\n return false;\n }\n\n // Check against array or single value\n if (Array.isArray(pattern)) {\n return pattern.includes(value);\n }\n\n return value === pattern;\n}\n\n/**\n * Check if a subject ID matches a pattern\n *\n * Supports:\n * - Exact match: \"user:abc123\"\n * - Prefix match with wildcard: \"user:*\" matches \"user:abc123\"\n *\n * @param id - Subject ID to check\n * @param pattern - Pattern to match against\n * @returns true if ID matches pattern\n */\nfunction matchesIdPattern(id: string | undefined, pattern: string | undefined): boolean {\n // No pattern = match anything\n if (pattern === undefined) {\n return true;\n }\n\n // No ID but pattern exists = no match\n if (id === undefined) {\n return false;\n }\n\n // Wildcard prefix match\n if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1);\n return id.startsWith(prefix);\n }\n\n // Exact match\n return id === pattern;\n}\n\n/**\n * Check if subject labels contain all required labels\n *\n * @param subjectLabels - Labels on the subject\n * @param requiredLabels - Labels required by the rule\n * @returns true if subject has all required labels\n */\nfunction hasAllLabels(\n subjectLabels: string[] | undefined,\n requiredLabels: string[] | undefined\n): boolean {\n // No required labels = match\n if (requiredLabels === undefined || requiredLabels.length === 0) {\n return true;\n }\n\n // Required labels but no subject labels = no match\n if (subjectLabels === undefined || subjectLabels.length === 0) {\n return false;\n }\n\n // Check all required labels are present\n return requiredLabels.every((label) => subjectLabels.includes(label));\n}\n\n/**\n * Check if a subject matches a subject matcher\n *\n * @param subject - Subject from evaluation context\n * @param matcher - Subject matcher from rule\n * @returns true if subject matches all criteria\n */\nfunction matchesSubject(\n subject: EvaluationContext['subject'],\n matcher: SubjectMatcher | undefined\n): boolean {\n // No matcher = match any subject\n if (matcher === undefined) {\n return true;\n }\n\n // Check type\n if (!matchesSingleOrArray(subject?.type, matcher.type)) {\n return false;\n }\n\n // Check labels (must have ALL required labels)\n if (!hasAllLabels(subject?.labels, matcher.labels)) {\n return false;\n }\n\n // Check ID pattern\n if (!matchesIdPattern(subject?.id, matcher.id)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Check if a rule matches the evaluation context\n *\n * All criteria must match (AND logic).\n *\n * @param rule - Policy rule to check\n * @param context - Evaluation context\n * @returns true if rule matches context\n */\nfunction ruleMatches(rule: PolicyRule, context: EvaluationContext): boolean {\n // Check subject\n if (!matchesSubject(context.subject, rule.subject)) {\n return false;\n }\n\n // Check purpose\n if (!matchesSingleOrArray(context.purpose, rule.purpose)) {\n return false;\n }\n\n // Check licensing mode\n if (!matchesSingleOrArray(context.licensing_mode, rule.licensing_mode)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Evaluate a policy against a context\n *\n * Uses first-match-wins semantics:\n * - Rules are evaluated in order\n * - First matching rule determines the decision\n * - If no rule matches, defaults are applied\n *\n * @param policy - Policy document\n * @param context - Evaluation context\n * @returns Evaluation result\n */\nexport function evaluate(policy: PolicyDocument, context: EvaluationContext): EvaluationResult {\n // Find first matching rule\n for (const rule of policy.rules) {\n if (ruleMatches(rule, context)) {\n return {\n decision: rule.decision,\n matched_rule: rule.name,\n reason: rule.reason,\n is_default: false,\n };\n }\n }\n\n // No rule matched, apply defaults\n return {\n decision: policy.defaults.decision,\n reason: policy.defaults.reason,\n is_default: true,\n };\n}\n\n/**\n * Explain which rules could potentially match a context\n *\n * Useful for debugging and policy analysis.\n * Returns all rules that would match if evaluated, in order.\n *\n * @param policy - Policy document\n * @param context - Evaluation context\n * @returns Array of rule names that match, or 'default' if none\n */\nexport function explainMatches(policy: PolicyDocument, context: EvaluationContext): string[] {\n const matches: string[] = [];\n\n for (const rule of policy.rules) {\n if (ruleMatches(rule, context)) {\n matches.push(rule.name);\n }\n }\n\n if (matches.length === 0) {\n matches.push('[default]');\n }\n\n return matches;\n}\n\n/**\n * Find the effective rule for a context\n *\n * Same as evaluate() but returns the full rule object.\n *\n * @param policy - Policy document\n * @param context - Evaluation context\n * @returns Matched rule or undefined if default applies\n */\nexport function findEffectiveRule(\n policy: PolicyDocument,\n context: EvaluationContext\n): PolicyRule | undefined {\n for (const rule of policy.rules) {\n if (ruleMatches(rule, context)) {\n return rule;\n }\n }\n return undefined;\n}\n\n/**\n * Check if a policy would allow a given context\n *\n * Convenience helper for common allow/deny checks.\n *\n * @param policy - Policy document\n * @param context - Evaluation context\n * @returns true if decision is 'allow'\n */\nexport function isAllowed(policy: PolicyDocument, context: EvaluationContext): boolean {\n const result = evaluate(policy, context);\n return result.decision === 'allow';\n}\n\n/**\n * Check if a policy would deny a given context\n *\n * Convenience helper for common allow/deny checks.\n *\n * @param policy - Policy document\n * @param context - Evaluation context\n * @returns true if decision is 'deny'\n */\nexport function isDenied(policy: PolicyDocument, context: EvaluationContext): boolean {\n const result = evaluate(policy, context);\n return result.decision === 'deny';\n}\n\n/**\n * Check if a policy requires review for a given context\n *\n * Convenience helper for review checks.\n *\n * @param policy - Policy document\n * @param context - Evaluation context\n * @returns true if decision is 'review'\n */\nexport function requiresReview(policy: PolicyDocument, context: EvaluationContext): boolean {\n const result = evaluate(policy, context);\n return result.decision === 'review';\n}\n\n/**\n * Batch evaluate multiple contexts against a policy\n *\n * Useful for testing or bulk authorization checks.\n *\n * @param policy - Policy document\n * @param contexts - Array of evaluation contexts\n * @returns Array of evaluation results (same order as contexts)\n */\nexport function evaluateBatch(\n policy: PolicyDocument,\n contexts: EvaluationContext[]\n): EvaluationResult[] {\n return contexts.map((context) => evaluate(policy, context));\n}\n","/**\n * PEAC Policy Kit Compiler\n *\n * Compiles policy documents to deployment artifacts:\n * - peac.txt (PEAC discovery file - canonical schema)\n * - robots.txt snippet for AI crawlers\n * - AIPREF header templates (compatibility output)\n * - Human-readable markdown summary\n *\n * All outputs are deterministic (stable ordering where semantically safe).\n * Rule order is preserved where it affects semantics (first-match-wins).\n *\n * @packageDocumentation\n */\n\nimport { PolicyDocument, ControlPurpose, POLICY_VERSION } from './types';\n\n/**\n * Default PEAC protocol version for generated peac.txt\n *\n * Uses major.minor format (e.g., \"0.9\") by default. Pass a full version\n * (e.g., \"0.9.17\") via peacVersion option if needed.\n *\n * This matches the wire format version from @peac/kernel.\n */\nexport const PEAC_PROTOCOL_VERSION = '0.9' as const;\n\n/**\n * Options for compilation\n */\nexport interface CompileOptions {\n /** Base URL for the site (used in peac.txt) */\n siteUrl?: string;\n /** Contact email for policy questions */\n contact?: string;\n /** Include comments in output */\n includeComments?: boolean;\n /**\n * PEAC protocol version for peac.txt (default: 0.9)\n * Use major.minor (0.9) or full version (0.9.17) as needed.\n */\n peacVersion?: string;\n /** Attribution requirement: required, optional, or none */\n attribution?: 'required' | 'optional' | 'none';\n /**\n * Receipts requirement: required, optional, or omit (don't include field)\n * Default: 'required' for conditional usage, 'optional' for open usage\n */\n receipts?: 'required' | 'optional' | 'omit';\n /** Rate limit string (e.g., \"100/hour\", \"unlimited\") */\n rateLimit?: string;\n /** Negotiate endpoint URL */\n negotiateUrl?: string;\n}\n\n/**\n * AIPREF header template\n */\nexport interface AiprefTemplate {\n /** Header name */\n header: string;\n /** Header value */\n value: string;\n /** Description of when to use */\n description: string;\n}\n\n/**\n * Compile policy to peac.txt format (canonical schema)\n *\n * Generates a PEAC discovery file that can be served at:\n * - /.well-known/peac.txt (primary)\n * - /peac.txt (fallback)\n *\n * Output uses canonical PEAC schema with `version` and `usage` fields.\n * Rule order is preserved in comments (first-match-wins semantics).\n *\n * @param policy - Policy document\n * @param options - Compilation options\n * @returns peac.txt content (YAML format)\n */\nexport function compilePeacTxt(policy: PolicyDocument, options: CompileOptions = {}): string {\n const lines: string[] = [];\n const { includeComments = true, peacVersion = PEAC_PROTOCOL_VERSION } = options;\n\n if (includeComments) {\n lines.push('# PEAC Policy Discovery File');\n lines.push(`# Generated from: ${policy.name || 'peac-policy.yaml'}`);\n lines.push('#');\n lines.push('# Serve at: /.well-known/peac.txt');\n lines.push('# See: https://www.peacprotocol.org');\n lines.push('');\n }\n\n // PEAC protocol version (canonical field)\n lines.push(`version: ${peacVersion}`);\n\n // Usage: open (allow default) or conditional (deny/review default)\n const usage = policy.defaults.decision === 'allow' ? 'open' : 'conditional';\n lines.push(`usage: ${usage}`);\n lines.push('');\n\n // List purposes covered by rules (sorted for determinism - safe because informational)\n const purposes = extractPurposes(policy);\n if (purposes.length > 0) {\n lines.push(`purposes: [${purposes.join(', ')}]`);\n }\n\n // Attribution if specified\n if (options.attribution && options.attribution !== 'none') {\n lines.push(`attribution: ${options.attribution}`);\n }\n\n // Receipts: configurable, with sensible defaults based on usage\n // - conditional: defaults to 'required' (explicit receipt needed)\n // - open: defaults to 'optional' (receipt accepted but not required)\n const receiptsDefault = usage === 'conditional' ? 'required' : 'optional';\n const receiptsValue = options.receipts ?? receiptsDefault;\n if (receiptsValue !== 'omit') {\n lines.push(`receipts: ${receiptsValue}`);\n }\n\n // Rate limit (applies to both open and conditional)\n if (options.rateLimit) {\n lines.push(`rate_limit: ${options.rateLimit}`);\n }\n\n // Negotiate endpoint (typically for conditional access)\n if (options.negotiateUrl) {\n lines.push(`negotiate: ${options.negotiateUrl}`);\n }\n\n // Contact if provided\n if (options.contact) {\n lines.push(`contact: ${options.contact}`);\n }\n\n // Show rule summary in comments (preserve author order - semantically significant)\n if (policy.rules.length > 0 && includeComments) {\n lines.push('');\n lines.push('# Policy rules (first-match-wins, author order preserved):');\n lines.push(`# Source: ${policy.name || 'peac-policy.yaml'} (${policy.rules.length} rules)`);\n for (const rule of policy.rules) {\n lines.push(`# ${rule.name}: ${rule.decision}`);\n }\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * Compile policy to robots.txt snippet for AI crawlers\n *\n * Generates User-agent blocks for known AI crawlers based on policy.\n * Conservative: if default is deny or review, disallows crawling.\n *\n * @param policy - Policy document\n * @param options - Compilation options\n * @returns robots.txt snippet content\n */\nexport function compileRobotsSnippet(policy: PolicyDocument, options: CompileOptions = {}): string {\n const lines: string[] = [];\n const { includeComments = true } = options;\n\n // Known AI crawler user agents (sorted for determinism)\n const aiCrawlers = [\n 'Anthropic-AI',\n 'CCBot',\n 'ChatGPT-User',\n 'Claude-Web',\n 'Cohere-AI',\n 'GPTBot',\n 'Google-Extended',\n 'Meta-ExternalAgent',\n 'Meta-ExternalFetcher',\n 'PerplexityBot',\n 'anthropic-ai',\n 'cohere-ai',\n ];\n\n if (includeComments) {\n lines.push('# AI Crawler Directives');\n lines.push(`# Generated from PEAC policy: ${policy.name || 'peac-policy.yaml'}`);\n lines.push('#');\n lines.push('# SNIPPET - Review before adding to your robots.txt');\n lines.push(`# Default policy: ${policy.defaults.decision}`);\n lines.push('');\n }\n\n // Conservative approach: only allow if default is explicitly 'allow'\n // If default is 'deny' or 'review', disallow and require PEAC receipt\n const isDefaultAllow = policy.defaults.decision === 'allow';\n\n for (const crawler of aiCrawlers) {\n lines.push(`User-agent: ${crawler}`);\n if (isDefaultAllow) {\n lines.push('Allow: /');\n } else {\n lines.push('Disallow: /');\n if (includeComments) {\n lines.push('# Requires PEAC receipt for access');\n }\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Compile policy to AIPREF header templates\n *\n * Generates header values for HTTP responses.\n * These are COMPATIBILITY templates, not normative PEAC headers.\n * The authoritative policy is always peac.txt.\n *\n * @param policy - Policy document\n * @param options - Compilation options\n * @returns Array of header templates\n */\nexport function compileAiprefTemplates(\n policy: PolicyDocument,\n options: CompileOptions = {}\n): AiprefTemplate[] {\n const templates: AiprefTemplate[] = [];\n const { peacVersion = PEAC_PROTOCOL_VERSION } = options;\n const usage = policy.defaults.decision === 'allow' ? 'open' : 'conditional';\n\n // PEAC-Policy header (debug/compatibility - see peac.txt for authoritative policy)\n templates.push({\n header: 'PEAC-Policy',\n value: `version=${peacVersion}; usage=${usage}; rules=${policy.rules.length}`,\n description: 'Debug/compatibility header - see peac.txt for authoritative policy',\n });\n\n // X-Robots-Tag for AI (compatibility, widely supported)\n if (policy.defaults.decision === 'deny') {\n templates.push({\n header: 'X-Robots-Tag',\n value: 'noai, noimageai',\n description: 'Compatibility header: signal no AI training (default deny policy)',\n });\n }\n\n // Note about AIPREF-style headers\n templates.push({\n header: '# Compatibility Note',\n value: 'See /.well-known/peac.txt for authoritative policy',\n description:\n 'These headers are for compatibility only. AIPREF-style X-AI-* headers are not generated to avoid contradictions with conditional rules.',\n });\n\n return templates;\n}\n\n/**\n * Render policy as human-readable markdown\n *\n * Generates an ai-policy.md file for documentation.\n *\n * @param policy - Policy document\n * @param options - Compilation options\n * @returns Markdown content\n */\nexport function renderPolicyMarkdown(policy: PolicyDocument, options: CompileOptions = {}): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${policy.name || 'AI Access Policy'}`);\n lines.push('');\n lines.push(`> Generated from PEAC policy (${policy.version})`);\n lines.push('');\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n lines.push(`- **Default Decision:** ${policy.defaults.decision}`);\n if (policy.defaults.reason) {\n lines.push(`- **Default Reason:** ${policy.defaults.reason}`);\n }\n lines.push(`- **Total Rules:** ${policy.rules.length}`);\n lines.push('');\n\n // Contact\n if (options.contact) {\n lines.push(`For questions about this policy, contact: ${options.contact}`);\n lines.push('');\n }\n\n // How it works\n lines.push('## How This Policy Works');\n lines.push('');\n lines.push(\n 'This policy uses **first-match-wins** semantics (like firewall rules). When an AI agent requests access:'\n );\n lines.push('');\n lines.push('1. Rules are evaluated in order');\n lines.push('2. The first matching rule determines the decision');\n lines.push('3. If no rule matches, the default decision applies');\n lines.push('');\n\n // Rules (preserve author order - first-match-wins semantics are order-dependent)\n if (policy.rules.length > 0) {\n lines.push('## Rules');\n lines.push('');\n lines.push('> Rules are evaluated in order. The first matching rule wins.');\n lines.push('');\n for (const rule of policy.rules) {\n lines.push(`### ${rule.name}`);\n lines.push('');\n lines.push(`- **Decision:** ${rule.decision}`);\n if (rule.reason) {\n lines.push(`- **Reason:** ${rule.reason}`);\n }\n if (rule.subject) {\n const subjectParts: string[] = [];\n if (rule.subject.type) {\n const types = Array.isArray(rule.subject.type)\n ? rule.subject.type.join(', ')\n : rule.subject.type;\n subjectParts.push(`type: ${types}`);\n }\n if (rule.subject.labels) {\n subjectParts.push(`labels: ${rule.subject.labels.join(', ')}`);\n }\n if (rule.subject.id) {\n subjectParts.push(`id: ${rule.subject.id}`);\n }\n if (subjectParts.length > 0) {\n lines.push(`- **Subject:** ${subjectParts.join('; ')}`);\n }\n }\n if (rule.purpose) {\n const purposes = Array.isArray(rule.purpose) ? rule.purpose.join(', ') : rule.purpose;\n lines.push(`- **Purpose:** ${purposes}`);\n }\n if (rule.licensing_mode) {\n const modes = Array.isArray(rule.licensing_mode)\n ? rule.licensing_mode.join(', ')\n : rule.licensing_mode;\n lines.push(`- **Licensing Mode:** ${modes}`);\n }\n lines.push('');\n }\n }\n\n // Footer\n lines.push('---');\n lines.push('');\n lines.push(\n '*This policy is enforced via the PEAC Protocol. See [peacprotocol.org](https://www.peacprotocol.org) for more information.*'\n );\n lines.push('');\n\n return lines.join('\\n');\n}\n\n// --- Helper functions ---\n\n/**\n * Extract all unique purposes from policy rules (sorted for determinism)\n */\nfunction extractPurposes(policy: PolicyDocument): ControlPurpose[] {\n const purposes = new Set<ControlPurpose>();\n\n for (const rule of policy.rules) {\n if (rule.purpose) {\n if (Array.isArray(rule.purpose)) {\n for (const p of rule.purpose) {\n purposes.add(p);\n }\n } else {\n purposes.add(rule.purpose);\n }\n }\n }\n\n // Sort for deterministic output\n return Array.from(purposes).sort();\n}\n","/**\n * Generated Profile Definitions\n *\n * DO NOT EDIT MANUALLY - Generated by scripts/generate-profiles.ts\n * Source: profiles/*.yaml\n */\n\nimport type { ProfileDefinition } from '../types';\n\n/**\n * Available profile IDs\n */\nexport const PROFILE_IDS = ['api-provider', 'news-media', 'open-source', 'saas-docs'] as const;\n\nexport type ProfileId = (typeof PROFILE_IDS)[number];\n\n/**\n * All profiles indexed by ID\n */\nexport const PROFILES: Record<ProfileId, ProfileDefinition> = {\n 'api-provider': {\n defaults: {\n rate_limit: {\n limit: 200,\n window_seconds: 3600,\n },\n requirements: {\n receipt: true,\n },\n },\n description:\n 'Policy profile for API providers and developer platforms.\\nAllows search indexing for API discoverability.\\nBlocks training to protect API design and documentation IP.\\nRequires receipts for inference to enable usage tracking.\\n',\n id: 'api-provider',\n name: 'API Provider',\n parameters: {\n contact: {\n description: 'Developer relations or API support email',\n example: 'api-support@example.com',\n required: true,\n validate: 'email',\n },\n negotiate_url: {\n description: 'URL for API access negotiation',\n required: false,\n validate: 'url',\n },\n rate_limit: {\n default: '200/hour',\n description: 'Rate limit for API documentation access',\n validate: 'rate_limit',\n },\n },\n policy: {\n defaults: {\n decision: 'deny',\n reason: 'Default deny - explicit permission required',\n },\n name: 'API Provider Policy',\n rules: [\n {\n decision: 'allow',\n name: 'allow-discovery',\n purpose: ['crawl', 'index', 'search', 'ai_index'],\n reason: 'Allow API discovery and search indexing',\n },\n {\n decision: 'deny',\n name: 'block-training',\n purpose: 'train',\n reason: 'API documentation training requires license',\n },\n {\n decision: 'review',\n name: 'inference-with-receipt',\n purpose: ['inference', 'ai_input'],\n reason: 'Inference requires valid PEAC receipt for tracking',\n },\n ],\n version: 'peac-policy/0.1',\n },\n },\n 'news-media': {\n defaults: {\n rate_limit: {\n limit: 100,\n window_seconds: 3600,\n },\n requirements: {\n receipt: true,\n },\n },\n description:\n 'Policy profile for news and media publishers.\\nAllows search engine indexing while blocking unauthorized AI training.\\nInference access requires a valid PEAC receipt.\\n',\n id: 'news-media',\n name: 'News Media Publisher',\n parameters: {\n contact: {\n description: 'Contact email for licensing inquiries',\n example: 'licensing@example.com',\n required: true,\n validate: 'email',\n },\n negotiate_url: {\n description: 'URL for license negotiation',\n required: false,\n validate: 'url',\n },\n rate_limit: {\n default: '100/hour',\n description: 'Rate limit for allowed purposes',\n validate: 'rate_limit',\n },\n },\n policy: {\n defaults: {\n decision: 'deny',\n reason: 'Default deny - explicit permission required',\n },\n name: 'News Media Policy',\n rules: [\n {\n decision: 'allow',\n name: 'allow-search-indexing',\n purpose: ['crawl', 'index', 'search', 'ai_index'],\n reason: 'Allow discovery and search engine indexing',\n },\n {\n decision: 'deny',\n name: 'block-training',\n purpose: 'train',\n reason: 'Training requires explicit licensing agreement',\n },\n {\n decision: 'review',\n name: 'inference-needs-receipt',\n purpose: ['inference', 'ai_input'],\n reason: 'Inference access requires valid PEAC receipt',\n },\n ],\n version: 'peac-policy/0.1',\n },\n },\n 'open-source': {\n defaults: {\n rate_limit: {\n limit: 1000,\n window_seconds: 3600,\n },\n },\n description:\n 'Policy profile for open source projects.\\nFully open access including AI training.\\nEncourages broad AI ecosystem adoption.\\nReceipts are optional for attribution tracking.\\n',\n id: 'open-source',\n name: 'Open Source Project',\n parameters: {\n attribution: {\n default: 'optional',\n description: 'Attribution requirement',\n example: 'required',\n },\n contact: {\n description: 'Project contact or maintainer email',\n example: 'maintainer@example.com',\n required: false,\n validate: 'email',\n },\n },\n policy: {\n defaults: {\n decision: 'allow',\n reason: 'Open source - all access permitted',\n },\n name: 'Open Source Policy',\n rules: [],\n version: 'peac-policy/0.1',\n },\n },\n 'saas-docs': {\n defaults: {\n rate_limit: {\n limit: 500,\n window_seconds: 3600,\n },\n },\n description:\n 'Policy profile for SaaS documentation sites.\\nOpen access for search and inference to improve discoverability.\\nTraining blocked to protect proprietary documentation.\\nReceipts are optional to encourage AI agent adoption.\\n',\n id: 'saas-docs',\n name: 'SaaS Documentation',\n parameters: {\n contact: {\n description: 'Contact email for questions',\n example: 'docs@example.com',\n required: false,\n validate: 'email',\n },\n rate_limit: {\n default: '500/hour',\n description: 'Rate limit for access',\n validate: 'rate_limit',\n },\n },\n policy: {\n defaults: {\n decision: 'allow',\n reason: 'Open by default for documentation',\n },\n name: 'SaaS Documentation Policy',\n rules: [\n {\n decision: 'deny',\n name: 'block-training',\n purpose: 'train',\n reason: 'Proprietary documentation - training requires license',\n },\n ],\n version: 'peac-policy/0.1',\n },\n },\n};\n","/**\n * Profile Loader API\n *\n * Convenience functions for working with pre-built policy profiles.\n *\n * @example\n * ```typescript\n * import { listProfiles, loadProfile, customizeProfile } from '@peac/policy-kit';\n *\n * // List available profiles\n * const ids = listProfiles(); // ['api-provider', 'news-media', ...]\n *\n * // Load a profile\n * const profile = loadProfile('news-media');\n *\n * // Customize with parameters\n * const policy = customizeProfile('news-media', {\n * contact: 'licensing@example.com',\n * rate_limit: '100/hour',\n * });\n * ```\n *\n * @packageDocumentation\n */\n\nimport { PROFILES, PROFILE_IDS, type ProfileId } from './generated/profiles';\nimport type { ProfileDefinition, ProfileParameter, PolicyDocument, RateLimitConfig } from './types';\nimport { parseRateLimit, RateLimitConfigSchema } from './types';\n\n/**\n * Error thrown when profile operations fail\n */\nexport class ProfileError extends Error {\n constructor(\n message: string,\n public readonly code:\n | 'PROFILE_NOT_FOUND'\n | 'INVALID_PARAMETER'\n | 'MISSING_REQUIRED_PARAMETER'\n | 'VALIDATION_FAILED'\n ) {\n super(message);\n this.name = 'ProfileError';\n }\n}\n\n/**\n * Result of parameter validation\n */\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationWarning[];\n}\n\n/**\n * Validation error details\n */\nexport interface ValidationError {\n parameter: string;\n message: string;\n code: 'MISSING_REQUIRED' | 'INVALID_FORMAT' | 'UNKNOWN_PARAMETER';\n}\n\n/**\n * Validation warning details\n */\nexport interface ValidationWarning {\n parameter: string;\n message: string;\n}\n\n/**\n * Customization result with policy and applied defaults\n */\nexport interface CustomizeResult {\n policy: PolicyDocument;\n appliedDefaults: {\n requirements?: { receipt?: boolean };\n rate_limit?: RateLimitConfig;\n };\n parameters: Record<string, string | number | boolean>;\n}\n\n/**\n * List all available profile IDs\n *\n * @returns Array of profile IDs\n *\n * @example\n * ```typescript\n * const ids = listProfiles();\n * // ['api-provider', 'news-media', 'open-source', 'saas-docs']\n * ```\n */\nexport function listProfiles(): ProfileId[] {\n return [...PROFILE_IDS];\n}\n\n/**\n * Check if a profile ID exists\n *\n * @param id - Profile ID to check\n * @returns true if profile exists\n *\n * @example\n * ```typescript\n * if (hasProfile('news-media')) {\n * const profile = loadProfile('news-media');\n * }\n * ```\n */\nexport function hasProfile(id: string): id is ProfileId {\n return PROFILE_IDS.includes(id as ProfileId);\n}\n\n/**\n * Load a profile by ID\n *\n * @param id - Profile ID\n * @returns Profile definition\n * @throws ProfileError if profile not found\n *\n * @example\n * ```typescript\n * const profile = loadProfile('news-media');\n * console.log(profile.name); // 'News Media Publisher'\n * ```\n */\nexport function loadProfile(id: ProfileId): ProfileDefinition {\n const profile = PROFILES[id];\n if (!profile) {\n throw new ProfileError(`Profile not found: ${id}`, 'PROFILE_NOT_FOUND');\n }\n return profile;\n}\n\n/**\n * Get a profile by ID, returning undefined if not found\n *\n * @param id - Profile ID\n * @returns Profile definition or undefined\n *\n * @example\n * ```typescript\n * const profile = getProfile('news-media');\n * if (profile) {\n * console.log(profile.name);\n * }\n * ```\n */\nexport function getProfile(id: string): ProfileDefinition | undefined {\n if (!hasProfile(id)) {\n return undefined;\n }\n return PROFILES[id];\n}\n\n/**\n * Validate parameters against a profile's requirements\n *\n * @param profile - Profile definition or ID\n * @param params - Parameters to validate\n * @returns Validation result with errors and warnings\n *\n * @example\n * ```typescript\n * const result = validateProfileParams('news-media', {\n * contact: 'invalid-email',\n * });\n *\n * if (!result.valid) {\n * console.error(result.errors);\n * }\n * ```\n */\nexport function validateProfileParams(\n profile: ProfileId | ProfileDefinition,\n params: Record<string, unknown>\n): ValidationResult {\n const def = typeof profile === 'string' ? loadProfile(profile) : profile;\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n\n const paramDefs = def.parameters || {};\n const providedKeys = new Set(Object.keys(params));\n\n // Check for required parameters\n for (const [key, paramDef] of Object.entries(paramDefs)) {\n if (paramDef.required && !providedKeys.has(key)) {\n errors.push({\n parameter: key,\n message: `Required parameter missing: ${key}`,\n code: 'MISSING_REQUIRED',\n });\n }\n }\n\n // Validate provided parameters\n for (const [key, value] of Object.entries(params)) {\n const paramDef = paramDefs[key] as ProfileParameter | undefined;\n\n if (!paramDef) {\n errors.push({\n parameter: key,\n message: `Unknown parameter: ${key}`,\n code: 'UNKNOWN_PARAMETER',\n });\n continue;\n }\n\n // Skip validation if value is undefined/null\n if (value === undefined || value === null) {\n if (paramDef.required) {\n errors.push({\n parameter: key,\n message: `Required parameter is null/undefined: ${key}`,\n code: 'MISSING_REQUIRED',\n });\n }\n continue;\n }\n\n // Type-specific validation\n const strValue = String(value);\n const validationError = validateParameterValue(key, strValue, paramDef);\n if (validationError) {\n errors.push(validationError);\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validate a single parameter value\n */\nfunction validateParameterValue(\n key: string,\n value: string,\n paramDef: ProfileParameter\n): ValidationError | null {\n if (!paramDef.validate) {\n return null;\n }\n\n switch (paramDef.validate) {\n case 'email': {\n // Basic email validation\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(value)) {\n return {\n parameter: key,\n message: `Invalid email format: ${value}`,\n code: 'INVALID_FORMAT',\n };\n }\n break;\n }\n\n case 'url': {\n try {\n new URL(value);\n } catch {\n return {\n parameter: key,\n message: `Invalid URL format: ${value}`,\n code: 'INVALID_FORMAT',\n };\n }\n break;\n }\n\n case 'rate_limit': {\n try {\n parseRateLimit(value);\n } catch {\n // Also try parsing as RateLimitConfig object\n const parsed = RateLimitConfigSchema.safeParse(value);\n if (!parsed.success) {\n return {\n parameter: key,\n message: `Invalid rate limit format: ${value}. Expected format: \"100/hour\" or RateLimitConfig object`,\n code: 'INVALID_FORMAT',\n };\n }\n }\n break;\n }\n }\n\n return null;\n}\n\n/**\n * Customize a profile with parameters to produce a PolicyDocument\n *\n * This applies parameter values and profile defaults to create a ready-to-use policy.\n *\n * @param profile - Profile definition or ID\n * @param params - Parameters to apply\n * @returns Customization result with policy and applied defaults\n * @throws ProfileError if validation fails\n *\n * @example\n * ```typescript\n * const result = customizeProfile('news-media', {\n * contact: 'licensing@example.com',\n * rate_limit: '100/hour',\n * });\n *\n * // result.policy is a PolicyDocument ready for use\n * const decision = evaluate(result.policy, context);\n * ```\n */\nexport function customizeProfile(\n profile: ProfileId | ProfileDefinition,\n params: Record<string, unknown> = {}\n): CustomizeResult {\n const def = typeof profile === 'string' ? loadProfile(profile) : profile;\n\n // Validate parameters\n const validation = validateProfileParams(def, params);\n if (!validation.valid) {\n const errorMessages = validation.errors.map((e) => `${e.parameter}: ${e.message}`).join(', ');\n throw new ProfileError(`Parameter validation failed: ${errorMessages}`, 'VALIDATION_FAILED');\n }\n\n // Apply defaults for missing optional parameters\n const appliedParams: Record<string, string | number | boolean> = {};\n for (const [key, paramDef] of Object.entries(def.parameters || {})) {\n if (key in params && params[key] !== undefined && params[key] !== null) {\n appliedParams[key] = params[key] as string | number | boolean;\n } else if (paramDef.default !== undefined) {\n appliedParams[key] = paramDef.default;\n }\n }\n\n // Deep clone the policy to avoid mutations\n const policy: PolicyDocument = JSON.parse(JSON.stringify(def.policy));\n\n // Apply profile defaults\n const appliedDefaults: CustomizeResult['appliedDefaults'] = {};\n\n if (def.defaults?.requirements) {\n appliedDefaults.requirements = { ...def.defaults.requirements };\n }\n\n if (def.defaults?.rate_limit) {\n appliedDefaults.rate_limit = { ...def.defaults.rate_limit };\n }\n\n // If rate_limit parameter was provided, parse and apply it\n if (appliedParams.rate_limit) {\n const rateLimitValue = appliedParams.rate_limit;\n if (typeof rateLimitValue === 'string') {\n try {\n appliedDefaults.rate_limit = parseRateLimit(rateLimitValue);\n } catch {\n // Already validated, should not happen\n }\n }\n }\n\n return {\n policy,\n appliedDefaults,\n parameters: appliedParams,\n };\n}\n\n/**\n * Get all profiles as an array\n *\n * @returns Array of all profile definitions\n *\n * @example\n * ```typescript\n * const profiles = getAllProfiles();\n * for (const profile of profiles) {\n * console.log(`${profile.id}: ${profile.name}`);\n * }\n * ```\n */\nexport function getAllProfiles(): ProfileDefinition[] {\n return PROFILE_IDS.map((id) => PROFILES[id]);\n}\n\n/**\n * Get profile summary for display purposes\n *\n * @param profile - Profile definition or ID\n * @returns Summary object with key information\n *\n * @example\n * ```typescript\n * const summary = getProfileSummary('news-media');\n * console.log(summary);\n * // {\n * // id: 'news-media',\n * // name: 'News Media Publisher',\n * // defaultDecision: 'deny',\n * // ruleCount: 3,\n * // requiresReceipt: true,\n * // requiredParams: ['contact']\n * // }\n * ```\n */\nexport function getProfileSummary(profile: ProfileId | ProfileDefinition): {\n id: string;\n name: string;\n description: string;\n defaultDecision: 'allow' | 'deny' | 'review';\n ruleCount: number;\n requiresReceipt: boolean;\n requiredParams: string[];\n optionalParams: string[];\n} {\n const def = typeof profile === 'string' ? loadProfile(profile) : profile;\n\n const requiredParams: string[] = [];\n const optionalParams: string[] = [];\n\n for (const [key, paramDef] of Object.entries(def.parameters || {})) {\n if (paramDef.required) {\n requiredParams.push(key);\n } else {\n optionalParams.push(key);\n }\n }\n\n return {\n id: def.id,\n name: def.name,\n description: def.description,\n defaultDecision: def.policy.defaults.decision,\n ruleCount: def.policy.rules?.length || 0,\n requiresReceipt: def.defaults?.requirements?.receipt ?? false,\n requiredParams: requiredParams.sort(),\n optionalParams: optionalParams.sort(),\n };\n}\n","/**\n * Decision Enforcement\n *\n * Helpers for enforcing policy decisions with explicit semantics.\n *\n * The `review` decision means \"challenge unless requirement is satisfied\".\n * By default, this means a valid receipt is required.\n *\n * @example\n * ```typescript\n * import { evaluate, enforceDecision } from '@peac/policy-kit';\n *\n * const result = evaluate(policy, context);\n * const enforcement = enforceDecision(result.decision, {\n * receiptVerified: hasValidReceipt,\n * });\n *\n * if (enforcement.allowed) {\n * // proceed\n * } else {\n * // return enforcement.statusCode (402 or 403)\n * }\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { ControlDecision } from './types';\n\n/**\n * Context for enforcement decision\n */\nexport interface EnforcementContext {\n /**\n * Whether a valid PEAC receipt has been verified.\n * If true, `review` decisions are allowed.\n *\n * This is the only requirement for `review` decisions in v0.9.23.\n * Future versions may add additional attestation models.\n */\n receiptVerified?: boolean;\n}\n\n/**\n * Result of enforcement decision\n */\nexport interface EnforcementResult {\n /**\n * Whether access should be allowed\n */\n allowed: boolean;\n\n /**\n * Recommended HTTP status code\n * - 200: OK (allowed)\n * - 402: Payment Required (review decision, receipt needed)\n * - 403: Forbidden (deny decision)\n */\n statusCode: 200 | 402 | 403;\n\n /**\n * Reason for the decision\n */\n reason: string;\n\n /**\n * Whether a challenge should be issued (for review decisions)\n */\n challenge: boolean;\n\n /**\n * The original decision that was enforced\n */\n decision: ControlDecision;\n}\n\n/**\n * Enforce a policy decision with explicit semantics.\n *\n * Decision meanings:\n * - `allow`: Access is permitted (200)\n * - `deny`: Access is forbidden (403)\n * - `review`: Challenge unless requirement is satisfied (default: receipt required)\n *\n * The `review` decision is a \"soft deny\" that becomes \"allow\" when the\n * requirement (typically a valid receipt) is satisfied.\n *\n * @param decision - The policy decision to enforce\n * @param context - Enforcement context with requirement flags\n * @returns Enforcement result with allowed status and HTTP code\n *\n * @example\n * ```typescript\n * // Allow decision\n * enforceDecision('allow', {});\n * // { allowed: true, statusCode: 200, challenge: false }\n *\n * // Deny decision\n * enforceDecision('deny', {});\n * // { allowed: false, statusCode: 403, challenge: false }\n *\n * // Review without receipt\n * enforceDecision('review', { receiptVerified: false });\n * // { allowed: false, statusCode: 402, challenge: true }\n *\n * // Review with valid receipt\n * enforceDecision('review', { receiptVerified: true });\n * // { allowed: true, statusCode: 200, challenge: false }\n * ```\n */\nexport function enforceDecision(\n decision: ControlDecision,\n context: EnforcementContext = {}\n): EnforcementResult {\n switch (decision) {\n case 'allow':\n return {\n allowed: true,\n statusCode: 200,\n reason: 'Access allowed by policy',\n challenge: false,\n decision,\n };\n\n case 'deny':\n return {\n allowed: false,\n statusCode: 403,\n reason: 'Access denied by policy',\n challenge: false,\n decision,\n };\n\n case 'review': {\n // review = \"challenge unless receiptVerified === true\"\n // This is the only requirement in v0.9.23\n if (context.receiptVerified === true) {\n return {\n allowed: true,\n statusCode: 200,\n reason: 'Access allowed - receipt verified',\n challenge: false,\n decision,\n };\n }\n\n // No valid receipt - return 402 Payment Required with challenge\n return {\n allowed: false,\n statusCode: 402,\n reason: 'Access requires verification - present valid receipt',\n challenge: true,\n decision,\n };\n }\n\n default: {\n // Exhaustive check - should never reach here\n const _exhaustive: never = decision;\n return {\n allowed: false,\n statusCode: 403,\n reason: `Unknown decision: ${_exhaustive}`,\n challenge: false,\n decision,\n };\n }\n }\n}\n\n/**\n * Check if an enforcement result requires a challenge response\n *\n * @param result - Enforcement result\n * @returns true if a challenge should be issued\n */\nexport function requiresChallenge(result: EnforcementResult): boolean {\n return result.challenge;\n}\n\n/**\n * Get the WWW-Authenticate header value for a challenge\n *\n * @param result - Enforcement result requiring challenge\n * @returns WWW-Authenticate header value or undefined if no challenge needed\n *\n * @example\n * ```typescript\n * const result = enforceDecision('review', { receiptVerified: false });\n * const header = getChallengeHeader(result);\n * // 'PEAC realm=\"receipt\", error=\"receipt_required\"'\n * ```\n */\nexport function getChallengeHeader(result: EnforcementResult): string | undefined {\n if (!result.challenge) {\n return undefined;\n }\n\n return 'PEAC realm=\"receipt\", error=\"receipt_required\"';\n}\n\n/**\n * Convenience function to enforce and get HTTP response details\n *\n * @param decision - Policy decision\n * @param context - Enforcement context\n * @returns Object with status code and headers for HTTP response\n *\n * @example\n * ```typescript\n * const { status, headers, allowed } = enforceForHttp('review', {\n * receiptVerified: false,\n * });\n * // { status: 402, headers: { 'WWW-Authenticate': '...' }, allowed: false }\n * ```\n */\nexport function enforceForHttp(\n decision: ControlDecision,\n context: EnforcementContext = {}\n): {\n status: number;\n headers: Record<string, string>;\n allowed: boolean;\n reason: string;\n} {\n const result = enforceDecision(decision, context);\n const headers: Record<string, string> = {};\n\n if (result.challenge) {\n const challengeHeader = getChallengeHeader(result);\n if (challengeHeader) {\n headers['WWW-Authenticate'] = challengeHeader;\n }\n }\n\n return {\n status: result.statusCode,\n headers,\n allowed: result.allowed,\n reason: result.reason,\n };\n}\n\n// ============================================================================\n// Purpose-Specific Enforcement (v0.9.24+)\n// ============================================================================\n\n/**\n * Result of purpose-specific enforcement\n *\n * Purpose enforcement NEVER uses 402. 402 is reserved for payment/receipt challenges.\n * Purpose decisions use:\n * - 200: OK (purpose allowed)\n * - 400: Bad Request (invalid purpose token)\n * - 403: Forbidden (purpose denied by policy)\n */\nexport interface PurposeEnforcementResult {\n /**\n * Whether access should be allowed based on purpose\n */\n allowed: boolean;\n\n /**\n * HTTP status code for purpose enforcement\n * - 200: OK (allowed)\n * - 400: Bad Request (invalid purpose token, explicit \"undeclared\")\n * - 403: Forbidden (purpose denied by policy)\n *\n * NOTE: 402 is NEVER returned. 402 is reserved for payment/receipt challenges.\n */\n statusCode: 200 | 400 | 403;\n\n /**\n * Reason for the decision\n */\n reason: string;\n\n /**\n * The purpose decision that was enforced\n */\n decision: ControlDecision;\n}\n\n/**\n * Context for purpose enforcement\n */\nexport interface PurposeEnforcementContext {\n /**\n * Whether the purpose token(s) passed grammar validation.\n * If false, returns 400 Bad Request.\n */\n purposeValid: boolean;\n\n /**\n * Whether the request explicitly included \"undeclared\" as a purpose.\n * If true, returns 400 Bad Request.\n */\n explicitUndeclared?: boolean;\n\n /**\n * Optional list of invalid tokens for error messaging\n */\n invalidTokens?: string[];\n}\n\n/**\n * Enforce a policy decision for purpose-based access control.\n *\n * This function is specifically for purpose enforcement and NEVER returns 402.\n * 402 is reserved for payment/receipt challenges (use `enforceDecision` for that).\n *\n * Status code semantics:\n * - 200: Purpose allowed\n * - 400: Invalid purpose token (grammar violation or explicit \"undeclared\")\n * - 403: Purpose denied by policy\n *\n * @param decision - The policy decision to enforce\n * @param context - Purpose enforcement context\n * @returns Purpose enforcement result with HTTP status code\n *\n * @example\n * ```typescript\n * import { enforcePurposeDecision } from '@peac/policy-kit';\n *\n * // Valid purpose, allowed\n * enforcePurposeDecision('allow', { purposeValid: true });\n * // { allowed: true, statusCode: 200, decision: 'allow' }\n *\n * // Valid purpose, denied by policy\n * enforcePurposeDecision('deny', { purposeValid: true });\n * // { allowed: false, statusCode: 403, decision: 'deny' }\n *\n * // Invalid purpose token\n * enforcePurposeDecision('allow', { purposeValid: false, invalidTokens: ['train-'] });\n * // { allowed: false, statusCode: 400, reason: 'Invalid purpose token(s): train-' }\n *\n * // Explicit \"undeclared\" in request (forbidden)\n * enforcePurposeDecision('allow', { purposeValid: true, explicitUndeclared: true });\n * // { allowed: false, statusCode: 400, reason: '\"undeclared\" is not a valid purpose token' }\n * ```\n */\nexport function enforcePurposeDecision(\n decision: ControlDecision,\n context: PurposeEnforcementContext\n): PurposeEnforcementResult {\n // Check for explicit \"undeclared\" first (always 400)\n if (context.explicitUndeclared) {\n return {\n allowed: false,\n statusCode: 400,\n reason: '\"undeclared\" is not a valid purpose token - it is internal-only',\n decision,\n };\n }\n\n // Check for invalid purpose tokens (400)\n if (!context.purposeValid) {\n const tokenList = context.invalidTokens?.join(', ') || 'unknown';\n return {\n allowed: false,\n statusCode: 400,\n reason: `Invalid purpose token(s): ${tokenList}`,\n decision,\n };\n }\n\n // Valid purpose - apply policy decision\n switch (decision) {\n case 'allow':\n return {\n allowed: true,\n statusCode: 200,\n reason: 'Purpose allowed by policy',\n decision,\n };\n\n case 'deny':\n return {\n allowed: false,\n statusCode: 403,\n reason: 'Purpose denied by policy',\n decision,\n };\n\n case 'review':\n // For purpose enforcement, 'review' is treated as 'deny' (403)\n // 402 is reserved for payment/receipt challenges\n return {\n allowed: false,\n statusCode: 403,\n reason: 'Purpose requires review - treated as denied for purpose enforcement',\n decision,\n };\n\n default: {\n const _exhaustive: never = decision;\n return {\n allowed: false,\n statusCode: 403,\n reason: `Unknown decision: ${_exhaustive}`,\n decision,\n };\n }\n }\n}\n\n/**\n * Get HTTP status code for a purpose decision (low-level helper).\n *\n * This helper maps policy decisions to HTTP status codes for purpose enforcement.\n * It NEVER returns 402 - that is reserved for payment/receipt challenges.\n *\n * For evaluating purpose with profiles, use getPurposeStatusCode from enforcement-profiles\n * which takes a PurposeEvaluationResult directly.\n *\n * @param decision - Policy decision\n * @param purposeValid - Whether the purpose token(s) passed validation\n * @returns HTTP status code (200, 400, or 403)\n *\n * @example\n * ```typescript\n * getPurposeDecisionStatusCode('allow', true); // 200\n * getPurposeDecisionStatusCode('deny', true); // 403\n * getPurposeDecisionStatusCode('review', true); // 403 (NOT 402!)\n * getPurposeDecisionStatusCode('allow', false); // 400 (invalid token)\n * ```\n */\nexport function getPurposeDecisionStatusCode(\n decision: ControlDecision,\n purposeValid: boolean\n): 200 | 400 | 403 {\n // Invalid purpose always returns 400\n if (!purposeValid) {\n return 400;\n }\n\n // Map decision to status code (never 402)\n switch (decision) {\n case 'allow':\n return 200;\n case 'deny':\n case 'review':\n return 403;\n default:\n return 403;\n }\n}\n","/**\n * Enforcement Profiles (v0.9.24+)\n *\n * Pre-defined profiles for handling undeclared and unknown purposes.\n * These are distinct from use-case profiles (api-provider, news-media, etc.).\n *\n * Three canonical profiles:\n * - `strict`: Deny undeclared purposes (regulated data, private APIs)\n * - `balanced`: Review + constraints for undeclared (general web, DEFAULT)\n * - `open`: Allow undeclared purposes with recording (public content, research)\n *\n * @example\n * ```typescript\n * import {\n * getEnforcementProfile,\n * evaluateWithProfile,\n * ENFORCEMENT_PROFILES,\n * } from '@peac/policy-kit';\n *\n * // Get the balanced profile (default)\n * const profile = getEnforcementProfile('balanced');\n *\n * // Evaluate with enforcement profile\n * const result = evaluateWithProfile(policy, context, 'balanced');\n * ```\n *\n * @packageDocumentation\n */\n\nimport type {\n EnforcementProfile,\n EnforcementProfileId,\n PolicyConstraints,\n ControlDecision,\n} from './types';\n\n// -----------------------------------------------------------------------------\n// Canonical Enforcement Profiles\n// -----------------------------------------------------------------------------\n\n/**\n * Strict enforcement profile.\n *\n * Use for: Regulated data, private APIs, compliance-critical resources.\n * - Undeclared purposes: DENY\n * - Unknown purpose tokens: DENY\n * - Receipts: Required\n */\nexport const STRICT_PROFILE: EnforcementProfile = {\n id: 'strict',\n name: 'Strict',\n description:\n 'Deny undeclared purposes. Use for regulated data, private APIs, or compliance-critical resources.',\n undeclared_decision: 'deny',\n unknown_decision: 'deny',\n purpose_reason: 'denied',\n receipts: 'required',\n};\n\n/**\n * Balanced enforcement profile (DEFAULT).\n *\n * Use for: General web, gradual compliance, typical publisher use case.\n * - Undeclared purposes: REVIEW + constraints\n * - Unknown purpose tokens: REVIEW + preserve\n * - Receipts: Optional (encouraged)\n */\nexport const BALANCED_PROFILE: EnforcementProfile = {\n id: 'balanced',\n name: 'Balanced',\n description: 'Review undeclared purposes with rate limits. Default for general web publishers.',\n undeclared_decision: 'review',\n unknown_decision: 'review',\n purpose_reason: 'undeclared_default',\n default_constraints: {\n rate_limit: {\n window_s: 3600, // 1 hour\n max: 100,\n retry_after_s: 60,\n },\n },\n receipts: 'optional',\n};\n\n/**\n * Open enforcement profile.\n *\n * Use for: Public content, research data, open access resources.\n * - Undeclared purposes: ALLOW (recorded)\n * - Unknown purpose tokens: ALLOW (preserved)\n * - Receipts: Optional (for attribution)\n */\nexport const OPEN_PROFILE: EnforcementProfile = {\n id: 'open',\n name: 'Open',\n description:\n 'Allow undeclared purposes with recording. Use for public content and research data.',\n undeclared_decision: 'allow',\n unknown_decision: 'allow',\n purpose_reason: 'allowed',\n receipts: 'optional',\n};\n\n/**\n * All canonical enforcement profiles indexed by ID.\n */\nexport const ENFORCEMENT_PROFILES: Record<EnforcementProfileId, EnforcementProfile> = {\n strict: STRICT_PROFILE,\n balanced: BALANCED_PROFILE,\n open: OPEN_PROFILE,\n};\n\n/**\n * Default enforcement profile ID.\n *\n * `balanced` is the default to encourage adoption while maintaining some protection.\n */\nexport const DEFAULT_ENFORCEMENT_PROFILE: EnforcementProfileId = 'balanced';\n\n/**\n * All enforcement profile IDs.\n */\nexport const ENFORCEMENT_PROFILE_IDS: readonly EnforcementProfileId[] = [\n 'strict',\n 'balanced',\n 'open',\n];\n\n// -----------------------------------------------------------------------------\n// Profile Lookup Functions\n// -----------------------------------------------------------------------------\n\n/**\n * Get an enforcement profile by ID.\n *\n * @param id - Profile ID\n * @returns Enforcement profile\n * @throws Error if profile ID is invalid\n *\n * @example\n * ```typescript\n * const profile = getEnforcementProfile('balanced');\n * console.log(profile.undeclared_decision); // 'review'\n * ```\n */\nexport function getEnforcementProfile(id: EnforcementProfileId): EnforcementProfile {\n const profile = ENFORCEMENT_PROFILES[id];\n if (!profile) {\n throw new Error(`Invalid enforcement profile ID: ${id}`);\n }\n return profile;\n}\n\n/**\n * Check if a string is a valid enforcement profile ID.\n *\n * @param id - String to check\n * @returns true if valid profile ID\n */\nexport function isEnforcementProfileId(id: string): id is EnforcementProfileId {\n return ENFORCEMENT_PROFILE_IDS.includes(id as EnforcementProfileId);\n}\n\n/**\n * Get the default enforcement profile.\n *\n * @returns The balanced profile (default)\n */\nexport function getDefaultEnforcementProfile(): EnforcementProfile {\n return ENFORCEMENT_PROFILES[DEFAULT_ENFORCEMENT_PROFILE];\n}\n\n// -----------------------------------------------------------------------------\n// Purpose Evaluation with Enforcement Profile\n// -----------------------------------------------------------------------------\n\n/**\n * Result of purpose evaluation with enforcement profile.\n */\nexport interface PurposeEvaluationResult {\n /** Decision from enforcement profile */\n decision: ControlDecision;\n\n /** Purpose enforced (for receipts) */\n purpose_enforced?: string;\n\n /** Reason for the decision */\n purpose_reason: string;\n\n /** Constraints to apply (for 'review' decisions) */\n constraints?: PolicyConstraints;\n\n /** Whether the purpose was declared */\n purpose_declared: boolean;\n\n /** Whether unknown purpose tokens were present */\n has_unknown_tokens: boolean;\n\n /** Preserved unknown tokens (for forward compatibility) */\n unknown_tokens: string[];\n\n /** The profile that was applied */\n profile_id: EnforcementProfileId;\n}\n\n/**\n * Canonical purpose tokens that PEAC defines semantics for.\n */\nconst CANONICAL_PURPOSES = new Set(['train', 'search', 'user_action', 'inference', 'index']);\n\n/**\n * Legacy purpose tokens that map to canonical purposes.\n */\nconst LEGACY_PURPOSE_MAP: Record<string, string> = {\n crawl: 'index',\n ai_input: 'inference',\n ai_index: 'index',\n};\n\n/**\n * Check if a purpose token is canonical.\n */\nfunction isCanonicalPurpose(token: string): boolean {\n return CANONICAL_PURPOSES.has(token);\n}\n\n/**\n * Check if a purpose token is a known legacy token.\n */\nfunction isLegacyPurpose(token: string): boolean {\n return token in LEGACY_PURPOSE_MAP;\n}\n\n/**\n * Evaluate declared purposes against an enforcement profile.\n *\n * This determines what decision to make based on the declared purposes\n * and the enforcement profile's rules for undeclared/unknown purposes.\n *\n * @param declaredPurposes - Array of purpose tokens from PEAC-Purpose header\n * @param profileId - Enforcement profile ID (default: 'balanced')\n * @returns Purpose evaluation result\n *\n * @example\n * ```typescript\n * // No purposes declared - uses undeclared_decision from profile\n * const result1 = evaluatePurpose([], 'strict');\n * // { decision: 'deny', purpose_reason: 'denied', ... }\n *\n * // Known purpose declared\n * const result2 = evaluatePurpose(['train'], 'balanced');\n * // { decision: 'allow', purpose_enforced: 'train', ... }\n *\n * // Unknown purpose token\n * const result3 = evaluatePurpose(['vendor:custom'], 'balanced');\n * // { decision: 'review', has_unknown_tokens: true, unknown_tokens: ['vendor:custom'], ... }\n * ```\n */\nexport function evaluatePurpose(\n declaredPurposes: string[],\n profileId: EnforcementProfileId = DEFAULT_ENFORCEMENT_PROFILE\n): PurposeEvaluationResult {\n const profile = getEnforcementProfile(profileId);\n\n // No purposes declared - apply undeclared handling\n if (declaredPurposes.length === 0) {\n return {\n decision: profile.undeclared_decision,\n purpose_reason: 'undeclared_default',\n constraints:\n profile.undeclared_decision === 'review' ? profile.default_constraints : undefined,\n purpose_declared: false,\n has_unknown_tokens: false,\n unknown_tokens: [],\n profile_id: profileId,\n };\n }\n\n // Categorize declared purposes\n const canonicalTokens: string[] = [];\n const legacyTokens: string[] = [];\n const unknownTokens: string[] = [];\n\n for (const token of declaredPurposes) {\n if (isCanonicalPurpose(token)) {\n canonicalTokens.push(token);\n } else if (isLegacyPurpose(token)) {\n legacyTokens.push(token);\n } else {\n unknownTokens.push(token);\n }\n }\n\n // If we have unknown tokens, apply unknown_decision\n if (unknownTokens.length > 0 && canonicalTokens.length === 0 && legacyTokens.length === 0) {\n // Only unknown tokens - apply unknown handling\n return {\n decision: profile.unknown_decision,\n purpose_reason: 'unknown_preserved',\n constraints: profile.unknown_decision === 'review' ? profile.default_constraints : undefined,\n purpose_declared: true,\n has_unknown_tokens: true,\n unknown_tokens: unknownTokens,\n profile_id: profileId,\n };\n }\n\n // We have at least some known tokens - allow with the first canonical/legacy purpose\n const enforcedPurpose = canonicalTokens[0] ?? LEGACY_PURPOSE_MAP[legacyTokens[0]];\n\n return {\n decision: 'allow',\n purpose_enforced: enforcedPurpose,\n purpose_reason: unknownTokens.length > 0 ? 'unknown_preserved' : 'allowed',\n purpose_declared: true,\n has_unknown_tokens: unknownTokens.length > 0,\n unknown_tokens: unknownTokens,\n profile_id: profileId,\n };\n}\n\n/**\n * Get the HTTP status code for a purpose evaluation result.\n *\n * NOTE: 402 is RESERVED for payment - purpose decisions never return 402.\n * - allow -> 200\n * - review -> 403 (NOT 402)\n * - deny -> 403\n *\n * @param result - Purpose evaluation result\n * @returns HTTP status code (200 or 403)\n */\nexport function getPurposeStatusCode(result: PurposeEvaluationResult): 200 | 403 {\n switch (result.decision) {\n case 'allow':\n return 200;\n case 'review':\n case 'deny':\n return 403;\n }\n}\n\n/**\n * Get the Retry-After header value from constraints.\n *\n * @param constraints - Policy constraints\n * @returns Retry-After seconds or undefined\n */\nexport function getRetryAfter(constraints: PolicyConstraints | undefined): number | undefined {\n return constraints?.rate_limit?.retry_after_s;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peac/policy-kit",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.11",
|
|
4
4
|
"description": "PEAC Policy Kit - deterministic policy evaluation for CAL semantics",
|
|
5
|
-
"main": "dist/index.
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -25,21 +25,34 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"yaml": "^2.3.4",
|
|
27
27
|
"zod": "^3.22.4",
|
|
28
|
-
"@peac/schema": "0.10.
|
|
28
|
+
"@peac/schema": "0.10.11"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^20.10.0",
|
|
32
32
|
"tsx": "^4.7.0",
|
|
33
33
|
"typescript": "^5.3.3",
|
|
34
|
-
"vitest": "^
|
|
34
|
+
"vitest": "^4.0.0",
|
|
35
|
+
"tsup": "^8.0.0"
|
|
36
|
+
},
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"types": "./dist/index.d.ts",
|
|
40
|
+
"import": "./dist/index.mjs",
|
|
41
|
+
"require": "./dist/index.cjs",
|
|
42
|
+
"default": "./dist/index.mjs"
|
|
43
|
+
},
|
|
44
|
+
"./package.json": "./package.json"
|
|
35
45
|
},
|
|
36
46
|
"scripts": {
|
|
37
47
|
"generate:profiles": "tsx scripts/generate-profiles.ts",
|
|
38
48
|
"generate:profiles:check": "tsx scripts/generate-profiles.ts --check",
|
|
39
|
-
"
|
|
49
|
+
"prebuild": "rm -rf dist",
|
|
50
|
+
"build": "pnpm generate:profiles && pnpm run build:js && pnpm run build:types",
|
|
40
51
|
"test": "vitest run",
|
|
41
52
|
"test:watch": "vitest",
|
|
42
53
|
"test:smoke": "tsx scripts/tarball-smoke-test.ts",
|
|
43
|
-
"clean": "rm -rf dist"
|
|
54
|
+
"clean": "rm -rf dist",
|
|
55
|
+
"build:js": "tsup",
|
|
56
|
+
"build:types": "rm -f dist/.tsbuildinfo && tsc && rm -f dist/.tsbuildinfo"
|
|
44
57
|
}
|
|
45
58
|
}
|
package/dist/compiler.js
DELETED
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* PEAC Policy Kit Compiler
|
|
4
|
-
*
|
|
5
|
-
* Compiles policy documents to deployment artifacts:
|
|
6
|
-
* - peac.txt (PEAC discovery file - canonical schema)
|
|
7
|
-
* - robots.txt snippet for AI crawlers
|
|
8
|
-
* - AIPREF header templates (compatibility output)
|
|
9
|
-
* - Human-readable markdown summary
|
|
10
|
-
*
|
|
11
|
-
* All outputs are deterministic (stable ordering where semantically safe).
|
|
12
|
-
* Rule order is preserved where it affects semantics (first-match-wins).
|
|
13
|
-
*
|
|
14
|
-
* @packageDocumentation
|
|
15
|
-
*/
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.PEAC_PROTOCOL_VERSION = void 0;
|
|
18
|
-
exports.compilePeacTxt = compilePeacTxt;
|
|
19
|
-
exports.compileRobotsSnippet = compileRobotsSnippet;
|
|
20
|
-
exports.compileAiprefTemplates = compileAiprefTemplates;
|
|
21
|
-
exports.renderPolicyMarkdown = renderPolicyMarkdown;
|
|
22
|
-
/**
|
|
23
|
-
* Default PEAC protocol version for generated peac.txt
|
|
24
|
-
*
|
|
25
|
-
* Uses major.minor format (e.g., "0.9") by default. Pass a full version
|
|
26
|
-
* (e.g., "0.9.17") via peacVersion option if needed.
|
|
27
|
-
*
|
|
28
|
-
* This matches the wire format version from @peac/kernel.
|
|
29
|
-
*/
|
|
30
|
-
exports.PEAC_PROTOCOL_VERSION = '0.9';
|
|
31
|
-
/**
|
|
32
|
-
* Compile policy to peac.txt format (canonical schema)
|
|
33
|
-
*
|
|
34
|
-
* Generates a PEAC discovery file that can be served at:
|
|
35
|
-
* - /.well-known/peac.txt (primary)
|
|
36
|
-
* - /peac.txt (fallback)
|
|
37
|
-
*
|
|
38
|
-
* Output uses canonical PEAC schema with `version` and `usage` fields.
|
|
39
|
-
* Rule order is preserved in comments (first-match-wins semantics).
|
|
40
|
-
*
|
|
41
|
-
* @param policy - Policy document
|
|
42
|
-
* @param options - Compilation options
|
|
43
|
-
* @returns peac.txt content (YAML format)
|
|
44
|
-
*/
|
|
45
|
-
function compilePeacTxt(policy, options = {}) {
|
|
46
|
-
const lines = [];
|
|
47
|
-
const { includeComments = true, peacVersion = exports.PEAC_PROTOCOL_VERSION } = options;
|
|
48
|
-
if (includeComments) {
|
|
49
|
-
lines.push('# PEAC Policy Discovery File');
|
|
50
|
-
lines.push(`# Generated from: ${policy.name || 'peac-policy.yaml'}`);
|
|
51
|
-
lines.push('#');
|
|
52
|
-
lines.push('# Serve at: /.well-known/peac.txt');
|
|
53
|
-
lines.push('# See: https://www.peacprotocol.org');
|
|
54
|
-
lines.push('');
|
|
55
|
-
}
|
|
56
|
-
// PEAC protocol version (canonical field)
|
|
57
|
-
lines.push(`version: ${peacVersion}`);
|
|
58
|
-
// Usage: open (allow default) or conditional (deny/review default)
|
|
59
|
-
const usage = policy.defaults.decision === 'allow' ? 'open' : 'conditional';
|
|
60
|
-
lines.push(`usage: ${usage}`);
|
|
61
|
-
lines.push('');
|
|
62
|
-
// List purposes covered by rules (sorted for determinism - safe because informational)
|
|
63
|
-
const purposes = extractPurposes(policy);
|
|
64
|
-
if (purposes.length > 0) {
|
|
65
|
-
lines.push(`purposes: [${purposes.join(', ')}]`);
|
|
66
|
-
}
|
|
67
|
-
// Attribution if specified
|
|
68
|
-
if (options.attribution && options.attribution !== 'none') {
|
|
69
|
-
lines.push(`attribution: ${options.attribution}`);
|
|
70
|
-
}
|
|
71
|
-
// Receipts: configurable, with sensible defaults based on usage
|
|
72
|
-
// - conditional: defaults to 'required' (explicit receipt needed)
|
|
73
|
-
// - open: defaults to 'optional' (receipt accepted but not required)
|
|
74
|
-
const receiptsDefault = usage === 'conditional' ? 'required' : 'optional';
|
|
75
|
-
const receiptsValue = options.receipts ?? receiptsDefault;
|
|
76
|
-
if (receiptsValue !== 'omit') {
|
|
77
|
-
lines.push(`receipts: ${receiptsValue}`);
|
|
78
|
-
}
|
|
79
|
-
// Rate limit (applies to both open and conditional)
|
|
80
|
-
if (options.rateLimit) {
|
|
81
|
-
lines.push(`rate_limit: ${options.rateLimit}`);
|
|
82
|
-
}
|
|
83
|
-
// Negotiate endpoint (typically for conditional access)
|
|
84
|
-
if (options.negotiateUrl) {
|
|
85
|
-
lines.push(`negotiate: ${options.negotiateUrl}`);
|
|
86
|
-
}
|
|
87
|
-
// Contact if provided
|
|
88
|
-
if (options.contact) {
|
|
89
|
-
lines.push(`contact: ${options.contact}`);
|
|
90
|
-
}
|
|
91
|
-
// Show rule summary in comments (preserve author order - semantically significant)
|
|
92
|
-
if (policy.rules.length > 0 && includeComments) {
|
|
93
|
-
lines.push('');
|
|
94
|
-
lines.push('# Policy rules (first-match-wins, author order preserved):');
|
|
95
|
-
lines.push(`# Source: ${policy.name || 'peac-policy.yaml'} (${policy.rules.length} rules)`);
|
|
96
|
-
for (const rule of policy.rules) {
|
|
97
|
-
lines.push(`# ${rule.name}: ${rule.decision}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return lines.join('\n') + '\n';
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Compile policy to robots.txt snippet for AI crawlers
|
|
104
|
-
*
|
|
105
|
-
* Generates User-agent blocks for known AI crawlers based on policy.
|
|
106
|
-
* Conservative: if default is deny or review, disallows crawling.
|
|
107
|
-
*
|
|
108
|
-
* @param policy - Policy document
|
|
109
|
-
* @param options - Compilation options
|
|
110
|
-
* @returns robots.txt snippet content
|
|
111
|
-
*/
|
|
112
|
-
function compileRobotsSnippet(policy, options = {}) {
|
|
113
|
-
const lines = [];
|
|
114
|
-
const { includeComments = true } = options;
|
|
115
|
-
// Known AI crawler user agents (sorted for determinism)
|
|
116
|
-
const aiCrawlers = [
|
|
117
|
-
'Anthropic-AI',
|
|
118
|
-
'CCBot',
|
|
119
|
-
'ChatGPT-User',
|
|
120
|
-
'Claude-Web',
|
|
121
|
-
'Cohere-AI',
|
|
122
|
-
'GPTBot',
|
|
123
|
-
'Google-Extended',
|
|
124
|
-
'Meta-ExternalAgent',
|
|
125
|
-
'Meta-ExternalFetcher',
|
|
126
|
-
'PerplexityBot',
|
|
127
|
-
'anthropic-ai',
|
|
128
|
-
'cohere-ai',
|
|
129
|
-
];
|
|
130
|
-
if (includeComments) {
|
|
131
|
-
lines.push('# AI Crawler Directives');
|
|
132
|
-
lines.push(`# Generated from PEAC policy: ${policy.name || 'peac-policy.yaml'}`);
|
|
133
|
-
lines.push('#');
|
|
134
|
-
lines.push('# SNIPPET - Review before adding to your robots.txt');
|
|
135
|
-
lines.push(`# Default policy: ${policy.defaults.decision}`);
|
|
136
|
-
lines.push('');
|
|
137
|
-
}
|
|
138
|
-
// Conservative approach: only allow if default is explicitly 'allow'
|
|
139
|
-
// If default is 'deny' or 'review', disallow and require PEAC receipt
|
|
140
|
-
const isDefaultAllow = policy.defaults.decision === 'allow';
|
|
141
|
-
for (const crawler of aiCrawlers) {
|
|
142
|
-
lines.push(`User-agent: ${crawler}`);
|
|
143
|
-
if (isDefaultAllow) {
|
|
144
|
-
lines.push('Allow: /');
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
lines.push('Disallow: /');
|
|
148
|
-
if (includeComments) {
|
|
149
|
-
lines.push('# Requires PEAC receipt for access');
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
lines.push('');
|
|
153
|
-
}
|
|
154
|
-
return lines.join('\n');
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Compile policy to AIPREF header templates
|
|
158
|
-
*
|
|
159
|
-
* Generates header values for HTTP responses.
|
|
160
|
-
* These are COMPATIBILITY templates, not normative PEAC headers.
|
|
161
|
-
* The authoritative policy is always peac.txt.
|
|
162
|
-
*
|
|
163
|
-
* @param policy - Policy document
|
|
164
|
-
* @param options - Compilation options
|
|
165
|
-
* @returns Array of header templates
|
|
166
|
-
*/
|
|
167
|
-
function compileAiprefTemplates(policy, options = {}) {
|
|
168
|
-
const templates = [];
|
|
169
|
-
const { peacVersion = exports.PEAC_PROTOCOL_VERSION } = options;
|
|
170
|
-
const usage = policy.defaults.decision === 'allow' ? 'open' : 'conditional';
|
|
171
|
-
// PEAC-Policy header (debug/compatibility - see peac.txt for authoritative policy)
|
|
172
|
-
templates.push({
|
|
173
|
-
header: 'PEAC-Policy',
|
|
174
|
-
value: `version=${peacVersion}; usage=${usage}; rules=${policy.rules.length}`,
|
|
175
|
-
description: 'Debug/compatibility header - see peac.txt for authoritative policy',
|
|
176
|
-
});
|
|
177
|
-
// X-Robots-Tag for AI (compatibility, widely supported)
|
|
178
|
-
if (policy.defaults.decision === 'deny') {
|
|
179
|
-
templates.push({
|
|
180
|
-
header: 'X-Robots-Tag',
|
|
181
|
-
value: 'noai, noimageai',
|
|
182
|
-
description: 'Compatibility header: signal no AI training (default deny policy)',
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
// Note about AIPREF-style headers
|
|
186
|
-
templates.push({
|
|
187
|
-
header: '# Compatibility Note',
|
|
188
|
-
value: 'See /.well-known/peac.txt for authoritative policy',
|
|
189
|
-
description: 'These headers are for compatibility only. AIPREF-style X-AI-* headers are not generated to avoid contradictions with conditional rules.',
|
|
190
|
-
});
|
|
191
|
-
return templates;
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Render policy as human-readable markdown
|
|
195
|
-
*
|
|
196
|
-
* Generates an ai-policy.md file for documentation.
|
|
197
|
-
*
|
|
198
|
-
* @param policy - Policy document
|
|
199
|
-
* @param options - Compilation options
|
|
200
|
-
* @returns Markdown content
|
|
201
|
-
*/
|
|
202
|
-
function renderPolicyMarkdown(policy, options = {}) {
|
|
203
|
-
const lines = [];
|
|
204
|
-
// Header
|
|
205
|
-
lines.push(`# ${policy.name || 'AI Access Policy'}`);
|
|
206
|
-
lines.push('');
|
|
207
|
-
lines.push(`> Generated from PEAC policy (${policy.version})`);
|
|
208
|
-
lines.push('');
|
|
209
|
-
// Summary
|
|
210
|
-
lines.push('## Summary');
|
|
211
|
-
lines.push('');
|
|
212
|
-
lines.push(`- **Default Decision:** ${policy.defaults.decision}`);
|
|
213
|
-
if (policy.defaults.reason) {
|
|
214
|
-
lines.push(`- **Default Reason:** ${policy.defaults.reason}`);
|
|
215
|
-
}
|
|
216
|
-
lines.push(`- **Total Rules:** ${policy.rules.length}`);
|
|
217
|
-
lines.push('');
|
|
218
|
-
// Contact
|
|
219
|
-
if (options.contact) {
|
|
220
|
-
lines.push(`For questions about this policy, contact: ${options.contact}`);
|
|
221
|
-
lines.push('');
|
|
222
|
-
}
|
|
223
|
-
// How it works
|
|
224
|
-
lines.push('## How This Policy Works');
|
|
225
|
-
lines.push('');
|
|
226
|
-
lines.push('This policy uses **first-match-wins** semantics (like firewall rules). When an AI agent requests access:');
|
|
227
|
-
lines.push('');
|
|
228
|
-
lines.push('1. Rules are evaluated in order');
|
|
229
|
-
lines.push('2. The first matching rule determines the decision');
|
|
230
|
-
lines.push('3. If no rule matches, the default decision applies');
|
|
231
|
-
lines.push('');
|
|
232
|
-
// Rules (preserve author order - first-match-wins semantics are order-dependent)
|
|
233
|
-
if (policy.rules.length > 0) {
|
|
234
|
-
lines.push('## Rules');
|
|
235
|
-
lines.push('');
|
|
236
|
-
lines.push('> Rules are evaluated in order. The first matching rule wins.');
|
|
237
|
-
lines.push('');
|
|
238
|
-
for (const rule of policy.rules) {
|
|
239
|
-
lines.push(`### ${rule.name}`);
|
|
240
|
-
lines.push('');
|
|
241
|
-
lines.push(`- **Decision:** ${rule.decision}`);
|
|
242
|
-
if (rule.reason) {
|
|
243
|
-
lines.push(`- **Reason:** ${rule.reason}`);
|
|
244
|
-
}
|
|
245
|
-
if (rule.subject) {
|
|
246
|
-
const subjectParts = [];
|
|
247
|
-
if (rule.subject.type) {
|
|
248
|
-
const types = Array.isArray(rule.subject.type)
|
|
249
|
-
? rule.subject.type.join(', ')
|
|
250
|
-
: rule.subject.type;
|
|
251
|
-
subjectParts.push(`type: ${types}`);
|
|
252
|
-
}
|
|
253
|
-
if (rule.subject.labels) {
|
|
254
|
-
subjectParts.push(`labels: ${rule.subject.labels.join(', ')}`);
|
|
255
|
-
}
|
|
256
|
-
if (rule.subject.id) {
|
|
257
|
-
subjectParts.push(`id: ${rule.subject.id}`);
|
|
258
|
-
}
|
|
259
|
-
if (subjectParts.length > 0) {
|
|
260
|
-
lines.push(`- **Subject:** ${subjectParts.join('; ')}`);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
if (rule.purpose) {
|
|
264
|
-
const purposes = Array.isArray(rule.purpose) ? rule.purpose.join(', ') : rule.purpose;
|
|
265
|
-
lines.push(`- **Purpose:** ${purposes}`);
|
|
266
|
-
}
|
|
267
|
-
if (rule.licensing_mode) {
|
|
268
|
-
const modes = Array.isArray(rule.licensing_mode)
|
|
269
|
-
? rule.licensing_mode.join(', ')
|
|
270
|
-
: rule.licensing_mode;
|
|
271
|
-
lines.push(`- **Licensing Mode:** ${modes}`);
|
|
272
|
-
}
|
|
273
|
-
lines.push('');
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
// Footer
|
|
277
|
-
lines.push('---');
|
|
278
|
-
lines.push('');
|
|
279
|
-
lines.push('*This policy is enforced via the PEAC Protocol. See [peacprotocol.org](https://www.peacprotocol.org) for more information.*');
|
|
280
|
-
lines.push('');
|
|
281
|
-
return lines.join('\n');
|
|
282
|
-
}
|
|
283
|
-
// --- Helper functions ---
|
|
284
|
-
/**
|
|
285
|
-
* Extract all unique purposes from policy rules (sorted for determinism)
|
|
286
|
-
*/
|
|
287
|
-
function extractPurposes(policy) {
|
|
288
|
-
const purposes = new Set();
|
|
289
|
-
for (const rule of policy.rules) {
|
|
290
|
-
if (rule.purpose) {
|
|
291
|
-
if (Array.isArray(rule.purpose)) {
|
|
292
|
-
for (const p of rule.purpose) {
|
|
293
|
-
purposes.add(p);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
purposes.add(rule.purpose);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
// Sort for deterministic output
|
|
302
|
-
return Array.from(purposes).sort();
|
|
303
|
-
}
|
|
304
|
-
//# sourceMappingURL=compiler.js.map
|