@ai-matrx/alchemy 0.8.32 → 0.8.33

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.33
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/alchemy/v0.8.32..npm/alchemy/v0.8.33 -- apps/shared/alchemy`).
7
+ No source changes intended and no consumer action required.
8
+
3
9
  ## 0.8.32
4
10
 
5
11
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/checks.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var checks_exports={};__export(checks_exports,{GOVERNANCE_COLUMNS:()=>GOVERNANCE_COLUMNS,conflictUpdateColumns:()=>conflictUpdateColumns,findDeadUrlPatterns:()=>findDeadUrlPatterns,findStaleRows:()=>findStaleRows,mirrorRowKey:()=>mirrorRowKey,planColumns:()=>planColumns,planSurfaceSync:()=>planSurfaceSync,renderSurfaceSyncSql:()=>renderSurfaceSyncSql,renderSurfaceSyncStatements:()=>renderSurfaceSyncStatements,routeSegments:()=>routeSegments,sqlLiteral:()=>sqlLiteral,urlPatternMatchesRoute:()=>urlPatternMatchesRoute});module.exports=__toCommonJS(checks_exports);function surfaceClientOf(surfaceName){return surfaceName.split("/")[0]??""}var DEFAULT_SENSITIVITY=Object.freeze({exportable:!0,classification:"ordinary",includedByDefault:!0});function resolveSensitivity(value){return{exportable:value.sensitivity?.exportable??DEFAULT_SENSITIVITY.exportable,classification:value.sensitivity?.classification??DEFAULT_SENSITIVITY.classification,includedByDefault:value.sensitivity?.includedByDefault??DEFAULT_SENSITIVITY.includedByDefault}}var GOVERNANCE_COLUMNS=["organization_id","visibility"];function childKey(schema){return schema?.itemType?["surface_name","item_type","name"]:["surface_name","name"]}function planSurfaceSync(declarations,options){let{organizationId,syncedFrom,schema}=options,provenance={synced_by:options.syncedBy??null,synced_from:syncedFrom},governance={organization_id:organizationId,visibility:"public"},surfaces=[],values=[],targets=[],itemTypes=[],extensionTables=new Map;for(let d of declarations){let urlPattern=d.urlPattern?.trim()||options.resolveUrlPattern?.(d)||null,intro=d.intro?.trim()||null,parent=d.inheritsFrom??null,owned={client_name:surfaceClientOf(d.surfaceName),execution_mode:d.executionMode,description:d.description,label:d.label,value_groups:d.groups??[],readiness:d.readiness,readiness_note:d.readinessNote?.trim()||null,...schema?.contentHash?{content_hash:d.contentHash}:{}},claimed={...d.overlayId?{overlay_id:d.overlayId}:{},...urlPattern?{url_pattern:urlPattern}:{},...intro?{intro}:{},...parent?{parent_surface_name:parent}:{}};surfaces.push({name:d.surfaceName,insert:{name:d.surfaceName,...owned,overlay_id:d.overlayId??null,url_pattern:urlPattern,intro,parent_surface_name:parent},update:{...owned,...claimed}});for(let v of d.values)values.push({...governance,surface_name:d.surfaceName,...schema?.itemType?{item_type:""}:{},name:v.name,label:v.label,description:v.description,value_type:v.valueType,always_available:v.alwaysAvailable,typical_char_count:v.typicalCharCount,sort_order:v.sortOrder??1e3,auto_context:v.autoContext??!0,group_key:v.groupKey??v.group??"general",...schema?.valueContract?{exportable:resolveSensitivity(v).exportable,classification:resolveSensitivity(v).classification,included_by_default:resolveSensitivity(v).includedByDefault,kind_key:v.valueKind??null,live_slot:v.liveSlot??null,role:v.role??"data"}:{},...provenance});for(let t of d.writeTargets??[])targets.push({...governance,surface_name:d.surfaceName,...schema?.itemType?{item_type:t.itemType??""}:{},name:t.name,label:t.label,description:t.description,value_type:t.valueType,mode:t.mode,updates_value:t.updatesValue??null,group_key:t.group??"general",sort_order:t.sortOrder??1e3,apply_policy:t.applyPolicy??"manual",kind_key:t.valueKind??null,...schema?.valueContract?{patchable:t.patchable??!1,approval_comparison:t.approvalComparison??null,stream_ops:t.streamOps?[...t.streamOps]:null,destination:t.destination??!1}:{},...provenance});if(schema?.itemType)for(let[position,item]of(d.itemTypes??[]).entries()){itemTypes.push({...governance,surface_name:d.surfaceName,name:item.name,label:item.label,description:item.description,identity:[...item.identity],levels:item.levels?[...item.levels]:null,entity_type:item.entityType??null,sort_order:position,...provenance});for(let v of item.values)values.push({...governance,surface_name:d.surfaceName,item_type:item.name,name:v.name,label:v.label,description:v.description,value_type:v.valueType,always_available:v.alwaysAvailable,typical_char_count:v.typicalCharCount,sort_order:v.sortOrder??1e3,auto_context:v.autoContext??!0,group_key:v.group??"general",...provenance})}for(let extension of options.extensions??[])for(let entry of extension.toRows?.(d)??[]){let plan=extensionTables.get(entry.table)??{table:entry.table,conflict:entry.conflict,insertOnly:GOVERNANCE_COLUMNS,rows:[]};plan.rows.push({...governance,...entry.row,...provenance}),extensionTables.set(entry.table,plan)}}let keys={"ui.ui_surface_value":childKey(schema),"ui.ui_surface_write_target":childKey(schema),...schema?.itemType?{"ui.ui_surface_item_type":["surface_name","name"]}:{}};for(let extension of options.extensions??[])extension.mirror&&(keys[extension.mirror.table]=extension.mirror.conflict);for(let plan of extensionTables.values())keys[plan.table]??=plan.conflict;let tables=[{table:"ui.ui_surface_value",conflict:childKey(schema),insertOnly:GOVERNANCE_COLUMNS,rows:values},{table:"ui.ui_surface_write_target",conflict:childKey(schema),insertOnly:GOVERNANCE_COLUMNS,rows:targets},...schema?.itemType?[{table:"ui.ui_surface_item_type",conflict:["surface_name","name"],insertOnly:GOVERNANCE_COLUMNS,rows:itemTypes}]:[],...extensionTables.values()];return{surfaces,tables:tables.filter(table=>table.rows.length>0),keys}}function mirrorRowKey(row,columns){return columns.map(column=>String(row[column]??"")).join("\0")}function findStaleRows(plan,table,existing){let key=plan.keys[table];if(!key)throw new Error(`Sync plan declares no key for "${table}"; give the extension that owns it a \`mirror\` entry.`);let managed=new Set(plan.surfaces.map(surface=>surface.name)),declared=new Set((plan.tables.find(entry=>entry.table===table)?.rows??[]).map(row=>mirrorRowKey(row,key)));return existing.filter(row=>managed.has(String(row.surface_name))&&!declared.has(mirrorRowKey(row,key)))}function planColumns(table){let columns=[];for(let row of table.rows)for(let key of Object.keys(row))columns.includes(key)||columns.push(key);return columns}function conflictUpdateColumns(table){return planColumns(table).filter(c=>!table.conflict.includes(c)&&!table.insertOnly.includes(c))}function sqlLiteral(value){return value==null?"NULL":typeof value=="boolean"||typeof value=="number"?String(value):typeof value=="string"?`'${value.replace(/'/g,"''")}'`:Array.isArray(value)&&value.every(entry=>typeof entry=="string")?`ARRAY[${value.map(entry=>sqlLiteral(entry)).join(", ")}]::text[]`:`'${JSON.stringify(value).replace(/'/g,"''")}'::jsonb`}function renderSurfaceSyncStatements(plan){let statements=[];if(plan.surfaces.length>0){let insertColumns=Object.keys(plan.surfaces[0].insert);statements.push(`INSERT INTO ui.ui_surface (${insertColumns.join(", ")}) VALUES
1
+ "use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var checks_exports={};__export(checks_exports,{GOVERNANCE_COLUMNS:()=>GOVERNANCE_COLUMNS,conflictUpdateColumns:()=>conflictUpdateColumns,findDeadUrlPatterns:()=>findDeadUrlPatterns,findStaleRows:()=>findStaleRows,mirrorRowKey:()=>mirrorRowKey,planColumns:()=>planColumns,planSurfaceSync:()=>planSurfaceSync,renderSurfaceSyncSql:()=>renderSurfaceSyncSql,renderSurfaceSyncStatements:()=>renderSurfaceSyncStatements,routeSegments:()=>routeSegments,sqlLiteral:()=>sqlLiteral,urlPatternMatchesRoute:()=>urlPatternMatchesRoute});module.exports=__toCommonJS(checks_exports);function surfaceClientOf(surfaceName){return surfaceName.split("/")[0]??""}var DEFAULT_SENSITIVITY=Object.freeze({exportable:!0,classification:"ordinary",includedByDefault:!0});function resolveSensitivity(value){return{exportable:value.sensitivity?.exportable??DEFAULT_SENSITIVITY.exportable,classification:value.sensitivity?.classification??DEFAULT_SENSITIVITY.classification,includedByDefault:value.sensitivity?.includedByDefault??DEFAULT_SENSITIVITY.includedByDefault}}var GOVERNANCE_COLUMNS=["organization_id","published_to_web"];function childKey(schema){return schema?.itemType?["surface_name","item_type","name"]:["surface_name","name"]}function planSurfaceSync(declarations,options){let{organizationId,syncedFrom,schema}=options,provenance={synced_by:options.syncedBy??null,synced_from:syncedFrom},governance={organization_id:organizationId,published_to_web:!0},surfaces=[],values=[],targets=[],itemTypes=[],extensionTables=new Map;for(let d of declarations){let urlPattern=d.urlPattern?.trim()||options.resolveUrlPattern?.(d)||null,intro=d.intro?.trim()||null,parent=d.inheritsFrom??null,owned={client_name:surfaceClientOf(d.surfaceName),execution_mode:d.executionMode,description:d.description,label:d.label,value_groups:d.groups??[],readiness:d.readiness,readiness_note:d.readinessNote?.trim()||null,...schema?.contentHash?{content_hash:d.contentHash}:{}},claimed={...d.overlayId?{overlay_id:d.overlayId}:{},...urlPattern?{url_pattern:urlPattern}:{},...intro?{intro}:{},...parent?{parent_surface_name:parent}:{}};surfaces.push({name:d.surfaceName,insert:{name:d.surfaceName,...owned,overlay_id:d.overlayId??null,url_pattern:urlPattern,intro,parent_surface_name:parent},update:{...owned,...claimed}});for(let v of d.values)values.push({...governance,surface_name:d.surfaceName,...schema?.itemType?{item_type:""}:{},name:v.name,label:v.label,description:v.description,value_type:v.valueType,always_available:v.alwaysAvailable,typical_char_count:v.typicalCharCount,sort_order:v.sortOrder??1e3,auto_context:v.autoContext??!0,group_key:v.groupKey??v.group??"general",...schema?.valueContract?{exportable:resolveSensitivity(v).exportable,classification:resolveSensitivity(v).classification,included_by_default:resolveSensitivity(v).includedByDefault,kind_key:v.valueKind??null,live_slot:v.liveSlot??null,role:v.role??"data"}:{},...provenance});for(let t of d.writeTargets??[])targets.push({...governance,surface_name:d.surfaceName,...schema?.itemType?{item_type:t.itemType??""}:{},name:t.name,label:t.label,description:t.description,value_type:t.valueType,mode:t.mode,updates_value:t.updatesValue??null,group_key:t.group??"general",sort_order:t.sortOrder??1e3,apply_policy:t.applyPolicy??"manual",kind_key:t.valueKind??null,...schema?.valueContract?{patchable:t.patchable??!1,approval_comparison:t.approvalComparison??null,stream_ops:t.streamOps?[...t.streamOps]:null,destination:t.destination??!1}:{},...provenance});if(schema?.itemType)for(let[position,item]of(d.itemTypes??[]).entries()){itemTypes.push({...governance,surface_name:d.surfaceName,name:item.name,label:item.label,description:item.description,identity:[...item.identity],levels:item.levels?[...item.levels]:null,entity_type:item.entityType??null,sort_order:position,...provenance});for(let v of item.values)values.push({...governance,surface_name:d.surfaceName,item_type:item.name,name:v.name,label:v.label,description:v.description,value_type:v.valueType,always_available:v.alwaysAvailable,typical_char_count:v.typicalCharCount,sort_order:v.sortOrder??1e3,auto_context:v.autoContext??!0,group_key:v.group??"general",...provenance})}for(let extension of options.extensions??[])for(let entry of extension.toRows?.(d)??[]){let plan=extensionTables.get(entry.table)??{table:entry.table,conflict:entry.conflict,insertOnly:GOVERNANCE_COLUMNS,rows:[]};plan.rows.push({...governance,...entry.row,...provenance}),extensionTables.set(entry.table,plan)}}let keys={"ui.ui_surface_value":childKey(schema),"ui.ui_surface_write_target":childKey(schema),...schema?.itemType?{"ui.ui_surface_item_type":["surface_name","name"]}:{}};for(let extension of options.extensions??[])extension.mirror&&(keys[extension.mirror.table]=extension.mirror.conflict);for(let plan of extensionTables.values())keys[plan.table]??=plan.conflict;let tables=[{table:"ui.ui_surface_value",conflict:childKey(schema),insertOnly:GOVERNANCE_COLUMNS,rows:values},{table:"ui.ui_surface_write_target",conflict:childKey(schema),insertOnly:GOVERNANCE_COLUMNS,rows:targets},...schema?.itemType?[{table:"ui.ui_surface_item_type",conflict:["surface_name","name"],insertOnly:GOVERNANCE_COLUMNS,rows:itemTypes}]:[],...extensionTables.values()];return{surfaces,tables:tables.filter(table=>table.rows.length>0),keys}}function mirrorRowKey(row,columns){return columns.map(column=>String(row[column]??"")).join("\0")}function findStaleRows(plan,table,existing){let key=plan.keys[table];if(!key)throw new Error(`Sync plan declares no key for "${table}"; give the extension that owns it a \`mirror\` entry.`);let managed=new Set(plan.surfaces.map(surface=>surface.name)),declared=new Set((plan.tables.find(entry=>entry.table===table)?.rows??[]).map(row=>mirrorRowKey(row,key)));return existing.filter(row=>managed.has(String(row.surface_name))&&!declared.has(mirrorRowKey(row,key)))}function planColumns(table){let columns=[];for(let row of table.rows)for(let key of Object.keys(row))columns.includes(key)||columns.push(key);return columns}function conflictUpdateColumns(table){return planColumns(table).filter(c=>!table.conflict.includes(c)&&!table.insertOnly.includes(c))}function sqlLiteral(value){return value==null?"NULL":typeof value=="boolean"||typeof value=="number"?String(value):typeof value=="string"?`'${value.replace(/'/g,"''")}'`:Array.isArray(value)&&value.every(entry=>typeof entry=="string")?`ARRAY[${value.map(entry=>sqlLiteral(entry)).join(", ")}]::text[]`:`'${JSON.stringify(value).replace(/'/g,"''")}'::jsonb`}function renderSurfaceSyncStatements(plan){let statements=[];if(plan.surfaces.length>0){let insertColumns=Object.keys(plan.surfaces[0].insert);statements.push(`INSERT INTO ui.ui_surface (${insertColumns.join(", ")}) VALUES
2
2
  ${plan.surfaces.map(s=>`(${insertColumns.map(c=>sqlLiteral(s.insert[c])).join(", ")})`).join(`,
3
3
  `)}
4
4
  ON CONFLICT (name) DO NOTHING`);for(let s of plan.surfaces)statements.push(`UPDATE ui.ui_surface SET ${Object.entries(s.update).map(([c,v])=>`${c} = ${sqlLiteral(v)}`).join(", ")}, updated_at = now() WHERE name = ${sqlLiteral(s.name)}`)}for(let table of plan.tables){let columns=planColumns(table),sets=conflictUpdateColumns(table).map(c=>`${c} = EXCLUDED.${c}`);statements.push(`INSERT INTO ${table.table} (${columns.join(", ")}) VALUES
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/checks.ts","../src/declare/keys.ts","../src/declare/sensitivity.ts","../src/checks/sync.ts","../src/checks/routes.ts"],"sourcesContent":["/**\n * `@ai-matrx/alchemy/checks` — the ONE surface sync (CONTRACT §2.7): the row plan\n * every sync path executes, and its SQL rendering. Pure; no database client.\n */\nexport {\n GOVERNANCE_COLUMNS,\n conflictUpdateColumns,\n findStaleRows,\n mirrorRowKey,\n planColumns,\n planSurfaceSync,\n renderSurfaceSyncSql,\n renderSurfaceSyncStatements,\n sqlLiteral,\n type SurfaceRowPlan,\n type SurfaceSyncPlan,\n type SurfaceSyncPlanOptions,\n type SyncSchema,\n type SyncTablePlan,\n} from \"./checks/sync\";\nexport { findDeadUrlPatterns, routeSegments, urlPatternMatchesRoute } from \"./checks/routes\";\n","import type { QualifiedValueKey } from \"./types\";\n\n/** Every value, write-target, item-type and group name (the DB CHECK rule). */\nexport const DECLARATION_NAME_RE = /^[a-z][a-z0-9_]*$/;\n\n/** \"<client>/<local>\" — the surface naming convention. */\nexport const SURFACE_NAME_RE = /^[a-z][a-z0-9-]*\\/[a-z0-9-/]+$/;\n\n/** A bare screen value (`status`) or an item value (`table_row.status`). */\nexport const QUALIFIED_VALUE_KEY_RE = /^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)?$/;\n\nexport interface ParsedValueKey {\n /** \"\" for a screen-level value. */\n itemType: string;\n name: string;\n}\n\n/** Split a qualified key; null when it is not a valid bare or qualified key. */\nexport function parseQualifiedValueKey(key: string): ParsedValueKey | null {\n if (!QUALIFIED_VALUE_KEY_RE.test(key)) return null;\n const dot = key.indexOf(\".\");\n if (dot === -1) return { itemType: \"\", name: key };\n return { itemType: key.slice(0, dot), name: key.slice(dot + 1) };\n}\n\nexport function qualifyValueKey(itemType: string, name: string): QualifiedValueKey {\n return itemType ? `${itemType}.${name}` : name;\n}\n\n/** The client that owns a surface: its name prefix. */\nexport function surfaceClientOf(surfaceName: string): string {\n return surfaceName.split(\"/\")[0] ?? \"\";\n}\n","/**\n * Sensitivity defaults and resolution (CONTRACT §2.1). Its own module so the\n * lightweight entries (`/actions`, the T0 React host) can project without\n * pulling the declaration registry.\n */\nimport type { DeclaredValue, Sensitivity } from \"./types\";\n\nexport const DEFAULT_SENSITIVITY: Sensitivity = Object.freeze({\n exportable: true,\n classification: \"ordinary\",\n includedByDefault: true,\n});\n\nexport function resolveSensitivity(value: Pick<DeclaredValue, \"sensitivity\">): Sensitivity {\n return {\n exportable: value.sensitivity?.exportable ?? DEFAULT_SENSITIVITY.exportable,\n classification: value.sensitivity?.classification ?? DEFAULT_SENSITIVITY.classification,\n includedByDefault: value.sensitivity?.includedByDefault ?? DEFAULT_SENSITIVITY.includedByDefault,\n };\n}\n","/**\n * THE ONE SYNC (CONTRACT §2.7 \"One sync path\", chair ruling B1).\n *\n * `planSurfaceSync` maps resolved declarations onto the `ui` mirror rows; every\n * sync path (the SQL emitter and the admin sync service) executes this plan and\n * builds no rows of its own. Governance columns (`organization_id`,\n * `visibility`) are INSERT-ONLY (chair ruling N5): a conflict never rewrites them.\n *\n * Schema generations: the columns added by the ALC-14 migration (item_type,\n * sensitivity, live slots, content_hash) are emitted only when the caller says\n * that migration is live (`schema`), so no emitter ever writes a column — or\n * upserts against a key — the database does not have yet.\n */\nimport { resolveSensitivity, type Resolved } from \"../declare/registry\";\nimport { surfaceClientOf } from \"../declare/keys\";\nimport type { DeclarationExtension, Json, SurfaceDeclaration } from \"../declare/types\";\n\nexport const GOVERNANCE_COLUMNS = [\"organization_id\", \"visibility\"] as const;\n\nexport interface SyncSchema {\n /** `ui_surface_value/write_target.item_type` exists and the conflict key includes it (re-key step 1). */\n itemType?: boolean;\n /** Sensitivity, kind, live slot and role columns exist on `ui_surface_value`. */\n valueContract?: boolean;\n /** `ui_surface.content_hash` exists. */\n contentHash?: boolean;\n}\n\nexport interface SurfaceSyncPlanOptions<D extends SurfaceDeclaration> {\n organizationId: string;\n syncedFrom: string;\n syncedBy?: string | null;\n /** The address the host derives for a declaration without `urlPattern`. */\n resolveUrlPattern?: (declaration: Resolved<D>) => string | undefined;\n extensions?: readonly DeclarationExtension<D>[];\n schema?: SyncSchema;\n}\n\nexport interface SurfaceRowPlan {\n name: string;\n /** Written only when the row does not exist yet. */\n insert: Record<string, Json>;\n /** Written on every sync (code owns these columns). */\n update: Record<string, Json>;\n}\n\nexport interface SyncTablePlan {\n table: string;\n /** The ON CONFLICT target (a unique index or primary key on exactly these columns). */\n conflict: readonly string[];\n /** Columns set on insert and never on conflict. */\n insertOnly: readonly string[];\n rows: Record<string, Json>[];\n}\n\nexport interface SurfaceSyncPlan {\n surfaces: SurfaceRowPlan[];\n tables: SyncTablePlan[];\n /**\n * The key (ON CONFLICT target) of every mirror table this plan owns,\n * including tables it emits no rows for. Stale detection and deletes use\n * exactly these columns (`findStaleRows`).\n */\n keys: Record<string, readonly string[]>;\n}\n\nfunction childKey(schema: SyncSchema | undefined): readonly string[] {\n return schema?.itemType ? [\"surface_name\", \"item_type\", \"name\"] : [\"surface_name\", \"name\"];\n}\n\nexport function planSurfaceSync<D extends SurfaceDeclaration>(\n declarations: readonly Resolved<D>[],\n options: SurfaceSyncPlanOptions<D>,\n): SurfaceSyncPlan {\n const { organizationId, syncedFrom, schema } = options;\n const syncedBy = options.syncedBy ?? null;\n const provenance = { synced_by: syncedBy, synced_from: syncedFrom };\n const governance = { organization_id: organizationId, visibility: \"public\" };\n const surfaces: SurfaceRowPlan[] = [];\n const values: Record<string, Json>[] = [];\n const targets: Record<string, Json>[] = [];\n const itemTypes: Record<string, Json>[] = [];\n const extensionTables = new Map<string, SyncTablePlan>();\n\n for (const d of declarations) {\n const urlPattern = d.urlPattern?.trim() || options.resolveUrlPattern?.(d) || null;\n const intro = d.intro?.trim() || null;\n const parent = d.inheritsFrom ?? null;\n const client = surfaceClientOf(d.surfaceName);\n const owned: Record<string, Json> = {\n client_name: client,\n execution_mode: d.executionMode,\n description: d.description,\n label: d.label,\n value_groups: (d.groups ?? []) as unknown as Json,\n readiness: d.readiness,\n readiness_note: d.readinessNote?.trim() || null,\n ...(schema?.contentHash ? { content_hash: d.contentHash } : {}),\n };\n // A declaration that does not claim these never clears a DB-authored value.\n const claimed: Record<string, Json> = {\n ...(d.overlayId ? { overlay_id: d.overlayId } : {}),\n ...(urlPattern ? { url_pattern: urlPattern } : {}),\n ...(intro ? { intro } : {}),\n ...(parent ? { parent_surface_name: parent } : {}),\n };\n surfaces.push({\n name: d.surfaceName,\n insert: {\n name: d.surfaceName,\n ...owned,\n overlay_id: d.overlayId ?? null,\n url_pattern: urlPattern,\n intro,\n parent_surface_name: parent,\n },\n update: { ...owned, ...claimed },\n });\n\n for (const v of d.values) {\n values.push({\n ...governance,\n surface_name: d.surfaceName,\n ...(schema?.itemType ? { item_type: \"\" } : {}),\n name: v.name,\n label: v.label,\n description: v.description,\n value_type: v.valueType,\n always_available: v.alwaysAvailable,\n typical_char_count: v.typicalCharCount,\n sort_order: v.sortOrder ?? 1000,\n auto_context: v.autoContext ?? true,\n group_key: v.groupKey ?? v.group ?? \"general\",\n ...(schema?.valueContract\n ? {\n exportable: resolveSensitivity(v).exportable,\n classification: resolveSensitivity(v).classification,\n included_by_default: resolveSensitivity(v).includedByDefault,\n kind_key: v.valueKind ?? null,\n live_slot: v.liveSlot ?? null,\n role: v.role ?? \"data\",\n }\n : {}),\n ...provenance,\n });\n }\n\n for (const t of d.writeTargets ?? []) {\n targets.push({\n ...governance,\n surface_name: d.surfaceName,\n ...(schema?.itemType ? { item_type: t.itemType ?? \"\" } : {}),\n name: t.name,\n label: t.label,\n description: t.description,\n value_type: t.valueType,\n mode: t.mode,\n updates_value: t.updatesValue ?? null,\n group_key: t.group ?? \"general\",\n sort_order: t.sortOrder ?? 1000,\n apply_policy: t.applyPolicy ?? \"manual\",\n kind_key: t.valueKind ?? null,\n ...(schema?.valueContract\n ? {\n patchable: t.patchable ?? false,\n approval_comparison: t.approvalComparison ?? null,\n stream_ops: t.streamOps ? [...t.streamOps] : null,\n destination: t.destination ?? false,\n }\n : {}),\n ...provenance,\n });\n }\n\n if (schema?.itemType) {\n for (const [position, item] of (d.itemTypes ?? []).entries()) {\n itemTypes.push({\n ...governance,\n surface_name: d.surfaceName,\n name: item.name,\n label: item.label,\n description: item.description,\n identity: [...item.identity],\n levels: item.levels ? [...item.levels] : null,\n entity_type: item.entityType ?? null,\n sort_order: position,\n ...provenance,\n });\n for (const v of item.values) {\n values.push({\n ...governance,\n surface_name: d.surfaceName,\n item_type: item.name,\n name: v.name,\n label: v.label,\n description: v.description,\n value_type: v.valueType,\n always_available: v.alwaysAvailable,\n typical_char_count: v.typicalCharCount,\n sort_order: v.sortOrder ?? 1000,\n auto_context: v.autoContext ?? true,\n group_key: v.group ?? \"general\",\n ...provenance,\n });\n }\n }\n }\n\n for (const extension of options.extensions ?? []) {\n for (const entry of extension.toRows?.(d as unknown as D) ?? []) {\n const plan = extensionTables.get(entry.table) ?? {\n table: entry.table,\n conflict: entry.conflict,\n insertOnly: GOVERNANCE_COLUMNS,\n rows: [],\n };\n plan.rows.push({ ...governance, ...entry.row, ...provenance });\n extensionTables.set(entry.table, plan);\n }\n }\n }\n\n const keys: Record<string, readonly string[]> = {\n \"ui.ui_surface_value\": childKey(schema),\n \"ui.ui_surface_write_target\": childKey(schema),\n ...(schema?.itemType ? { \"ui.ui_surface_item_type\": [\"surface_name\", \"name\"] } : {}),\n };\n for (const extension of options.extensions ?? []) {\n if (extension.mirror) keys[extension.mirror.table] = extension.mirror.conflict;\n }\n for (const plan of extensionTables.values()) keys[plan.table] ??= plan.conflict;\n\n const tables: SyncTablePlan[] = [\n { table: \"ui.ui_surface_value\", conflict: childKey(schema), insertOnly: GOVERNANCE_COLUMNS, rows: values },\n { table: \"ui.ui_surface_write_target\", conflict: childKey(schema), insertOnly: GOVERNANCE_COLUMNS, rows: targets },\n ...(schema?.itemType\n ? [{ table: \"ui.ui_surface_item_type\", conflict: [\"surface_name\", \"name\"], insertOnly: GOVERNANCE_COLUMNS, rows: itemTypes }]\n : []),\n ...extensionTables.values(),\n ];\n return { surfaces, tables: tables.filter((table) => table.rows.length > 0), keys };\n}\n\n/** One row's key under `columns` (a missing column reads as ''). */\nexport function mirrorRowKey(row: Readonly<Record<string, unknown>>, columns: readonly string[]): string {\n return columns.map((column) => String(row[column] ?? \"\")).join(\"\\u0000\");\n}\n\n/**\n * Rows of `table` that belong to a surface this plan manages but that the\n * plan no longer declares, judged by the table's full key (`plan.keys`) — so\n * a screen value and an item value that share a name are distinct rows. The\n * caller deletes each returned row filtered by every column of that key.\n */\nexport function findStaleRows<R extends Readonly<Record<string, unknown>>>(\n plan: SurfaceSyncPlan,\n table: string,\n existing: readonly R[],\n): R[] {\n const key = plan.keys[table];\n if (!key) {\n throw new Error(\n `Sync plan declares no key for \"${table}\"; give the extension that owns it a \\`mirror\\` entry.`,\n );\n }\n const managed = new Set(plan.surfaces.map((surface) => surface.name));\n const declared = new Set(\n (plan.tables.find((entry) => entry.table === table)?.rows ?? []).map((row) => mirrorRowKey(row, key)),\n );\n return existing.filter(\n (row) => managed.has(String(row.surface_name)) && !declared.has(mirrorRowKey(row, key)),\n );\n}\n\n/** Every column a table's rows carry, in first-seen order. */\nexport function planColumns(table: SyncTablePlan): string[] {\n const columns: string[] = [];\n for (const row of table.rows) for (const key of Object.keys(row)) if (!columns.includes(key)) columns.push(key);\n return columns;\n}\n\n/** Columns a conflict rewrites: everything except the key and the insert-only set. */\nexport function conflictUpdateColumns(table: SyncTablePlan): string[] {\n return planColumns(table).filter((c) => !table.conflict.includes(c) && !table.insertOnly.includes(c));\n}\n\nexport function sqlLiteral(value: Json | undefined): string {\n if (value === null || value === undefined) return \"NULL\";\n if (typeof value === \"boolean\" || typeof value === \"number\") return String(value);\n if (typeof value === \"string\") return `'${value.replace(/'/g, \"''\")}'`;\n if (Array.isArray(value) && value.every((entry) => typeof entry === \"string\")) {\n return `ARRAY[${value.map((entry) => sqlLiteral(entry)).join(\", \")}]::text[]`;\n }\n return `'${JSON.stringify(value).replace(/'/g, \"''\")}'::jsonb`;\n}\n\n/**\n * The plan as SQL statements, one per entry: surface insert, one UPDATE per\n * surface, one upsert per table. Callers may run them, or EXPLAIN each one in a\n * read-only transaction to prove the plan against a live schema with no write.\n */\nexport function renderSurfaceSyncStatements(plan: SurfaceSyncPlan): string[] {\n const statements: string[] = [];\n if (plan.surfaces.length > 0) {\n const insertColumns = Object.keys(plan.surfaces[0]!.insert);\n statements.push(\n `INSERT INTO ui.ui_surface (${insertColumns.join(\", \")}) VALUES\\n${plan.surfaces\n .map((s) => `(${insertColumns.map((c) => sqlLiteral(s.insert[c])).join(\", \")})`)\n .join(\",\\n\")}\\nON CONFLICT (name) DO NOTHING`,\n );\n for (const s of plan.surfaces) {\n statements.push(\n `UPDATE ui.ui_surface SET ${Object.entries(s.update)\n .map(([c, v]) => `${c} = ${sqlLiteral(v)}`)\n .join(\", \")}, updated_at = now() WHERE name = ${sqlLiteral(s.name)}`,\n );\n }\n }\n for (const table of plan.tables) {\n const columns = planColumns(table);\n const sets = conflictUpdateColumns(table).map((c) => `${c} = EXCLUDED.${c}`);\n statements.push(\n `INSERT INTO ${table.table} (${columns.join(\", \")}) VALUES\\n${table.rows\n .map((row) => `(${columns.map((c) => sqlLiteral(row[c])).join(\", \")})`)\n .join(\",\\n\")}\\nON CONFLICT (${table.conflict.join(\", \")}) DO UPDATE SET ${[...sets, \"updated_at = now()\"].join(\", \")}`,\n );\n }\n return statements;\n}\n\n/** The plan as one SQL script (governance columns insert-only). */\nexport function renderSurfaceSyncSql(plan: SurfaceSyncPlan): string {\n return renderSurfaceSyncStatements(plan)\n .map((statement) => `${statement};`)\n .join(\"\\n\\n\");\n}\n","/**\n * The declaration half of the route check (CONTRACT §2.6 `/checks`): does each\n * declared `urlPattern` address a live route? The host supplies its route list\n * (it owns the filesystem); the matching rule lives here, once. Ported from\n * matrx-frontend `scripts/check-surface-routes.ts` (ALC-14).\n */\n\n/** Route or pattern → segments; `[x]` / `:x` → \"*\", `[...x]` / `[[...x]]` → \"**\". */\nexport function routeSegments(path: string): string[] {\n return (path.split(\"?\")[0] ?? \"\")\n .split(\"#\")[0]!\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (/^\\[\\[?\\.\\.\\..+\\]\\]?$/.test(segment)) return \"**\";\n if (segment.startsWith(\"[\") || segment.startsWith(\":\")) return \"*\";\n return segment;\n });\n}\n\n/**\n * Does a declared `urlPattern` address a live route? A literal pattern segment\n * must be a literal route segment — a dynamic route segment does NOT satisfy it,\n * or `/marketing/[brandId]/…` would \"cover\" a retired `/marketing/brands/…`.\n * A trailing `*` makes the pattern a prefix.\n */\nexport function urlPatternMatchesRoute(pattern: string, route: readonly string[]): boolean {\n const isPrefix = pattern.trimEnd().endsWith(\"*\") && !pattern.endsWith(\"]*\");\n const segments = routeSegments(pattern.replace(/\\*+\\s*$/, \"\"));\n for (let i = 0; i < segments.length; i += 1) {\n const routeSegment = route[i];\n if (routeSegment === \"**\") return true;\n if (routeSegment === undefined) return false;\n const declared = segments[i];\n if (declared === \"**\") return true;\n if (declared === \"*\" ? routeSegment !== \"*\" : routeSegment !== declared) return false;\n }\n return isPrefix || route.length === segments.length;\n}\n\n/** Every declaration whose `urlPattern` no live route can produce. */\nexport function findDeadUrlPatterns(\n declarations: readonly { surfaceName: string; urlPattern?: string | undefined }[],\n liveRoutes: readonly string[],\n): { surfaceName: string; urlPattern: string }[] {\n const routes = liveRoutes.map(routeSegments);\n const dead: { surfaceName: string; urlPattern: string }[] = [];\n for (const declaration of declarations) {\n const pattern = declaration.urlPattern;\n if (!pattern) continue;\n if (!routes.some((route) => urlPatternMatchesRoute(pattern, route))) {\n dead.push({ surfaceName: declaration.surfaceName, urlPattern: pattern });\n }\n }\n return dead;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/checks.ts","../src/declare/keys.ts","../src/declare/sensitivity.ts","../src/checks/sync.ts","../src/checks/routes.ts"],"sourcesContent":["/**\n * `@ai-matrx/alchemy/checks` — the ONE surface sync (CONTRACT §2.7): the row plan\n * every sync path executes, and its SQL rendering. Pure; no database client.\n */\nexport {\n GOVERNANCE_COLUMNS,\n conflictUpdateColumns,\n findStaleRows,\n mirrorRowKey,\n planColumns,\n planSurfaceSync,\n renderSurfaceSyncSql,\n renderSurfaceSyncStatements,\n sqlLiteral,\n type SurfaceRowPlan,\n type SurfaceSyncPlan,\n type SurfaceSyncPlanOptions,\n type SyncSchema,\n type SyncTablePlan,\n} from \"./checks/sync\";\nexport { findDeadUrlPatterns, routeSegments, urlPatternMatchesRoute } from \"./checks/routes\";\n","import type { QualifiedValueKey } from \"./types\";\n\n/** Every value, write-target, item-type and group name (the DB CHECK rule). */\nexport const DECLARATION_NAME_RE = /^[a-z][a-z0-9_]*$/;\n\n/** \"<client>/<local>\" — the surface naming convention. */\nexport const SURFACE_NAME_RE = /^[a-z][a-z0-9-]*\\/[a-z0-9-/]+$/;\n\n/** A bare screen value (`status`) or an item value (`table_row.status`). */\nexport const QUALIFIED_VALUE_KEY_RE = /^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)?$/;\n\nexport interface ParsedValueKey {\n /** \"\" for a screen-level value. */\n itemType: string;\n name: string;\n}\n\n/** Split a qualified key; null when it is not a valid bare or qualified key. */\nexport function parseQualifiedValueKey(key: string): ParsedValueKey | null {\n if (!QUALIFIED_VALUE_KEY_RE.test(key)) return null;\n const dot = key.indexOf(\".\");\n if (dot === -1) return { itemType: \"\", name: key };\n return { itemType: key.slice(0, dot), name: key.slice(dot + 1) };\n}\n\nexport function qualifyValueKey(itemType: string, name: string): QualifiedValueKey {\n return itemType ? `${itemType}.${name}` : name;\n}\n\n/** The client that owns a surface: its name prefix. */\nexport function surfaceClientOf(surfaceName: string): string {\n return surfaceName.split(\"/\")[0] ?? \"\";\n}\n","/**\n * Sensitivity defaults and resolution (CONTRACT §2.1). Its own module so the\n * lightweight entries (`/actions`, the T0 React host) can project without\n * pulling the declaration registry.\n */\nimport type { DeclaredValue, Sensitivity } from \"./types\";\n\nexport const DEFAULT_SENSITIVITY: Sensitivity = Object.freeze({\n exportable: true,\n classification: \"ordinary\",\n includedByDefault: true,\n});\n\nexport function resolveSensitivity(value: Pick<DeclaredValue, \"sensitivity\">): Sensitivity {\n return {\n exportable: value.sensitivity?.exportable ?? DEFAULT_SENSITIVITY.exportable,\n classification: value.sensitivity?.classification ?? DEFAULT_SENSITIVITY.classification,\n includedByDefault: value.sensitivity?.includedByDefault ?? DEFAULT_SENSITIVITY.includedByDefault,\n };\n}\n","/**\n * THE ONE SYNC (CONTRACT §2.7 \"One sync path\", chair ruling B1).\n *\n * `planSurfaceSync` maps resolved declarations onto the `ui` mirror rows; every\n * sync path (the SQL emitter and the admin sync service) executes this plan and\n * builds no rows of its own. Governance columns (`organization_id`,\n * `published_to_web`) are INSERT-ONLY (chair ruling N5): a conflict never rewrites them.\n * Mirror rows are published to the web on insert, written explicitly (access ladder\n * T-13: never left to a column default); the database stamps when and by whom.\n *\n * Schema generations: the columns added by the ALC-14 migration (item_type,\n * sensitivity, live slots, content_hash) are emitted only when the caller says\n * that migration is live (`schema`), so no emitter ever writes a column — or\n * upserts against a key — the database does not have yet.\n */\nimport { resolveSensitivity, type Resolved } from \"../declare/registry\";\nimport { surfaceClientOf } from \"../declare/keys\";\nimport type { DeclarationExtension, Json, SurfaceDeclaration } from \"../declare/types\";\n\nexport const GOVERNANCE_COLUMNS = [\"organization_id\", \"published_to_web\"] as const;\n\nexport interface SyncSchema {\n /** `ui_surface_value/write_target.item_type` exists and the conflict key includes it (re-key step 1). */\n itemType?: boolean;\n /** Sensitivity, kind, live slot and role columns exist on `ui_surface_value`. */\n valueContract?: boolean;\n /** `ui_surface.content_hash` exists. */\n contentHash?: boolean;\n}\n\nexport interface SurfaceSyncPlanOptions<D extends SurfaceDeclaration> {\n organizationId: string;\n syncedFrom: string;\n syncedBy?: string | null;\n /** The address the host derives for a declaration without `urlPattern`. */\n resolveUrlPattern?: (declaration: Resolved<D>) => string | undefined;\n extensions?: readonly DeclarationExtension<D>[];\n schema?: SyncSchema;\n}\n\nexport interface SurfaceRowPlan {\n name: string;\n /** Written only when the row does not exist yet. */\n insert: Record<string, Json>;\n /** Written on every sync (code owns these columns). */\n update: Record<string, Json>;\n}\n\nexport interface SyncTablePlan {\n table: string;\n /** The ON CONFLICT target (a unique index or primary key on exactly these columns). */\n conflict: readonly string[];\n /** Columns set on insert and never on conflict. */\n insertOnly: readonly string[];\n rows: Record<string, Json>[];\n}\n\nexport interface SurfaceSyncPlan {\n surfaces: SurfaceRowPlan[];\n tables: SyncTablePlan[];\n /**\n * The key (ON CONFLICT target) of every mirror table this plan owns,\n * including tables it emits no rows for. Stale detection and deletes use\n * exactly these columns (`findStaleRows`).\n */\n keys: Record<string, readonly string[]>;\n}\n\nfunction childKey(schema: SyncSchema | undefined): readonly string[] {\n return schema?.itemType ? [\"surface_name\", \"item_type\", \"name\"] : [\"surface_name\", \"name\"];\n}\n\nexport function planSurfaceSync<D extends SurfaceDeclaration>(\n declarations: readonly Resolved<D>[],\n options: SurfaceSyncPlanOptions<D>,\n): SurfaceSyncPlan {\n const { organizationId, syncedFrom, schema } = options;\n const syncedBy = options.syncedBy ?? null;\n const provenance = { synced_by: syncedBy, synced_from: syncedFrom };\n const governance = { organization_id: organizationId, published_to_web: true };\n const surfaces: SurfaceRowPlan[] = [];\n const values: Record<string, Json>[] = [];\n const targets: Record<string, Json>[] = [];\n const itemTypes: Record<string, Json>[] = [];\n const extensionTables = new Map<string, SyncTablePlan>();\n\n for (const d of declarations) {\n const urlPattern = d.urlPattern?.trim() || options.resolveUrlPattern?.(d) || null;\n const intro = d.intro?.trim() || null;\n const parent = d.inheritsFrom ?? null;\n const client = surfaceClientOf(d.surfaceName);\n const owned: Record<string, Json> = {\n client_name: client,\n execution_mode: d.executionMode,\n description: d.description,\n label: d.label,\n value_groups: (d.groups ?? []) as unknown as Json,\n readiness: d.readiness,\n readiness_note: d.readinessNote?.trim() || null,\n ...(schema?.contentHash ? { content_hash: d.contentHash } : {}),\n };\n // A declaration that does not claim these never clears a DB-authored value.\n const claimed: Record<string, Json> = {\n ...(d.overlayId ? { overlay_id: d.overlayId } : {}),\n ...(urlPattern ? { url_pattern: urlPattern } : {}),\n ...(intro ? { intro } : {}),\n ...(parent ? { parent_surface_name: parent } : {}),\n };\n surfaces.push({\n name: d.surfaceName,\n insert: {\n name: d.surfaceName,\n ...owned,\n overlay_id: d.overlayId ?? null,\n url_pattern: urlPattern,\n intro,\n parent_surface_name: parent,\n },\n update: { ...owned, ...claimed },\n });\n\n for (const v of d.values) {\n values.push({\n ...governance,\n surface_name: d.surfaceName,\n ...(schema?.itemType ? { item_type: \"\" } : {}),\n name: v.name,\n label: v.label,\n description: v.description,\n value_type: v.valueType,\n always_available: v.alwaysAvailable,\n typical_char_count: v.typicalCharCount,\n sort_order: v.sortOrder ?? 1000,\n auto_context: v.autoContext ?? true,\n group_key: v.groupKey ?? v.group ?? \"general\",\n ...(schema?.valueContract\n ? {\n exportable: resolveSensitivity(v).exportable,\n classification: resolveSensitivity(v).classification,\n included_by_default: resolveSensitivity(v).includedByDefault,\n kind_key: v.valueKind ?? null,\n live_slot: v.liveSlot ?? null,\n role: v.role ?? \"data\",\n }\n : {}),\n ...provenance,\n });\n }\n\n for (const t of d.writeTargets ?? []) {\n targets.push({\n ...governance,\n surface_name: d.surfaceName,\n ...(schema?.itemType ? { item_type: t.itemType ?? \"\" } : {}),\n name: t.name,\n label: t.label,\n description: t.description,\n value_type: t.valueType,\n mode: t.mode,\n updates_value: t.updatesValue ?? null,\n group_key: t.group ?? \"general\",\n sort_order: t.sortOrder ?? 1000,\n apply_policy: t.applyPolicy ?? \"manual\",\n kind_key: t.valueKind ?? null,\n ...(schema?.valueContract\n ? {\n patchable: t.patchable ?? false,\n approval_comparison: t.approvalComparison ?? null,\n stream_ops: t.streamOps ? [...t.streamOps] : null,\n destination: t.destination ?? false,\n }\n : {}),\n ...provenance,\n });\n }\n\n if (schema?.itemType) {\n for (const [position, item] of (d.itemTypes ?? []).entries()) {\n itemTypes.push({\n ...governance,\n surface_name: d.surfaceName,\n name: item.name,\n label: item.label,\n description: item.description,\n identity: [...item.identity],\n levels: item.levels ? [...item.levels] : null,\n entity_type: item.entityType ?? null,\n sort_order: position,\n ...provenance,\n });\n for (const v of item.values) {\n values.push({\n ...governance,\n surface_name: d.surfaceName,\n item_type: item.name,\n name: v.name,\n label: v.label,\n description: v.description,\n value_type: v.valueType,\n always_available: v.alwaysAvailable,\n typical_char_count: v.typicalCharCount,\n sort_order: v.sortOrder ?? 1000,\n auto_context: v.autoContext ?? true,\n group_key: v.group ?? \"general\",\n ...provenance,\n });\n }\n }\n }\n\n for (const extension of options.extensions ?? []) {\n for (const entry of extension.toRows?.(d as unknown as D) ?? []) {\n const plan = extensionTables.get(entry.table) ?? {\n table: entry.table,\n conflict: entry.conflict,\n insertOnly: GOVERNANCE_COLUMNS,\n rows: [],\n };\n plan.rows.push({ ...governance, ...entry.row, ...provenance });\n extensionTables.set(entry.table, plan);\n }\n }\n }\n\n const keys: Record<string, readonly string[]> = {\n \"ui.ui_surface_value\": childKey(schema),\n \"ui.ui_surface_write_target\": childKey(schema),\n ...(schema?.itemType ? { \"ui.ui_surface_item_type\": [\"surface_name\", \"name\"] } : {}),\n };\n for (const extension of options.extensions ?? []) {\n if (extension.mirror) keys[extension.mirror.table] = extension.mirror.conflict;\n }\n for (const plan of extensionTables.values()) keys[plan.table] ??= plan.conflict;\n\n const tables: SyncTablePlan[] = [\n { table: \"ui.ui_surface_value\", conflict: childKey(schema), insertOnly: GOVERNANCE_COLUMNS, rows: values },\n { table: \"ui.ui_surface_write_target\", conflict: childKey(schema), insertOnly: GOVERNANCE_COLUMNS, rows: targets },\n ...(schema?.itemType\n ? [{ table: \"ui.ui_surface_item_type\", conflict: [\"surface_name\", \"name\"], insertOnly: GOVERNANCE_COLUMNS, rows: itemTypes }]\n : []),\n ...extensionTables.values(),\n ];\n return { surfaces, tables: tables.filter((table) => table.rows.length > 0), keys };\n}\n\n/** One row's key under `columns` (a missing column reads as ''). */\nexport function mirrorRowKey(row: Readonly<Record<string, unknown>>, columns: readonly string[]): string {\n return columns.map((column) => String(row[column] ?? \"\")).join(\"\\u0000\");\n}\n\n/**\n * Rows of `table` that belong to a surface this plan manages but that the\n * plan no longer declares, judged by the table's full key (`plan.keys`) — so\n * a screen value and an item value that share a name are distinct rows. The\n * caller deletes each returned row filtered by every column of that key.\n */\nexport function findStaleRows<R extends Readonly<Record<string, unknown>>>(\n plan: SurfaceSyncPlan,\n table: string,\n existing: readonly R[],\n): R[] {\n const key = plan.keys[table];\n if (!key) {\n throw new Error(\n `Sync plan declares no key for \"${table}\"; give the extension that owns it a \\`mirror\\` entry.`,\n );\n }\n const managed = new Set(plan.surfaces.map((surface) => surface.name));\n const declared = new Set(\n (plan.tables.find((entry) => entry.table === table)?.rows ?? []).map((row) => mirrorRowKey(row, key)),\n );\n return existing.filter(\n (row) => managed.has(String(row.surface_name)) && !declared.has(mirrorRowKey(row, key)),\n );\n}\n\n/** Every column a table's rows carry, in first-seen order. */\nexport function planColumns(table: SyncTablePlan): string[] {\n const columns: string[] = [];\n for (const row of table.rows) for (const key of Object.keys(row)) if (!columns.includes(key)) columns.push(key);\n return columns;\n}\n\n/** Columns a conflict rewrites: everything except the key and the insert-only set. */\nexport function conflictUpdateColumns(table: SyncTablePlan): string[] {\n return planColumns(table).filter((c) => !table.conflict.includes(c) && !table.insertOnly.includes(c));\n}\n\nexport function sqlLiteral(value: Json | undefined): string {\n if (value === null || value === undefined) return \"NULL\";\n if (typeof value === \"boolean\" || typeof value === \"number\") return String(value);\n if (typeof value === \"string\") return `'${value.replace(/'/g, \"''\")}'`;\n if (Array.isArray(value) && value.every((entry) => typeof entry === \"string\")) {\n return `ARRAY[${value.map((entry) => sqlLiteral(entry)).join(\", \")}]::text[]`;\n }\n return `'${JSON.stringify(value).replace(/'/g, \"''\")}'::jsonb`;\n}\n\n/**\n * The plan as SQL statements, one per entry: surface insert, one UPDATE per\n * surface, one upsert per table. Callers may run them, or EXPLAIN each one in a\n * read-only transaction to prove the plan against a live schema with no write.\n */\nexport function renderSurfaceSyncStatements(plan: SurfaceSyncPlan): string[] {\n const statements: string[] = [];\n if (plan.surfaces.length > 0) {\n const insertColumns = Object.keys(plan.surfaces[0]!.insert);\n statements.push(\n `INSERT INTO ui.ui_surface (${insertColumns.join(\", \")}) VALUES\\n${plan.surfaces\n .map((s) => `(${insertColumns.map((c) => sqlLiteral(s.insert[c])).join(\", \")})`)\n .join(\",\\n\")}\\nON CONFLICT (name) DO NOTHING`,\n );\n for (const s of plan.surfaces) {\n statements.push(\n `UPDATE ui.ui_surface SET ${Object.entries(s.update)\n .map(([c, v]) => `${c} = ${sqlLiteral(v)}`)\n .join(\", \")}, updated_at = now() WHERE name = ${sqlLiteral(s.name)}`,\n );\n }\n }\n for (const table of plan.tables) {\n const columns = planColumns(table);\n const sets = conflictUpdateColumns(table).map((c) => `${c} = EXCLUDED.${c}`);\n statements.push(\n `INSERT INTO ${table.table} (${columns.join(\", \")}) VALUES\\n${table.rows\n .map((row) => `(${columns.map((c) => sqlLiteral(row[c])).join(\", \")})`)\n .join(\",\\n\")}\\nON CONFLICT (${table.conflict.join(\", \")}) DO UPDATE SET ${[...sets, \"updated_at = now()\"].join(\", \")}`,\n );\n }\n return statements;\n}\n\n/** The plan as one SQL script (governance columns insert-only). */\nexport function renderSurfaceSyncSql(plan: SurfaceSyncPlan): string {\n return renderSurfaceSyncStatements(plan)\n .map((statement) => `${statement};`)\n .join(\"\\n\\n\");\n}\n","/**\n * The declaration half of the route check (CONTRACT §2.6 `/checks`): does each\n * declared `urlPattern` address a live route? The host supplies its route list\n * (it owns the filesystem); the matching rule lives here, once. Ported from\n * matrx-frontend `scripts/check-surface-routes.ts` (ALC-14).\n */\n\n/** Route or pattern → segments; `[x]` / `:x` → \"*\", `[...x]` / `[[...x]]` → \"**\". */\nexport function routeSegments(path: string): string[] {\n return (path.split(\"?\")[0] ?? \"\")\n .split(\"#\")[0]!\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (/^\\[\\[?\\.\\.\\..+\\]\\]?$/.test(segment)) return \"**\";\n if (segment.startsWith(\"[\") || segment.startsWith(\":\")) return \"*\";\n return segment;\n });\n}\n\n/**\n * Does a declared `urlPattern` address a live route? A literal pattern segment\n * must be a literal route segment — a dynamic route segment does NOT satisfy it,\n * or `/marketing/[brandId]/…` would \"cover\" a retired `/marketing/brands/…`.\n * A trailing `*` makes the pattern a prefix.\n */\nexport function urlPatternMatchesRoute(pattern: string, route: readonly string[]): boolean {\n const isPrefix = pattern.trimEnd().endsWith(\"*\") && !pattern.endsWith(\"]*\");\n const segments = routeSegments(pattern.replace(/\\*+\\s*$/, \"\"));\n for (let i = 0; i < segments.length; i += 1) {\n const routeSegment = route[i];\n if (routeSegment === \"**\") return true;\n if (routeSegment === undefined) return false;\n const declared = segments[i];\n if (declared === \"**\") return true;\n if (declared === \"*\" ? routeSegment !== \"*\" : routeSegment !== declared) return false;\n }\n return isPrefix || route.length === segments.length;\n}\n\n/** Every declaration whose `urlPattern` no live route can produce. */\nexport function findDeadUrlPatterns(\n declarations: readonly { surfaceName: string; urlPattern?: string | undefined }[],\n liveRoutes: readonly string[],\n): { surfaceName: string; urlPattern: string }[] {\n const routes = liveRoutes.map(routeSegments);\n const dead: { surfaceName: string; urlPattern: string }[] = [];\n for (const declaration of declarations) {\n const pattern = declaration.urlPattern;\n if (!pattern) continue;\n if (!routes.some((route) => urlPatternMatchesRoute(pattern, route))) {\n dead.push({ surfaceName: declaration.surfaceName, urlPattern: pattern });\n }\n }\n return dead;\n}\n"],"mappings":"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","names":[]}
package/dist/checks.d.cts CHANGED
@@ -204,7 +204,9 @@ type Resolved<D extends SurfaceDeclaration> = Omit<D, "values" | "groups"> & {
204
204
  * `planSurfaceSync` maps resolved declarations onto the `ui` mirror rows; every
205
205
  * sync path (the SQL emitter and the admin sync service) executes this plan and
206
206
  * builds no rows of its own. Governance columns (`organization_id`,
207
- * `visibility`) are INSERT-ONLY (chair ruling N5): a conflict never rewrites them.
207
+ * `published_to_web`) are INSERT-ONLY (chair ruling N5): a conflict never rewrites them.
208
+ * Mirror rows are published to the web on insert, written explicitly (access ladder
209
+ * T-13: never left to a column default); the database stamps when and by whom.
208
210
  *
209
211
  * Schema generations: the columns added by the ALC-14 migration (item_type,
210
212
  * sensitivity, live slots, content_hash) are emitted only when the caller says
@@ -212,7 +214,7 @@ type Resolved<D extends SurfaceDeclaration> = Omit<D, "values" | "groups"> & {
212
214
  * upserts against a key — the database does not have yet.
213
215
  */
214
216
 
215
- declare const GOVERNANCE_COLUMNS: readonly ["organization_id", "visibility"];
217
+ declare const GOVERNANCE_COLUMNS: readonly ["organization_id", "published_to_web"];
216
218
  interface SyncSchema {
217
219
  /** `ui_surface_value/write_target.item_type` exists and the conflict key includes it (re-key step 1). */
218
220
  itemType?: boolean;
package/dist/checks.d.ts CHANGED
@@ -204,7 +204,9 @@ type Resolved<D extends SurfaceDeclaration> = Omit<D, "values" | "groups"> & {
204
204
  * `planSurfaceSync` maps resolved declarations onto the `ui` mirror rows; every
205
205
  * sync path (the SQL emitter and the admin sync service) executes this plan and
206
206
  * builds no rows of its own. Governance columns (`organization_id`,
207
- * `visibility`) are INSERT-ONLY (chair ruling N5): a conflict never rewrites them.
207
+ * `published_to_web`) are INSERT-ONLY (chair ruling N5): a conflict never rewrites them.
208
+ * Mirror rows are published to the web on insert, written explicitly (access ladder
209
+ * T-13: never left to a column default); the database stamps when and by whom.
208
210
  *
209
211
  * Schema generations: the columns added by the ALC-14 migration (item_type,
210
212
  * sensitivity, live slots, content_hash) are emitted only when the caller says
@@ -212,7 +214,7 @@ type Resolved<D extends SurfaceDeclaration> = Omit<D, "values" | "groups"> & {
212
214
  * upserts against a key — the database does not have yet.
213
215
  */
214
216
 
215
- declare const GOVERNANCE_COLUMNS: readonly ["organization_id", "visibility"];
217
+ declare const GOVERNANCE_COLUMNS: readonly ["organization_id", "published_to_web"];
216
218
  interface SyncSchema {
217
219
  /** `ui_surface_value/write_target.item_type` exists and the conflict key includes it (re-key step 1). */
218
220
  itemType?: boolean;
package/dist/checks.js CHANGED
@@ -1,4 +1,4 @@
1
- function surfaceClientOf(surfaceName){return surfaceName.split("/")[0]??""}var DEFAULT_SENSITIVITY=Object.freeze({exportable:!0,classification:"ordinary",includedByDefault:!0});function resolveSensitivity(value){return{exportable:value.sensitivity?.exportable??DEFAULT_SENSITIVITY.exportable,classification:value.sensitivity?.classification??DEFAULT_SENSITIVITY.classification,includedByDefault:value.sensitivity?.includedByDefault??DEFAULT_SENSITIVITY.includedByDefault}}var GOVERNANCE_COLUMNS=["organization_id","visibility"];function childKey(schema){return schema?.itemType?["surface_name","item_type","name"]:["surface_name","name"]}function planSurfaceSync(declarations,options){let{organizationId,syncedFrom,schema}=options,provenance={synced_by:options.syncedBy??null,synced_from:syncedFrom},governance={organization_id:organizationId,visibility:"public"},surfaces=[],values=[],targets=[],itemTypes=[],extensionTables=new Map;for(let d of declarations){let urlPattern=d.urlPattern?.trim()||options.resolveUrlPattern?.(d)||null,intro=d.intro?.trim()||null,parent=d.inheritsFrom??null,owned={client_name:surfaceClientOf(d.surfaceName),execution_mode:d.executionMode,description:d.description,label:d.label,value_groups:d.groups??[],readiness:d.readiness,readiness_note:d.readinessNote?.trim()||null,...schema?.contentHash?{content_hash:d.contentHash}:{}},claimed={...d.overlayId?{overlay_id:d.overlayId}:{},...urlPattern?{url_pattern:urlPattern}:{},...intro?{intro}:{},...parent?{parent_surface_name:parent}:{}};surfaces.push({name:d.surfaceName,insert:{name:d.surfaceName,...owned,overlay_id:d.overlayId??null,url_pattern:urlPattern,intro,parent_surface_name:parent},update:{...owned,...claimed}});for(let v of d.values)values.push({...governance,surface_name:d.surfaceName,...schema?.itemType?{item_type:""}:{},name:v.name,label:v.label,description:v.description,value_type:v.valueType,always_available:v.alwaysAvailable,typical_char_count:v.typicalCharCount,sort_order:v.sortOrder??1e3,auto_context:v.autoContext??!0,group_key:v.groupKey??v.group??"general",...schema?.valueContract?{exportable:resolveSensitivity(v).exportable,classification:resolveSensitivity(v).classification,included_by_default:resolveSensitivity(v).includedByDefault,kind_key:v.valueKind??null,live_slot:v.liveSlot??null,role:v.role??"data"}:{},...provenance});for(let t of d.writeTargets??[])targets.push({...governance,surface_name:d.surfaceName,...schema?.itemType?{item_type:t.itemType??""}:{},name:t.name,label:t.label,description:t.description,value_type:t.valueType,mode:t.mode,updates_value:t.updatesValue??null,group_key:t.group??"general",sort_order:t.sortOrder??1e3,apply_policy:t.applyPolicy??"manual",kind_key:t.valueKind??null,...schema?.valueContract?{patchable:t.patchable??!1,approval_comparison:t.approvalComparison??null,stream_ops:t.streamOps?[...t.streamOps]:null,destination:t.destination??!1}:{},...provenance});if(schema?.itemType)for(let[position,item]of(d.itemTypes??[]).entries()){itemTypes.push({...governance,surface_name:d.surfaceName,name:item.name,label:item.label,description:item.description,identity:[...item.identity],levels:item.levels?[...item.levels]:null,entity_type:item.entityType??null,sort_order:position,...provenance});for(let v of item.values)values.push({...governance,surface_name:d.surfaceName,item_type:item.name,name:v.name,label:v.label,description:v.description,value_type:v.valueType,always_available:v.alwaysAvailable,typical_char_count:v.typicalCharCount,sort_order:v.sortOrder??1e3,auto_context:v.autoContext??!0,group_key:v.group??"general",...provenance})}for(let extension of options.extensions??[])for(let entry of extension.toRows?.(d)??[]){let plan=extensionTables.get(entry.table)??{table:entry.table,conflict:entry.conflict,insertOnly:GOVERNANCE_COLUMNS,rows:[]};plan.rows.push({...governance,...entry.row,...provenance}),extensionTables.set(entry.table,plan)}}let keys={"ui.ui_surface_value":childKey(schema),"ui.ui_surface_write_target":childKey(schema),...schema?.itemType?{"ui.ui_surface_item_type":["surface_name","name"]}:{}};for(let extension of options.extensions??[])extension.mirror&&(keys[extension.mirror.table]=extension.mirror.conflict);for(let plan of extensionTables.values())keys[plan.table]??=plan.conflict;let tables=[{table:"ui.ui_surface_value",conflict:childKey(schema),insertOnly:GOVERNANCE_COLUMNS,rows:values},{table:"ui.ui_surface_write_target",conflict:childKey(schema),insertOnly:GOVERNANCE_COLUMNS,rows:targets},...schema?.itemType?[{table:"ui.ui_surface_item_type",conflict:["surface_name","name"],insertOnly:GOVERNANCE_COLUMNS,rows:itemTypes}]:[],...extensionTables.values()];return{surfaces,tables:tables.filter(table=>table.rows.length>0),keys}}function mirrorRowKey(row,columns){return columns.map(column=>String(row[column]??"")).join("\0")}function findStaleRows(plan,table,existing){let key=plan.keys[table];if(!key)throw new Error(`Sync plan declares no key for "${table}"; give the extension that owns it a \`mirror\` entry.`);let managed=new Set(plan.surfaces.map(surface=>surface.name)),declared=new Set((plan.tables.find(entry=>entry.table===table)?.rows??[]).map(row=>mirrorRowKey(row,key)));return existing.filter(row=>managed.has(String(row.surface_name))&&!declared.has(mirrorRowKey(row,key)))}function planColumns(table){let columns=[];for(let row of table.rows)for(let key of Object.keys(row))columns.includes(key)||columns.push(key);return columns}function conflictUpdateColumns(table){return planColumns(table).filter(c=>!table.conflict.includes(c)&&!table.insertOnly.includes(c))}function sqlLiteral(value){return value==null?"NULL":typeof value=="boolean"||typeof value=="number"?String(value):typeof value=="string"?`'${value.replace(/'/g,"''")}'`:Array.isArray(value)&&value.every(entry=>typeof entry=="string")?`ARRAY[${value.map(entry=>sqlLiteral(entry)).join(", ")}]::text[]`:`'${JSON.stringify(value).replace(/'/g,"''")}'::jsonb`}function renderSurfaceSyncStatements(plan){let statements=[];if(plan.surfaces.length>0){let insertColumns=Object.keys(plan.surfaces[0].insert);statements.push(`INSERT INTO ui.ui_surface (${insertColumns.join(", ")}) VALUES
1
+ function surfaceClientOf(surfaceName){return surfaceName.split("/")[0]??""}var DEFAULT_SENSITIVITY=Object.freeze({exportable:!0,classification:"ordinary",includedByDefault:!0});function resolveSensitivity(value){return{exportable:value.sensitivity?.exportable??DEFAULT_SENSITIVITY.exportable,classification:value.sensitivity?.classification??DEFAULT_SENSITIVITY.classification,includedByDefault:value.sensitivity?.includedByDefault??DEFAULT_SENSITIVITY.includedByDefault}}var GOVERNANCE_COLUMNS=["organization_id","published_to_web"];function childKey(schema){return schema?.itemType?["surface_name","item_type","name"]:["surface_name","name"]}function planSurfaceSync(declarations,options){let{organizationId,syncedFrom,schema}=options,provenance={synced_by:options.syncedBy??null,synced_from:syncedFrom},governance={organization_id:organizationId,published_to_web:!0},surfaces=[],values=[],targets=[],itemTypes=[],extensionTables=new Map;for(let d of declarations){let urlPattern=d.urlPattern?.trim()||options.resolveUrlPattern?.(d)||null,intro=d.intro?.trim()||null,parent=d.inheritsFrom??null,owned={client_name:surfaceClientOf(d.surfaceName),execution_mode:d.executionMode,description:d.description,label:d.label,value_groups:d.groups??[],readiness:d.readiness,readiness_note:d.readinessNote?.trim()||null,...schema?.contentHash?{content_hash:d.contentHash}:{}},claimed={...d.overlayId?{overlay_id:d.overlayId}:{},...urlPattern?{url_pattern:urlPattern}:{},...intro?{intro}:{},...parent?{parent_surface_name:parent}:{}};surfaces.push({name:d.surfaceName,insert:{name:d.surfaceName,...owned,overlay_id:d.overlayId??null,url_pattern:urlPattern,intro,parent_surface_name:parent},update:{...owned,...claimed}});for(let v of d.values)values.push({...governance,surface_name:d.surfaceName,...schema?.itemType?{item_type:""}:{},name:v.name,label:v.label,description:v.description,value_type:v.valueType,always_available:v.alwaysAvailable,typical_char_count:v.typicalCharCount,sort_order:v.sortOrder??1e3,auto_context:v.autoContext??!0,group_key:v.groupKey??v.group??"general",...schema?.valueContract?{exportable:resolveSensitivity(v).exportable,classification:resolveSensitivity(v).classification,included_by_default:resolveSensitivity(v).includedByDefault,kind_key:v.valueKind??null,live_slot:v.liveSlot??null,role:v.role??"data"}:{},...provenance});for(let t of d.writeTargets??[])targets.push({...governance,surface_name:d.surfaceName,...schema?.itemType?{item_type:t.itemType??""}:{},name:t.name,label:t.label,description:t.description,value_type:t.valueType,mode:t.mode,updates_value:t.updatesValue??null,group_key:t.group??"general",sort_order:t.sortOrder??1e3,apply_policy:t.applyPolicy??"manual",kind_key:t.valueKind??null,...schema?.valueContract?{patchable:t.patchable??!1,approval_comparison:t.approvalComparison??null,stream_ops:t.streamOps?[...t.streamOps]:null,destination:t.destination??!1}:{},...provenance});if(schema?.itemType)for(let[position,item]of(d.itemTypes??[]).entries()){itemTypes.push({...governance,surface_name:d.surfaceName,name:item.name,label:item.label,description:item.description,identity:[...item.identity],levels:item.levels?[...item.levels]:null,entity_type:item.entityType??null,sort_order:position,...provenance});for(let v of item.values)values.push({...governance,surface_name:d.surfaceName,item_type:item.name,name:v.name,label:v.label,description:v.description,value_type:v.valueType,always_available:v.alwaysAvailable,typical_char_count:v.typicalCharCount,sort_order:v.sortOrder??1e3,auto_context:v.autoContext??!0,group_key:v.group??"general",...provenance})}for(let extension of options.extensions??[])for(let entry of extension.toRows?.(d)??[]){let plan=extensionTables.get(entry.table)??{table:entry.table,conflict:entry.conflict,insertOnly:GOVERNANCE_COLUMNS,rows:[]};plan.rows.push({...governance,...entry.row,...provenance}),extensionTables.set(entry.table,plan)}}let keys={"ui.ui_surface_value":childKey(schema),"ui.ui_surface_write_target":childKey(schema),...schema?.itemType?{"ui.ui_surface_item_type":["surface_name","name"]}:{}};for(let extension of options.extensions??[])extension.mirror&&(keys[extension.mirror.table]=extension.mirror.conflict);for(let plan of extensionTables.values())keys[plan.table]??=plan.conflict;let tables=[{table:"ui.ui_surface_value",conflict:childKey(schema),insertOnly:GOVERNANCE_COLUMNS,rows:values},{table:"ui.ui_surface_write_target",conflict:childKey(schema),insertOnly:GOVERNANCE_COLUMNS,rows:targets},...schema?.itemType?[{table:"ui.ui_surface_item_type",conflict:["surface_name","name"],insertOnly:GOVERNANCE_COLUMNS,rows:itemTypes}]:[],...extensionTables.values()];return{surfaces,tables:tables.filter(table=>table.rows.length>0),keys}}function mirrorRowKey(row,columns){return columns.map(column=>String(row[column]??"")).join("\0")}function findStaleRows(plan,table,existing){let key=plan.keys[table];if(!key)throw new Error(`Sync plan declares no key for "${table}"; give the extension that owns it a \`mirror\` entry.`);let managed=new Set(plan.surfaces.map(surface=>surface.name)),declared=new Set((plan.tables.find(entry=>entry.table===table)?.rows??[]).map(row=>mirrorRowKey(row,key)));return existing.filter(row=>managed.has(String(row.surface_name))&&!declared.has(mirrorRowKey(row,key)))}function planColumns(table){let columns=[];for(let row of table.rows)for(let key of Object.keys(row))columns.includes(key)||columns.push(key);return columns}function conflictUpdateColumns(table){return planColumns(table).filter(c=>!table.conflict.includes(c)&&!table.insertOnly.includes(c))}function sqlLiteral(value){return value==null?"NULL":typeof value=="boolean"||typeof value=="number"?String(value):typeof value=="string"?`'${value.replace(/'/g,"''")}'`:Array.isArray(value)&&value.every(entry=>typeof entry=="string")?`ARRAY[${value.map(entry=>sqlLiteral(entry)).join(", ")}]::text[]`:`'${JSON.stringify(value).replace(/'/g,"''")}'::jsonb`}function renderSurfaceSyncStatements(plan){let statements=[];if(plan.surfaces.length>0){let insertColumns=Object.keys(plan.surfaces[0].insert);statements.push(`INSERT INTO ui.ui_surface (${insertColumns.join(", ")}) VALUES
2
2
  ${plan.surfaces.map(s=>`(${insertColumns.map(c=>sqlLiteral(s.insert[c])).join(", ")})`).join(`,
3
3
  `)}
4
4
  ON CONFLICT (name) DO NOTHING`);for(let s of plan.surfaces)statements.push(`UPDATE ui.ui_surface SET ${Object.entries(s.update).map(([c,v])=>`${c} = ${sqlLiteral(v)}`).join(", ")}, updated_at = now() WHERE name = ${sqlLiteral(s.name)}`)}for(let table of plan.tables){let columns=planColumns(table),sets=conflictUpdateColumns(table).map(c=>`${c} = EXCLUDED.${c}`);statements.push(`INSERT INTO ${table.table} (${columns.join(", ")}) VALUES
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/declare/keys.ts","../src/declare/sensitivity.ts","../src/checks/sync.ts","../src/checks/routes.ts"],"sourcesContent":["import type { QualifiedValueKey } from \"./types\";\n\n/** Every value, write-target, item-type and group name (the DB CHECK rule). */\nexport const DECLARATION_NAME_RE = /^[a-z][a-z0-9_]*$/;\n\n/** \"<client>/<local>\" — the surface naming convention. */\nexport const SURFACE_NAME_RE = /^[a-z][a-z0-9-]*\\/[a-z0-9-/]+$/;\n\n/** A bare screen value (`status`) or an item value (`table_row.status`). */\nexport const QUALIFIED_VALUE_KEY_RE = /^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)?$/;\n\nexport interface ParsedValueKey {\n /** \"\" for a screen-level value. */\n itemType: string;\n name: string;\n}\n\n/** Split a qualified key; null when it is not a valid bare or qualified key. */\nexport function parseQualifiedValueKey(key: string): ParsedValueKey | null {\n if (!QUALIFIED_VALUE_KEY_RE.test(key)) return null;\n const dot = key.indexOf(\".\");\n if (dot === -1) return { itemType: \"\", name: key };\n return { itemType: key.slice(0, dot), name: key.slice(dot + 1) };\n}\n\nexport function qualifyValueKey(itemType: string, name: string): QualifiedValueKey {\n return itemType ? `${itemType}.${name}` : name;\n}\n\n/** The client that owns a surface: its name prefix. */\nexport function surfaceClientOf(surfaceName: string): string {\n return surfaceName.split(\"/\")[0] ?? \"\";\n}\n","/**\n * Sensitivity defaults and resolution (CONTRACT §2.1). Its own module so the\n * lightweight entries (`/actions`, the T0 React host) can project without\n * pulling the declaration registry.\n */\nimport type { DeclaredValue, Sensitivity } from \"./types\";\n\nexport const DEFAULT_SENSITIVITY: Sensitivity = Object.freeze({\n exportable: true,\n classification: \"ordinary\",\n includedByDefault: true,\n});\n\nexport function resolveSensitivity(value: Pick<DeclaredValue, \"sensitivity\">): Sensitivity {\n return {\n exportable: value.sensitivity?.exportable ?? DEFAULT_SENSITIVITY.exportable,\n classification: value.sensitivity?.classification ?? DEFAULT_SENSITIVITY.classification,\n includedByDefault: value.sensitivity?.includedByDefault ?? DEFAULT_SENSITIVITY.includedByDefault,\n };\n}\n","/**\n * THE ONE SYNC (CONTRACT §2.7 \"One sync path\", chair ruling B1).\n *\n * `planSurfaceSync` maps resolved declarations onto the `ui` mirror rows; every\n * sync path (the SQL emitter and the admin sync service) executes this plan and\n * builds no rows of its own. Governance columns (`organization_id`,\n * `visibility`) are INSERT-ONLY (chair ruling N5): a conflict never rewrites them.\n *\n * Schema generations: the columns added by the ALC-14 migration (item_type,\n * sensitivity, live slots, content_hash) are emitted only when the caller says\n * that migration is live (`schema`), so no emitter ever writes a column — or\n * upserts against a key — the database does not have yet.\n */\nimport { resolveSensitivity, type Resolved } from \"../declare/registry\";\nimport { surfaceClientOf } from \"../declare/keys\";\nimport type { DeclarationExtension, Json, SurfaceDeclaration } from \"../declare/types\";\n\nexport const GOVERNANCE_COLUMNS = [\"organization_id\", \"visibility\"] as const;\n\nexport interface SyncSchema {\n /** `ui_surface_value/write_target.item_type` exists and the conflict key includes it (re-key step 1). */\n itemType?: boolean;\n /** Sensitivity, kind, live slot and role columns exist on `ui_surface_value`. */\n valueContract?: boolean;\n /** `ui_surface.content_hash` exists. */\n contentHash?: boolean;\n}\n\nexport interface SurfaceSyncPlanOptions<D extends SurfaceDeclaration> {\n organizationId: string;\n syncedFrom: string;\n syncedBy?: string | null;\n /** The address the host derives for a declaration without `urlPattern`. */\n resolveUrlPattern?: (declaration: Resolved<D>) => string | undefined;\n extensions?: readonly DeclarationExtension<D>[];\n schema?: SyncSchema;\n}\n\nexport interface SurfaceRowPlan {\n name: string;\n /** Written only when the row does not exist yet. */\n insert: Record<string, Json>;\n /** Written on every sync (code owns these columns). */\n update: Record<string, Json>;\n}\n\nexport interface SyncTablePlan {\n table: string;\n /** The ON CONFLICT target (a unique index or primary key on exactly these columns). */\n conflict: readonly string[];\n /** Columns set on insert and never on conflict. */\n insertOnly: readonly string[];\n rows: Record<string, Json>[];\n}\n\nexport interface SurfaceSyncPlan {\n surfaces: SurfaceRowPlan[];\n tables: SyncTablePlan[];\n /**\n * The key (ON CONFLICT target) of every mirror table this plan owns,\n * including tables it emits no rows for. Stale detection and deletes use\n * exactly these columns (`findStaleRows`).\n */\n keys: Record<string, readonly string[]>;\n}\n\nfunction childKey(schema: SyncSchema | undefined): readonly string[] {\n return schema?.itemType ? [\"surface_name\", \"item_type\", \"name\"] : [\"surface_name\", \"name\"];\n}\n\nexport function planSurfaceSync<D extends SurfaceDeclaration>(\n declarations: readonly Resolved<D>[],\n options: SurfaceSyncPlanOptions<D>,\n): SurfaceSyncPlan {\n const { organizationId, syncedFrom, schema } = options;\n const syncedBy = options.syncedBy ?? null;\n const provenance = { synced_by: syncedBy, synced_from: syncedFrom };\n const governance = { organization_id: organizationId, visibility: \"public\" };\n const surfaces: SurfaceRowPlan[] = [];\n const values: Record<string, Json>[] = [];\n const targets: Record<string, Json>[] = [];\n const itemTypes: Record<string, Json>[] = [];\n const extensionTables = new Map<string, SyncTablePlan>();\n\n for (const d of declarations) {\n const urlPattern = d.urlPattern?.trim() || options.resolveUrlPattern?.(d) || null;\n const intro = d.intro?.trim() || null;\n const parent = d.inheritsFrom ?? null;\n const client = surfaceClientOf(d.surfaceName);\n const owned: Record<string, Json> = {\n client_name: client,\n execution_mode: d.executionMode,\n description: d.description,\n label: d.label,\n value_groups: (d.groups ?? []) as unknown as Json,\n readiness: d.readiness,\n readiness_note: d.readinessNote?.trim() || null,\n ...(schema?.contentHash ? { content_hash: d.contentHash } : {}),\n };\n // A declaration that does not claim these never clears a DB-authored value.\n const claimed: Record<string, Json> = {\n ...(d.overlayId ? { overlay_id: d.overlayId } : {}),\n ...(urlPattern ? { url_pattern: urlPattern } : {}),\n ...(intro ? { intro } : {}),\n ...(parent ? { parent_surface_name: parent } : {}),\n };\n surfaces.push({\n name: d.surfaceName,\n insert: {\n name: d.surfaceName,\n ...owned,\n overlay_id: d.overlayId ?? null,\n url_pattern: urlPattern,\n intro,\n parent_surface_name: parent,\n },\n update: { ...owned, ...claimed },\n });\n\n for (const v of d.values) {\n values.push({\n ...governance,\n surface_name: d.surfaceName,\n ...(schema?.itemType ? { item_type: \"\" } : {}),\n name: v.name,\n label: v.label,\n description: v.description,\n value_type: v.valueType,\n always_available: v.alwaysAvailable,\n typical_char_count: v.typicalCharCount,\n sort_order: v.sortOrder ?? 1000,\n auto_context: v.autoContext ?? true,\n group_key: v.groupKey ?? v.group ?? \"general\",\n ...(schema?.valueContract\n ? {\n exportable: resolveSensitivity(v).exportable,\n classification: resolveSensitivity(v).classification,\n included_by_default: resolveSensitivity(v).includedByDefault,\n kind_key: v.valueKind ?? null,\n live_slot: v.liveSlot ?? null,\n role: v.role ?? \"data\",\n }\n : {}),\n ...provenance,\n });\n }\n\n for (const t of d.writeTargets ?? []) {\n targets.push({\n ...governance,\n surface_name: d.surfaceName,\n ...(schema?.itemType ? { item_type: t.itemType ?? \"\" } : {}),\n name: t.name,\n label: t.label,\n description: t.description,\n value_type: t.valueType,\n mode: t.mode,\n updates_value: t.updatesValue ?? null,\n group_key: t.group ?? \"general\",\n sort_order: t.sortOrder ?? 1000,\n apply_policy: t.applyPolicy ?? \"manual\",\n kind_key: t.valueKind ?? null,\n ...(schema?.valueContract\n ? {\n patchable: t.patchable ?? false,\n approval_comparison: t.approvalComparison ?? null,\n stream_ops: t.streamOps ? [...t.streamOps] : null,\n destination: t.destination ?? false,\n }\n : {}),\n ...provenance,\n });\n }\n\n if (schema?.itemType) {\n for (const [position, item] of (d.itemTypes ?? []).entries()) {\n itemTypes.push({\n ...governance,\n surface_name: d.surfaceName,\n name: item.name,\n label: item.label,\n description: item.description,\n identity: [...item.identity],\n levels: item.levels ? [...item.levels] : null,\n entity_type: item.entityType ?? null,\n sort_order: position,\n ...provenance,\n });\n for (const v of item.values) {\n values.push({\n ...governance,\n surface_name: d.surfaceName,\n item_type: item.name,\n name: v.name,\n label: v.label,\n description: v.description,\n value_type: v.valueType,\n always_available: v.alwaysAvailable,\n typical_char_count: v.typicalCharCount,\n sort_order: v.sortOrder ?? 1000,\n auto_context: v.autoContext ?? true,\n group_key: v.group ?? \"general\",\n ...provenance,\n });\n }\n }\n }\n\n for (const extension of options.extensions ?? []) {\n for (const entry of extension.toRows?.(d as unknown as D) ?? []) {\n const plan = extensionTables.get(entry.table) ?? {\n table: entry.table,\n conflict: entry.conflict,\n insertOnly: GOVERNANCE_COLUMNS,\n rows: [],\n };\n plan.rows.push({ ...governance, ...entry.row, ...provenance });\n extensionTables.set(entry.table, plan);\n }\n }\n }\n\n const keys: Record<string, readonly string[]> = {\n \"ui.ui_surface_value\": childKey(schema),\n \"ui.ui_surface_write_target\": childKey(schema),\n ...(schema?.itemType ? { \"ui.ui_surface_item_type\": [\"surface_name\", \"name\"] } : {}),\n };\n for (const extension of options.extensions ?? []) {\n if (extension.mirror) keys[extension.mirror.table] = extension.mirror.conflict;\n }\n for (const plan of extensionTables.values()) keys[plan.table] ??= plan.conflict;\n\n const tables: SyncTablePlan[] = [\n { table: \"ui.ui_surface_value\", conflict: childKey(schema), insertOnly: GOVERNANCE_COLUMNS, rows: values },\n { table: \"ui.ui_surface_write_target\", conflict: childKey(schema), insertOnly: GOVERNANCE_COLUMNS, rows: targets },\n ...(schema?.itemType\n ? [{ table: \"ui.ui_surface_item_type\", conflict: [\"surface_name\", \"name\"], insertOnly: GOVERNANCE_COLUMNS, rows: itemTypes }]\n : []),\n ...extensionTables.values(),\n ];\n return { surfaces, tables: tables.filter((table) => table.rows.length > 0), keys };\n}\n\n/** One row's key under `columns` (a missing column reads as ''). */\nexport function mirrorRowKey(row: Readonly<Record<string, unknown>>, columns: readonly string[]): string {\n return columns.map((column) => String(row[column] ?? \"\")).join(\"\\u0000\");\n}\n\n/**\n * Rows of `table` that belong to a surface this plan manages but that the\n * plan no longer declares, judged by the table's full key (`plan.keys`) — so\n * a screen value and an item value that share a name are distinct rows. The\n * caller deletes each returned row filtered by every column of that key.\n */\nexport function findStaleRows<R extends Readonly<Record<string, unknown>>>(\n plan: SurfaceSyncPlan,\n table: string,\n existing: readonly R[],\n): R[] {\n const key = plan.keys[table];\n if (!key) {\n throw new Error(\n `Sync plan declares no key for \"${table}\"; give the extension that owns it a \\`mirror\\` entry.`,\n );\n }\n const managed = new Set(plan.surfaces.map((surface) => surface.name));\n const declared = new Set(\n (plan.tables.find((entry) => entry.table === table)?.rows ?? []).map((row) => mirrorRowKey(row, key)),\n );\n return existing.filter(\n (row) => managed.has(String(row.surface_name)) && !declared.has(mirrorRowKey(row, key)),\n );\n}\n\n/** Every column a table's rows carry, in first-seen order. */\nexport function planColumns(table: SyncTablePlan): string[] {\n const columns: string[] = [];\n for (const row of table.rows) for (const key of Object.keys(row)) if (!columns.includes(key)) columns.push(key);\n return columns;\n}\n\n/** Columns a conflict rewrites: everything except the key and the insert-only set. */\nexport function conflictUpdateColumns(table: SyncTablePlan): string[] {\n return planColumns(table).filter((c) => !table.conflict.includes(c) && !table.insertOnly.includes(c));\n}\n\nexport function sqlLiteral(value: Json | undefined): string {\n if (value === null || value === undefined) return \"NULL\";\n if (typeof value === \"boolean\" || typeof value === \"number\") return String(value);\n if (typeof value === \"string\") return `'${value.replace(/'/g, \"''\")}'`;\n if (Array.isArray(value) && value.every((entry) => typeof entry === \"string\")) {\n return `ARRAY[${value.map((entry) => sqlLiteral(entry)).join(\", \")}]::text[]`;\n }\n return `'${JSON.stringify(value).replace(/'/g, \"''\")}'::jsonb`;\n}\n\n/**\n * The plan as SQL statements, one per entry: surface insert, one UPDATE per\n * surface, one upsert per table. Callers may run them, or EXPLAIN each one in a\n * read-only transaction to prove the plan against a live schema with no write.\n */\nexport function renderSurfaceSyncStatements(plan: SurfaceSyncPlan): string[] {\n const statements: string[] = [];\n if (plan.surfaces.length > 0) {\n const insertColumns = Object.keys(plan.surfaces[0]!.insert);\n statements.push(\n `INSERT INTO ui.ui_surface (${insertColumns.join(\", \")}) VALUES\\n${plan.surfaces\n .map((s) => `(${insertColumns.map((c) => sqlLiteral(s.insert[c])).join(\", \")})`)\n .join(\",\\n\")}\\nON CONFLICT (name) DO NOTHING`,\n );\n for (const s of plan.surfaces) {\n statements.push(\n `UPDATE ui.ui_surface SET ${Object.entries(s.update)\n .map(([c, v]) => `${c} = ${sqlLiteral(v)}`)\n .join(\", \")}, updated_at = now() WHERE name = ${sqlLiteral(s.name)}`,\n );\n }\n }\n for (const table of plan.tables) {\n const columns = planColumns(table);\n const sets = conflictUpdateColumns(table).map((c) => `${c} = EXCLUDED.${c}`);\n statements.push(\n `INSERT INTO ${table.table} (${columns.join(\", \")}) VALUES\\n${table.rows\n .map((row) => `(${columns.map((c) => sqlLiteral(row[c])).join(\", \")})`)\n .join(\",\\n\")}\\nON CONFLICT (${table.conflict.join(\", \")}) DO UPDATE SET ${[...sets, \"updated_at = now()\"].join(\", \")}`,\n );\n }\n return statements;\n}\n\n/** The plan as one SQL script (governance columns insert-only). */\nexport function renderSurfaceSyncSql(plan: SurfaceSyncPlan): string {\n return renderSurfaceSyncStatements(plan)\n .map((statement) => `${statement};`)\n .join(\"\\n\\n\");\n}\n","/**\n * The declaration half of the route check (CONTRACT §2.6 `/checks`): does each\n * declared `urlPattern` address a live route? The host supplies its route list\n * (it owns the filesystem); the matching rule lives here, once. Ported from\n * matrx-frontend `scripts/check-surface-routes.ts` (ALC-14).\n */\n\n/** Route or pattern → segments; `[x]` / `:x` → \"*\", `[...x]` / `[[...x]]` → \"**\". */\nexport function routeSegments(path: string): string[] {\n return (path.split(\"?\")[0] ?? \"\")\n .split(\"#\")[0]!\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (/^\\[\\[?\\.\\.\\..+\\]\\]?$/.test(segment)) return \"**\";\n if (segment.startsWith(\"[\") || segment.startsWith(\":\")) return \"*\";\n return segment;\n });\n}\n\n/**\n * Does a declared `urlPattern` address a live route? A literal pattern segment\n * must be a literal route segment — a dynamic route segment does NOT satisfy it,\n * or `/marketing/[brandId]/…` would \"cover\" a retired `/marketing/brands/…`.\n * A trailing `*` makes the pattern a prefix.\n */\nexport function urlPatternMatchesRoute(pattern: string, route: readonly string[]): boolean {\n const isPrefix = pattern.trimEnd().endsWith(\"*\") && !pattern.endsWith(\"]*\");\n const segments = routeSegments(pattern.replace(/\\*+\\s*$/, \"\"));\n for (let i = 0; i < segments.length; i += 1) {\n const routeSegment = route[i];\n if (routeSegment === \"**\") return true;\n if (routeSegment === undefined) return false;\n const declared = segments[i];\n if (declared === \"**\") return true;\n if (declared === \"*\" ? routeSegment !== \"*\" : routeSegment !== declared) return false;\n }\n return isPrefix || route.length === segments.length;\n}\n\n/** Every declaration whose `urlPattern` no live route can produce. */\nexport function findDeadUrlPatterns(\n declarations: readonly { surfaceName: string; urlPattern?: string | undefined }[],\n liveRoutes: readonly string[],\n): { surfaceName: string; urlPattern: string }[] {\n const routes = liveRoutes.map(routeSegments);\n const dead: { surfaceName: string; urlPattern: string }[] = [];\n for (const declaration of declarations) {\n const pattern = declaration.urlPattern;\n if (!pattern) continue;\n if (!routes.some((route) => urlPatternMatchesRoute(pattern, route))) {\n dead.push({ surfaceName: declaration.surfaceName, urlPattern: pattern });\n }\n }\n return dead;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/declare/keys.ts","../src/declare/sensitivity.ts","../src/checks/sync.ts","../src/checks/routes.ts"],"sourcesContent":["import type { QualifiedValueKey } from \"./types\";\n\n/** Every value, write-target, item-type and group name (the DB CHECK rule). */\nexport const DECLARATION_NAME_RE = /^[a-z][a-z0-9_]*$/;\n\n/** \"<client>/<local>\" — the surface naming convention. */\nexport const SURFACE_NAME_RE = /^[a-z][a-z0-9-]*\\/[a-z0-9-/]+$/;\n\n/** A bare screen value (`status`) or an item value (`table_row.status`). */\nexport const QUALIFIED_VALUE_KEY_RE = /^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)?$/;\n\nexport interface ParsedValueKey {\n /** \"\" for a screen-level value. */\n itemType: string;\n name: string;\n}\n\n/** Split a qualified key; null when it is not a valid bare or qualified key. */\nexport function parseQualifiedValueKey(key: string): ParsedValueKey | null {\n if (!QUALIFIED_VALUE_KEY_RE.test(key)) return null;\n const dot = key.indexOf(\".\");\n if (dot === -1) return { itemType: \"\", name: key };\n return { itemType: key.slice(0, dot), name: key.slice(dot + 1) };\n}\n\nexport function qualifyValueKey(itemType: string, name: string): QualifiedValueKey {\n return itemType ? `${itemType}.${name}` : name;\n}\n\n/** The client that owns a surface: its name prefix. */\nexport function surfaceClientOf(surfaceName: string): string {\n return surfaceName.split(\"/\")[0] ?? \"\";\n}\n","/**\n * Sensitivity defaults and resolution (CONTRACT §2.1). Its own module so the\n * lightweight entries (`/actions`, the T0 React host) can project without\n * pulling the declaration registry.\n */\nimport type { DeclaredValue, Sensitivity } from \"./types\";\n\nexport const DEFAULT_SENSITIVITY: Sensitivity = Object.freeze({\n exportable: true,\n classification: \"ordinary\",\n includedByDefault: true,\n});\n\nexport function resolveSensitivity(value: Pick<DeclaredValue, \"sensitivity\">): Sensitivity {\n return {\n exportable: value.sensitivity?.exportable ?? DEFAULT_SENSITIVITY.exportable,\n classification: value.sensitivity?.classification ?? DEFAULT_SENSITIVITY.classification,\n includedByDefault: value.sensitivity?.includedByDefault ?? DEFAULT_SENSITIVITY.includedByDefault,\n };\n}\n","/**\n * THE ONE SYNC (CONTRACT §2.7 \"One sync path\", chair ruling B1).\n *\n * `planSurfaceSync` maps resolved declarations onto the `ui` mirror rows; every\n * sync path (the SQL emitter and the admin sync service) executes this plan and\n * builds no rows of its own. Governance columns (`organization_id`,\n * `published_to_web`) are INSERT-ONLY (chair ruling N5): a conflict never rewrites them.\n * Mirror rows are published to the web on insert, written explicitly (access ladder\n * T-13: never left to a column default); the database stamps when and by whom.\n *\n * Schema generations: the columns added by the ALC-14 migration (item_type,\n * sensitivity, live slots, content_hash) are emitted only when the caller says\n * that migration is live (`schema`), so no emitter ever writes a column — or\n * upserts against a key — the database does not have yet.\n */\nimport { resolveSensitivity, type Resolved } from \"../declare/registry\";\nimport { surfaceClientOf } from \"../declare/keys\";\nimport type { DeclarationExtension, Json, SurfaceDeclaration } from \"../declare/types\";\n\nexport const GOVERNANCE_COLUMNS = [\"organization_id\", \"published_to_web\"] as const;\n\nexport interface SyncSchema {\n /** `ui_surface_value/write_target.item_type` exists and the conflict key includes it (re-key step 1). */\n itemType?: boolean;\n /** Sensitivity, kind, live slot and role columns exist on `ui_surface_value`. */\n valueContract?: boolean;\n /** `ui_surface.content_hash` exists. */\n contentHash?: boolean;\n}\n\nexport interface SurfaceSyncPlanOptions<D extends SurfaceDeclaration> {\n organizationId: string;\n syncedFrom: string;\n syncedBy?: string | null;\n /** The address the host derives for a declaration without `urlPattern`. */\n resolveUrlPattern?: (declaration: Resolved<D>) => string | undefined;\n extensions?: readonly DeclarationExtension<D>[];\n schema?: SyncSchema;\n}\n\nexport interface SurfaceRowPlan {\n name: string;\n /** Written only when the row does not exist yet. */\n insert: Record<string, Json>;\n /** Written on every sync (code owns these columns). */\n update: Record<string, Json>;\n}\n\nexport interface SyncTablePlan {\n table: string;\n /** The ON CONFLICT target (a unique index or primary key on exactly these columns). */\n conflict: readonly string[];\n /** Columns set on insert and never on conflict. */\n insertOnly: readonly string[];\n rows: Record<string, Json>[];\n}\n\nexport interface SurfaceSyncPlan {\n surfaces: SurfaceRowPlan[];\n tables: SyncTablePlan[];\n /**\n * The key (ON CONFLICT target) of every mirror table this plan owns,\n * including tables it emits no rows for. Stale detection and deletes use\n * exactly these columns (`findStaleRows`).\n */\n keys: Record<string, readonly string[]>;\n}\n\nfunction childKey(schema: SyncSchema | undefined): readonly string[] {\n return schema?.itemType ? [\"surface_name\", \"item_type\", \"name\"] : [\"surface_name\", \"name\"];\n}\n\nexport function planSurfaceSync<D extends SurfaceDeclaration>(\n declarations: readonly Resolved<D>[],\n options: SurfaceSyncPlanOptions<D>,\n): SurfaceSyncPlan {\n const { organizationId, syncedFrom, schema } = options;\n const syncedBy = options.syncedBy ?? null;\n const provenance = { synced_by: syncedBy, synced_from: syncedFrom };\n const governance = { organization_id: organizationId, published_to_web: true };\n const surfaces: SurfaceRowPlan[] = [];\n const values: Record<string, Json>[] = [];\n const targets: Record<string, Json>[] = [];\n const itemTypes: Record<string, Json>[] = [];\n const extensionTables = new Map<string, SyncTablePlan>();\n\n for (const d of declarations) {\n const urlPattern = d.urlPattern?.trim() || options.resolveUrlPattern?.(d) || null;\n const intro = d.intro?.trim() || null;\n const parent = d.inheritsFrom ?? null;\n const client = surfaceClientOf(d.surfaceName);\n const owned: Record<string, Json> = {\n client_name: client,\n execution_mode: d.executionMode,\n description: d.description,\n label: d.label,\n value_groups: (d.groups ?? []) as unknown as Json,\n readiness: d.readiness,\n readiness_note: d.readinessNote?.trim() || null,\n ...(schema?.contentHash ? { content_hash: d.contentHash } : {}),\n };\n // A declaration that does not claim these never clears a DB-authored value.\n const claimed: Record<string, Json> = {\n ...(d.overlayId ? { overlay_id: d.overlayId } : {}),\n ...(urlPattern ? { url_pattern: urlPattern } : {}),\n ...(intro ? { intro } : {}),\n ...(parent ? { parent_surface_name: parent } : {}),\n };\n surfaces.push({\n name: d.surfaceName,\n insert: {\n name: d.surfaceName,\n ...owned,\n overlay_id: d.overlayId ?? null,\n url_pattern: urlPattern,\n intro,\n parent_surface_name: parent,\n },\n update: { ...owned, ...claimed },\n });\n\n for (const v of d.values) {\n values.push({\n ...governance,\n surface_name: d.surfaceName,\n ...(schema?.itemType ? { item_type: \"\" } : {}),\n name: v.name,\n label: v.label,\n description: v.description,\n value_type: v.valueType,\n always_available: v.alwaysAvailable,\n typical_char_count: v.typicalCharCount,\n sort_order: v.sortOrder ?? 1000,\n auto_context: v.autoContext ?? true,\n group_key: v.groupKey ?? v.group ?? \"general\",\n ...(schema?.valueContract\n ? {\n exportable: resolveSensitivity(v).exportable,\n classification: resolveSensitivity(v).classification,\n included_by_default: resolveSensitivity(v).includedByDefault,\n kind_key: v.valueKind ?? null,\n live_slot: v.liveSlot ?? null,\n role: v.role ?? \"data\",\n }\n : {}),\n ...provenance,\n });\n }\n\n for (const t of d.writeTargets ?? []) {\n targets.push({\n ...governance,\n surface_name: d.surfaceName,\n ...(schema?.itemType ? { item_type: t.itemType ?? \"\" } : {}),\n name: t.name,\n label: t.label,\n description: t.description,\n value_type: t.valueType,\n mode: t.mode,\n updates_value: t.updatesValue ?? null,\n group_key: t.group ?? \"general\",\n sort_order: t.sortOrder ?? 1000,\n apply_policy: t.applyPolicy ?? \"manual\",\n kind_key: t.valueKind ?? null,\n ...(schema?.valueContract\n ? {\n patchable: t.patchable ?? false,\n approval_comparison: t.approvalComparison ?? null,\n stream_ops: t.streamOps ? [...t.streamOps] : null,\n destination: t.destination ?? false,\n }\n : {}),\n ...provenance,\n });\n }\n\n if (schema?.itemType) {\n for (const [position, item] of (d.itemTypes ?? []).entries()) {\n itemTypes.push({\n ...governance,\n surface_name: d.surfaceName,\n name: item.name,\n label: item.label,\n description: item.description,\n identity: [...item.identity],\n levels: item.levels ? [...item.levels] : null,\n entity_type: item.entityType ?? null,\n sort_order: position,\n ...provenance,\n });\n for (const v of item.values) {\n values.push({\n ...governance,\n surface_name: d.surfaceName,\n item_type: item.name,\n name: v.name,\n label: v.label,\n description: v.description,\n value_type: v.valueType,\n always_available: v.alwaysAvailable,\n typical_char_count: v.typicalCharCount,\n sort_order: v.sortOrder ?? 1000,\n auto_context: v.autoContext ?? true,\n group_key: v.group ?? \"general\",\n ...provenance,\n });\n }\n }\n }\n\n for (const extension of options.extensions ?? []) {\n for (const entry of extension.toRows?.(d as unknown as D) ?? []) {\n const plan = extensionTables.get(entry.table) ?? {\n table: entry.table,\n conflict: entry.conflict,\n insertOnly: GOVERNANCE_COLUMNS,\n rows: [],\n };\n plan.rows.push({ ...governance, ...entry.row, ...provenance });\n extensionTables.set(entry.table, plan);\n }\n }\n }\n\n const keys: Record<string, readonly string[]> = {\n \"ui.ui_surface_value\": childKey(schema),\n \"ui.ui_surface_write_target\": childKey(schema),\n ...(schema?.itemType ? { \"ui.ui_surface_item_type\": [\"surface_name\", \"name\"] } : {}),\n };\n for (const extension of options.extensions ?? []) {\n if (extension.mirror) keys[extension.mirror.table] = extension.mirror.conflict;\n }\n for (const plan of extensionTables.values()) keys[plan.table] ??= plan.conflict;\n\n const tables: SyncTablePlan[] = [\n { table: \"ui.ui_surface_value\", conflict: childKey(schema), insertOnly: GOVERNANCE_COLUMNS, rows: values },\n { table: \"ui.ui_surface_write_target\", conflict: childKey(schema), insertOnly: GOVERNANCE_COLUMNS, rows: targets },\n ...(schema?.itemType\n ? [{ table: \"ui.ui_surface_item_type\", conflict: [\"surface_name\", \"name\"], insertOnly: GOVERNANCE_COLUMNS, rows: itemTypes }]\n : []),\n ...extensionTables.values(),\n ];\n return { surfaces, tables: tables.filter((table) => table.rows.length > 0), keys };\n}\n\n/** One row's key under `columns` (a missing column reads as ''). */\nexport function mirrorRowKey(row: Readonly<Record<string, unknown>>, columns: readonly string[]): string {\n return columns.map((column) => String(row[column] ?? \"\")).join(\"\\u0000\");\n}\n\n/**\n * Rows of `table` that belong to a surface this plan manages but that the\n * plan no longer declares, judged by the table's full key (`plan.keys`) — so\n * a screen value and an item value that share a name are distinct rows. The\n * caller deletes each returned row filtered by every column of that key.\n */\nexport function findStaleRows<R extends Readonly<Record<string, unknown>>>(\n plan: SurfaceSyncPlan,\n table: string,\n existing: readonly R[],\n): R[] {\n const key = plan.keys[table];\n if (!key) {\n throw new Error(\n `Sync plan declares no key for \"${table}\"; give the extension that owns it a \\`mirror\\` entry.`,\n );\n }\n const managed = new Set(plan.surfaces.map((surface) => surface.name));\n const declared = new Set(\n (plan.tables.find((entry) => entry.table === table)?.rows ?? []).map((row) => mirrorRowKey(row, key)),\n );\n return existing.filter(\n (row) => managed.has(String(row.surface_name)) && !declared.has(mirrorRowKey(row, key)),\n );\n}\n\n/** Every column a table's rows carry, in first-seen order. */\nexport function planColumns(table: SyncTablePlan): string[] {\n const columns: string[] = [];\n for (const row of table.rows) for (const key of Object.keys(row)) if (!columns.includes(key)) columns.push(key);\n return columns;\n}\n\n/** Columns a conflict rewrites: everything except the key and the insert-only set. */\nexport function conflictUpdateColumns(table: SyncTablePlan): string[] {\n return planColumns(table).filter((c) => !table.conflict.includes(c) && !table.insertOnly.includes(c));\n}\n\nexport function sqlLiteral(value: Json | undefined): string {\n if (value === null || value === undefined) return \"NULL\";\n if (typeof value === \"boolean\" || typeof value === \"number\") return String(value);\n if (typeof value === \"string\") return `'${value.replace(/'/g, \"''\")}'`;\n if (Array.isArray(value) && value.every((entry) => typeof entry === \"string\")) {\n return `ARRAY[${value.map((entry) => sqlLiteral(entry)).join(\", \")}]::text[]`;\n }\n return `'${JSON.stringify(value).replace(/'/g, \"''\")}'::jsonb`;\n}\n\n/**\n * The plan as SQL statements, one per entry: surface insert, one UPDATE per\n * surface, one upsert per table. Callers may run them, or EXPLAIN each one in a\n * read-only transaction to prove the plan against a live schema with no write.\n */\nexport function renderSurfaceSyncStatements(plan: SurfaceSyncPlan): string[] {\n const statements: string[] = [];\n if (plan.surfaces.length > 0) {\n const insertColumns = Object.keys(plan.surfaces[0]!.insert);\n statements.push(\n `INSERT INTO ui.ui_surface (${insertColumns.join(\", \")}) VALUES\\n${plan.surfaces\n .map((s) => `(${insertColumns.map((c) => sqlLiteral(s.insert[c])).join(\", \")})`)\n .join(\",\\n\")}\\nON CONFLICT (name) DO NOTHING`,\n );\n for (const s of plan.surfaces) {\n statements.push(\n `UPDATE ui.ui_surface SET ${Object.entries(s.update)\n .map(([c, v]) => `${c} = ${sqlLiteral(v)}`)\n .join(\", \")}, updated_at = now() WHERE name = ${sqlLiteral(s.name)}`,\n );\n }\n }\n for (const table of plan.tables) {\n const columns = planColumns(table);\n const sets = conflictUpdateColumns(table).map((c) => `${c} = EXCLUDED.${c}`);\n statements.push(\n `INSERT INTO ${table.table} (${columns.join(\", \")}) VALUES\\n${table.rows\n .map((row) => `(${columns.map((c) => sqlLiteral(row[c])).join(\", \")})`)\n .join(\",\\n\")}\\nON CONFLICT (${table.conflict.join(\", \")}) DO UPDATE SET ${[...sets, \"updated_at = now()\"].join(\", \")}`,\n );\n }\n return statements;\n}\n\n/** The plan as one SQL script (governance columns insert-only). */\nexport function renderSurfaceSyncSql(plan: SurfaceSyncPlan): string {\n return renderSurfaceSyncStatements(plan)\n .map((statement) => `${statement};`)\n .join(\"\\n\\n\");\n}\n","/**\n * The declaration half of the route check (CONTRACT §2.6 `/checks`): does each\n * declared `urlPattern` address a live route? The host supplies its route list\n * (it owns the filesystem); the matching rule lives here, once. Ported from\n * matrx-frontend `scripts/check-surface-routes.ts` (ALC-14).\n */\n\n/** Route or pattern → segments; `[x]` / `:x` → \"*\", `[...x]` / `[[...x]]` → \"**\". */\nexport function routeSegments(path: string): string[] {\n return (path.split(\"?\")[0] ?? \"\")\n .split(\"#\")[0]!\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (/^\\[\\[?\\.\\.\\..+\\]\\]?$/.test(segment)) return \"**\";\n if (segment.startsWith(\"[\") || segment.startsWith(\":\")) return \"*\";\n return segment;\n });\n}\n\n/**\n * Does a declared `urlPattern` address a live route? A literal pattern segment\n * must be a literal route segment — a dynamic route segment does NOT satisfy it,\n * or `/marketing/[brandId]/…` would \"cover\" a retired `/marketing/brands/…`.\n * A trailing `*` makes the pattern a prefix.\n */\nexport function urlPatternMatchesRoute(pattern: string, route: readonly string[]): boolean {\n const isPrefix = pattern.trimEnd().endsWith(\"*\") && !pattern.endsWith(\"]*\");\n const segments = routeSegments(pattern.replace(/\\*+\\s*$/, \"\"));\n for (let i = 0; i < segments.length; i += 1) {\n const routeSegment = route[i];\n if (routeSegment === \"**\") return true;\n if (routeSegment === undefined) return false;\n const declared = segments[i];\n if (declared === \"**\") return true;\n if (declared === \"*\" ? routeSegment !== \"*\" : routeSegment !== declared) return false;\n }\n return isPrefix || route.length === segments.length;\n}\n\n/** Every declaration whose `urlPattern` no live route can produce. */\nexport function findDeadUrlPatterns(\n declarations: readonly { surfaceName: string; urlPattern?: string | undefined }[],\n liveRoutes: readonly string[],\n): { surfaceName: string; urlPattern: string }[] {\n const routes = liveRoutes.map(routeSegments);\n const dead: { surfaceName: string; urlPattern: string }[] = [];\n for (const declaration of declarations) {\n const pattern = declaration.urlPattern;\n if (!pattern) continue;\n if (!routes.some((route) => urlPatternMatchesRoute(pattern, route))) {\n dead.push({ surfaceName: declaration.surfaceName, urlPattern: pattern });\n }\n }\n return dead;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/alchemy",
3
- "version": "0.8.32",
3
+ "version": "0.8.33",
4
4
  "description": "Matrx Alchemy: the complete Matrx copy, prepare-for-AI, and export experience, with framework-neutral core, React menu, glyph and styles; Declare (what a screen holds: types, registry, validation, JSON schema) and the one surface sync; Actions (the one action registry: eligibility, duplicate refusal, projected reads) and the one menu engine (model + bar, overflow, context, selection, sheet and palette layouts as per-layout React subpaths).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -298,8 +298,8 @@
298
298
  ],
299
299
  "dependencies": {
300
300
  "@ai-matrx/kit": "latest",
301
- "@ai-matrx/design-system": "latest",
302
- "@ai-matrx/print": "latest"
301
+ "@ai-matrx/print": "latest",
302
+ "@ai-matrx/design-system": "latest"
303
303
  },
304
304
  "scripts": {
305
305
  "build": "pnpm clean && tsup && node ./scripts/copy-assets.mjs && node ./scripts/assert-distribution-artifacts.mjs && node ./scripts/check-subpath-sizes.mjs",