@runa-ai/runa-cli 0.10.2 → 0.10.4

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.
Files changed (32) hide show
  1. package/dist/{build-P2A6345N.js → build-C65G2QQE.js} +3 -2
  2. package/dist/{chunk-UHDAYPHH.js → chunk-47BG6DRP.js} +1 -1
  3. package/dist/chunk-AYYHYZU7.js +3636 -0
  4. package/dist/{chunk-MAFJAA2P.js → chunk-C3SRIUWX.js} +1 -1
  5. package/dist/{chunk-QSEF4T3Y.js → chunk-F2AQ3EYJ.js} +10 -199
  6. package/dist/chunk-NOXYPVMZ.js +204 -0
  7. package/dist/{chunk-LCJNIHZY.js → chunk-OUMW5LKJ.js} +4745 -7689
  8. package/dist/{chunk-IR7SA2ME.js → chunk-WIT46HVC.js} +1 -1
  9. package/dist/{chunk-XFXGFUAM.js → chunk-XVGMGFKF.js} +1 -1
  10. package/dist/{chunk-WGRVAGSR.js → chunk-ZDETCPCE.js} +2 -2
  11. package/dist/{ci-6XYG7XNX.js → ci-Q4PLRFPB.js} +11 -9
  12. package/dist/{cli-2XL3VESS.js → cli-LS2THG3F.js} +12 -12
  13. package/dist/commands/db/apply/helpers/plan-check-filter.d.ts +1 -1
  14. package/dist/commands/db/sync/schema-guardrail-graph.d.ts +2 -0
  15. package/dist/commands/db/sync/schema-guardrail-rewrite.d.ts +8 -0
  16. package/dist/commands/db/sync/schema-guardrail-types.d.ts +2 -2
  17. package/dist/commands/db/utils/function-acl-manifest.d.ts +39 -0
  18. package/dist/{db-4AGPISOW.js → db-MB3LQIGI.js} +226 -166
  19. package/dist/{dev-QR55VDNZ.js → dev-N3BFJZ7F.js} +3 -2
  20. package/dist/{env-KYR6Q7WO.js → env-2XM45E7O.js} +4 -3
  21. package/dist/{env-XPPACZM4.js → env-KIMSQSPS.js} +3 -2
  22. package/dist/helpers-PDT3WQNF.js +15 -0
  23. package/dist/{hotfix-JYHDY2M6.js → hotfix-QP5J6FCD.js} +4 -3
  24. package/dist/index.js +3 -3
  25. package/dist/local-supabase-KTTC3O2L.js +8 -0
  26. package/dist/{risk-detector-GDDLISVE.js → risk-detector-4D5HRUMY.js} +1 -1
  27. package/dist/{risk-detector-core-YI3M6INI.js → risk-detector-core-CHUY6M5N.js} +1 -1
  28. package/dist/{vuln-check-LMDYYJUE.js → vuln-check-JSPRI5ZY.js} +1 -1
  29. package/dist/{vuln-checker-NHXLNZRM.js → vuln-checker-H3VJY5WX.js} +1 -1
  30. package/dist/{watch-4RHXVCQ3.js → watch-VQQHKDNQ.js} +1 -1
  31. package/package.json +1 -1
  32. package/dist/{risk-detector-plpgsql-4GWEQXUG.js → risk-detector-plpgsql-NNUZU3OQ.js} +1 -1
@@ -1,30 +1,32 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'module';
3
- import { detectDatabaseStack, getStackPaths } from './chunk-MILCC3B6.js';
4
- import { categorizeRisks, detectSchemaRisks } from './chunk-XFXGFUAM.js';
5
- import { isExecaError, resolveDbPreviewEnvironment, buildDbPlanCommandLabel, runDbApply, buildDbApplyCliError, DbPlanOutputSchema, parseDbPreviewProfile, DEFAULT_DB_PREVIEW_PROFILE, getDbPreviewModeLabel, buildDbPreviewCommandLabel, isCompareOnlyPreviewProfile, DbApplyOutputSchema, applyCommand, getDbPreviewIdempotentSchemaCount, classifyDbSyncCommandFailure, getDbSyncFallbackSuggestions, detectAppSchemas, normalizeDatabaseUrlForDdl, analyzeDuplicateFunctionOwnership, formatDuplicateFunctionOwnershipFinding, reviewDeclarativeDependencyWarnings, logDeclarativeDependencyWarnings, buildDeclarativeDependencyWarningFailureLines, parsePlanOutput, validateDependencyOrder, getBoundaryPolicy, resolveProductionApplyStrictMode, findDeclarativeRiskAllowlistMatch, assertBoundaryPolicyUsable, assertBoundaryPolicyQualityGate, formatSchemasForSql, findDirectoryPlacementAllowlistMatch, formatAllowlistMetadata, assessPlanSize, formatPlanSizeSummary, extractFunctionOwnershipDefinition } from './chunk-LCJNIHZY.js';
6
3
  import { createError } from './chunk-NIS77243.js';
7
- import { resolveDatabaseUrl, resolveDatabaseTarget, tryResolveDatabaseUrl } from './chunk-WGRVAGSR.js';
8
- export { resolveDatabaseUrl, tryResolveDatabaseUrl } from './chunk-WGRVAGSR.js';
9
- import { analyzeDeclarativeDependencyContract, formatDeclarativeDependencyViolation, parseSqlFilename, collectSqlFiles, splitSqlStatements, ALLOW_DYNAMIC_SQL_ANNOTATION, extractFirstDollarBody, sanitizeExecutableCode, detectExtensionFilePath, FUNCTION_DEFINITION_RE, blankQuotedStrings, sanitizeExecutableCodePreserveStrings, countNewlines, shouldReviewUnknownDeclarativeDdl, extractDdlObject, isNonSchemaOperation, isNonDdlMaintenanceStatement, shouldReviewUnknownIdempotentDdl } from './chunk-HWR5NUUZ.js';
10
- import './chunk-UHDAYPHH.js';
4
+ import { detectDatabaseStack, getStackPaths } from './chunk-MILCC3B6.js';
5
+ import { categorizeRisks, detectSchemaRisks } from './chunk-XVGMGFKF.js';
6
+ import { isExecaError, resolveDbPreviewEnvironment, buildDbPlanCommandLabel, runDbApply, buildDbApplyCliError, parseDbPreviewProfile, DEFAULT_DB_PREVIEW_PROFILE, getDbPreviewModeLabel, buildDbPreviewCommandLabel, isCompareOnlyPreviewProfile, applyCommand, getDbPreviewIdempotentSchemaCount, classifyDbSyncCommandFailure, getDbSyncFallbackSuggestions, reviewDeclarativeDependencyWarnings, logDeclarativeDependencyWarnings, buildDeclarativeDependencyWarningFailureLines, getBoundaryPolicy, resolveProductionApplyStrictMode, findDeclarativeRiskAllowlistMatch, assertBoundaryPolicyUsable, assertBoundaryPolicyQualityGate, findDirectoryPlacementAllowlistMatch, formatAllowlistMetadata, assessPlanSize, formatPlanSizeSummary } from './chunk-AYYHYZU7.js';
7
+ import { DbPlanOutputSchema, DbApplyOutputSchema, detectAppSchemas, normalizeDatabaseUrlForDdl, analyzeDuplicateFunctionOwnership, formatDuplicateFunctionOwnershipFinding, parsePlanOutput, validateDependencyOrder, formatSchemasForSql, FUNCTION_ACL_RECONCILIATION_RELATIVE_PATH, functionAclManifestHasEntries, validateFunctionAclMigration, isManagedFunctionAclFileContentStale, renderFunctionAclFile, buildFunctionAclManifestFromSqlFiles, buildFunctionAclIdempotentTouchMetadata, stableSorted, normalizePolicyCommand, normalizeFileList, extractFunctionOwnershipDefinition, SECURITY_DEFINER_RE, MANAGED_BOUNDARY_SCHEMAS, currentIsoTimestamp, makeGraphVersion, GENERATOR_VERSION, MAX_SCHEMA_GUIDANCE_TARGETS_PER_FILE, QUALIFIED_SQL_OBJECT_RE, SEARCH_PATH_LOCK_RE, TRIGGER_GUIDANCE_SUPPRESSED_FUNCTIONS, SQL_EXTENSION_IDENTIFIER_PATTERN, SQL_IDENTIFIER_PATTERN } from './chunk-OUMW5LKJ.js';
11
8
  import './chunk-EZ46JIEO.js';
9
+ import { resolveDatabaseUrl, resolveDatabaseTarget, tryResolveDatabaseUrl } from './chunk-ZDETCPCE.js';
10
+ export { resolveDatabaseUrl, tryResolveDatabaseUrl } from './chunk-ZDETCPCE.js';
11
+ import { analyzeDeclarativeDependencyContract, formatDeclarativeDependencyViolation, parseSqlFilename, collectSqlFiles, splitSqlStatements, ALLOW_DYNAMIC_SQL_ANNOTATION, extractFirstDollarBody, sanitizeExecutableCode, detectExtensionFilePath, FUNCTION_DEFINITION_RE, blankQuotedStrings, sanitizeExecutableCodePreserveStrings, countNewlines, shouldReviewUnknownDeclarativeDdl, extractDdlObject, isNonSchemaOperation, isNonDdlMaintenanceStatement, shouldReviewUnknownIdempotentDdl } from './chunk-HWR5NUUZ.js';
12
+ import './chunk-47BG6DRP.js';
13
+ import { writeEnvLocalBridge, removeEnvLocalBridge } from './chunk-KUH3G522.js';
14
+ import { extractSchemaTablesAndEnums, fetchDbTablesAndEnums, extractTablesFromIdempotentSql, extractDynamicTablePatternsFromIdempotentSql, diffSchema, getSqlParserUtils, buildTablePatternMatcher } from './chunk-O3M7A73M.js';
15
+ import { psqlExec, psqlQuery, blankDollarQuotedBodies, stripSqlComments, parsePostgresUrl, buildPsqlArgs, buildPsqlEnv } from './chunk-A6A7JIRD.js';
12
16
  import { loadEnvFiles } from './chunk-IWVXI5O4.js';
13
- import './chunk-IR7SA2ME.js';
17
+ import './chunk-WIT46HVC.js';
14
18
  import { diagnoseSupabaseStart } from './chunk-AAIE4F2U.js';
15
19
  import { validateUserFilePath, filterSafePaths, resolveSafePath } from './chunk-B7C7CLW2.js';
16
20
  import { runMachine } from './chunk-QDF7QXBL.js';
17
21
  import './chunk-XVNDDHAF.js';
18
- import { writeEnvLocalBridge, removeEnvLocalBridge } from './chunk-KUH3G522.js';
19
- import { extractSchemaTablesAndEnums, fetchDbTablesAndEnums, extractTablesFromIdempotentSql, extractDynamicTablePatternsFromIdempotentSql, diffSchema, getSqlParserUtils, buildTablePatternMatcher } from './chunk-O3M7A73M.js';
20
- import { psqlExec, psqlQuery, blankDollarQuotedBodies, stripSqlComments, parsePostgresUrl, buildPsqlArgs, buildPsqlEnv } from './chunk-A6A7JIRD.js';
21
22
  import { redactSecrets } from './chunk-II7VYQEM.js';
22
- import { init_local_supabase, init_constants, detectLocalSupabasePorts, buildLocalDatabaseUrl, DATABASE_DEFAULTS, SEED_DEFAULTS, SCRIPT_LOCATIONS } from './chunk-QSEF4T3Y.js';
23
- export { DATABASE_DEFAULTS, SCRIPT_LOCATIONS, SEED_DEFAULTS } from './chunk-QSEF4T3Y.js';
23
+ import { init_constants, DATABASE_DEFAULTS, SEED_DEFAULTS, SCRIPT_LOCATIONS } from './chunk-NOXYPVMZ.js';
24
+ export { DATABASE_DEFAULTS, SCRIPT_LOCATIONS, SEED_DEFAULTS } from './chunk-NOXYPVMZ.js';
24
25
  import { secureSupabase, secureDocker } from './chunk-RZLYEO4U.js';
25
26
  import { emitJsonSuccess } from './chunk-KE6QJBZG.js';
26
27
  import './chunk-WJXC4MVY.js';
27
28
  import { getOutputFormatFromEnv } from './chunk-HKUWEGUX.js';
29
+ import { init_local_supabase, detectLocalSupabasePorts, buildLocalDatabaseUrl } from './chunk-F2AQ3EYJ.js';
28
30
  import { getDatabasePackagePath, loadRunaConfig, getSDKScriptsPath } from './chunk-OERS32LW.js';
29
31
  import { findRunaConfig, findWorkspaceRoot } from './chunk-GT5DMS5R.js';
30
32
  import { init_esm_shims } from './chunk-VRXHCR5K.js';
@@ -1145,7 +1147,8 @@ z.object({
1145
1147
  });
1146
1148
  var SchemaManagedBlockKindSchema = z.enum([
1147
1149
  "file-header",
1148
- "table-header"
1150
+ "table-header",
1151
+ "generated-file"
1149
1152
  ]);
1150
1153
  var SchemaGuardrailPhaseIdSchema = z.enum([
1151
1154
  "load_sources",
@@ -1166,6 +1169,7 @@ var SchemaGuardrailFailureCodeSchema = z.enum([
1166
1169
  "dynamic_sql_blocked",
1167
1170
  "extension_placement_blocked",
1168
1171
  "stale_generated_header",
1172
+ "function_acl_migration_required",
1169
1173
  "generated_header_validation_failed",
1170
1174
  "generated_header_rewrite_failed",
1171
1175
  "static_graph_build_failed",
@@ -1509,39 +1513,46 @@ function buildGuardrailConflictEntries(report, entries) {
1509
1513
  pushSemanticEvidenceEntries(entries, report);
1510
1514
  pushBoundaryGuidanceEntries(entries, report);
1511
1515
  }
1512
- function buildGuardrailHeaderEntries(report, entries) {
1513
- if (report.staleBlocks.length > 0) {
1514
- const byFile = /* @__PURE__ */ new Map();
1515
- for (const block of report.staleBlocks) {
1516
- const kinds = byFile.get(block.file) ?? [];
1517
- kinds.push(block.kind === "file-header" ? "file metadata" : `table: ${block.target}`);
1518
- byFile.set(block.file, kinds);
1519
- }
1516
+ function describeStaleBlock(block) {
1517
+ return block.kind === "file-header" ? "file metadata" : block.kind === "generated-file" ? "managed file body" : `table: ${block.target}`;
1518
+ }
1519
+ function pushStaleArtifactEntries(report, entries) {
1520
+ if (report.staleBlocks.length === 0) {
1521
+ return;
1522
+ }
1523
+ const byFile = /* @__PURE__ */ new Map();
1524
+ for (const block of report.staleBlocks) {
1525
+ const kinds = byFile.get(block.file) ?? [];
1526
+ kinds.push(describeStaleBlock(block));
1527
+ byFile.set(block.file, kinds);
1528
+ }
1529
+ entries.push({
1530
+ level: "warn",
1531
+ message: `Generated SQL artifacts are stale (${report.staleBlocks.length} block(s) in ${byFile.size} file(s)):`
1532
+ });
1533
+ for (const [file, kinds] of byFile) {
1520
1534
  entries.push({
1521
- level: "warn",
1522
- message: `Generated headers are stale (${report.staleBlocks.length} block(s) in ${byFile.size} file(s)):`
1535
+ level: "info",
1536
+ message: ` ${file}: ${kinds.join(", ")}`
1537
+ });
1538
+ }
1539
+ if (!report.failure) {
1540
+ entries.push({
1541
+ level: "info",
1542
+ message: "Auto-fix: Run `runa db sync` to regenerate managed SQL artifacts automatically."
1543
+ });
1544
+ entries.push({
1545
+ level: "info",
1546
+ message: "Managed SQL artifacts track: FK references, RLS policies, triggers, function ownership, schema dependencies, and function ACL reconciliation."
1523
1547
  });
1524
- for (const [file, kinds] of byFile) {
1525
- entries.push({
1526
- level: "info",
1527
- message: ` ${file}: ${kinds.join(", ")}`
1528
- });
1529
- }
1530
- if (!report.failure) {
1531
- entries.push({
1532
- level: "info",
1533
- message: "Auto-fix: Run `runa db sync` to regenerate all headers automatically."
1534
- });
1535
- entries.push({
1536
- level: "info",
1537
- message: "Headers track: FK references, RLS policies, triggers, function ownership, and schema dependencies."
1538
- });
1539
- }
1540
1548
  }
1549
+ }
1550
+ function buildGuardrailHeaderEntries(report, entries) {
1551
+ pushStaleArtifactEntries(report, entries);
1541
1552
  if (report.headersRewritten.length > 0) {
1542
1553
  entries.push({
1543
1554
  level: "info",
1544
- message: `Generated headers refreshed in ${report.headersRewritten.length} file(s).`
1555
+ message: `Generated SQL artifacts refreshed in ${report.headersRewritten.length} file(s).`
1545
1556
  });
1546
1557
  }
1547
1558
  }
@@ -2797,7 +2808,7 @@ function normalizeAllowlistSignature(value) {
2797
2808
  function normalizeSuppressionPair(value) {
2798
2809
  return value.split("::").map((part) => part.trim().toLowerCase()).filter((part) => part.length > 0).sort((left, right) => left.localeCompare(right)).join("::");
2799
2810
  }
2800
- function normalizeFileList(files) {
2811
+ function normalizeFileList2(files) {
2801
2812
  return [...new Set(files)].sort((a, b) => a.localeCompare(b));
2802
2813
  }
2803
2814
  function isSchemaGuardrailTextFallbackAllowed() {
@@ -2859,7 +2870,7 @@ function loadSchemaGuardrailConfig(targetDir) {
2859
2870
  // Fallback: merge schema-ownership.json allowed_duplicates if present
2860
2871
  ...loadAllowedDuplicatesFromSchemaOwnership(targetDir)
2861
2872
  ],
2862
- generatedHeaderRewriteTargets: normalizeFileList(
2873
+ generatedHeaderRewriteTargets: normalizeFileList2(
2863
2874
  (databaseConfig.schemaGuardrails?.generatedHeaderRewriteTargets ?? []).map(
2864
2875
  (value) => normalizePathForMatch(value)
2865
2876
  )
@@ -2884,7 +2895,7 @@ function loadSchemaGuardrailConfig(targetDir) {
2884
2895
  defaults,
2885
2896
  normalizers: {
2886
2897
  normalizeAllowlistSignature,
2887
- normalizeFileList,
2898
+ normalizeFileList: normalizeFileList2,
2888
2899
  normalizeFunctionQualifiedName,
2889
2900
  normalizePathForMatch,
2890
2901
  normalizeSuppressionPair
@@ -4196,7 +4207,7 @@ init_esm_shims();
4196
4207
  var riskDetectorLoader = null;
4197
4208
  function loadRiskDetectorModule() {
4198
4209
  if (!riskDetectorLoader) {
4199
- riskDetectorLoader = import('./risk-detector-GDDLISVE.js').then((module) => ({
4210
+ riskDetectorLoader = import('./risk-detector-4D5HRUMY.js').then((module) => ({
4200
4211
  detectSchemaRisks: module.detectSchemaRisks
4201
4212
  })).catch((error) => {
4202
4213
  riskDetectorLoader = null;
@@ -5441,7 +5452,7 @@ init_esm_shims();
5441
5452
 
5442
5453
  // src/commands/db/sync/schema-guardrail-runtime.ts
5443
5454
  init_esm_shims();
5444
- function stableSorted(values, map) {
5455
+ function stableSorted2(values, map) {
5445
5456
  return [...values].sort((a, b) => map(a).localeCompare(map(b)));
5446
5457
  }
5447
5458
  function normalizeFkSet(foreignKeys) {
@@ -5563,8 +5574,8 @@ function reconcileRuntimeGraph(params) {
5563
5574
  });
5564
5575
  }
5565
5576
  return {
5566
- warnings: stableSorted(warnings, (value) => value.target),
5567
- contradictions: stableSorted(contradictions, (value) => `${value.code}.${value.target}`)
5577
+ warnings: stableSorted2(warnings, (value) => value.target),
5578
+ contradictions: stableSorted2(contradictions, (value) => `${value.code}.${value.target}`)
5568
5579
  };
5569
5580
  }
5570
5581
  function runSchemaGuardrailRuntime(input) {
@@ -5594,7 +5605,7 @@ function runSchemaGuardrailRuntime(input) {
5594
5605
 
5595
5606
  // src/commands/db/sync/schema-guardrail-local-blockers.ts
5596
5607
  init_esm_shims();
5597
- function stableSorted2(values, keyOf) {
5608
+ function stableSorted3(values, keyOf) {
5598
5609
  return [...values].sort((left, right) => keyOf(left).localeCompare(keyOf(right)));
5599
5610
  }
5600
5611
  function createCrossSchemaHelperSuggestion(_filePath) {
@@ -5623,7 +5634,7 @@ function buildRawCrossSchemaRlsBlockers(params) {
5623
5634
  });
5624
5635
  }
5625
5636
  }
5626
- return stableSorted2(
5637
+ return stableSorted3(
5627
5638
  blockers,
5628
5639
  (value) => `${value.sourceFile}:${value.line ?? 0}:${value.target}`
5629
5640
  );
@@ -5650,7 +5661,7 @@ function buildExtensionPlacementBlockers(params) {
5650
5661
  });
5651
5662
  }
5652
5663
  }
5653
- return stableSorted2(
5664
+ return stableSorted3(
5654
5665
  blockers,
5655
5666
  (value) => `${value.sourceFile}:${value.line ?? 0}:${value.target}`
5656
5667
  );
@@ -5741,7 +5752,7 @@ function buildDynamicSqlBlockers(params) {
5741
5752
  blockers.push(...stmtBlockers);
5742
5753
  }
5743
5754
  }
5744
- return stableSorted2(blockers, (value) => `${value.sourceFile}:${value.line ?? 0}:${value.kind}`);
5755
+ return stableSorted3(blockers, (value) => `${value.sourceFile}:${value.line ?? 0}:${value.kind}`);
5745
5756
  }
5746
5757
  function buildLocalBlindSpotBlockers(params) {
5747
5758
  const blockers = [
@@ -5758,7 +5769,7 @@ function buildLocalBlindSpotBlockers(params) {
5758
5769
  requiredFile: detectExtensionFilePath()
5759
5770
  })
5760
5771
  ];
5761
- return stableSorted2(
5772
+ return stableSorted3(
5762
5773
  blockers,
5763
5774
  (value) => `${value.kind}:${value.sourceFile}:${value.line ?? 0}:${value.target}`
5764
5775
  );
@@ -5766,7 +5777,7 @@ function buildLocalBlindSpotBlockers(params) {
5766
5777
 
5767
5778
  // src/commands/db/sync/schema-guardrail-semantic-warnings.ts
5768
5779
  init_esm_shims();
5769
- function stableSorted3(values, map) {
5780
+ function stableSorted4(values, map) {
5770
5781
  return [...values].sort((a, b) => map(a).localeCompare(map(b)));
5771
5782
  }
5772
5783
  function normalizeFkSet2(foreignKeys) {
@@ -5971,50 +5982,7 @@ function buildSemanticDuplicateWarnings(params) {
5971
5982
  suppressionKey: createSuppressionPair(proposed.qualifiedName, primary.qualifiedName)
5972
5983
  });
5973
5984
  }
5974
- return stableSorted3(warnings, (value) => `${value.proposedTable}.${value.suppressionKey}`);
5975
- }
5976
-
5977
- // src/commands/db/sync/schema-guardrail-graph-types.ts
5978
- init_esm_shims();
5979
- var GENERATOR_VERSION = "1.0.0";
5980
- var SQL_IDENTIFIER_PATTERN = /"(?:[^"]|"")+"|[A-Za-z_][A-Za-z0-9_$]*/g;
5981
- var SQL_EXTENSION_IDENTIFIER_PATTERN = /"(?:[^"]|"")+"|[A-Za-z0-9_-]+/g;
5982
- var QUALIFIED_SQL_OBJECT_RE = /\b([A-Za-z_][A-Za-z0-9_$]*)\s*\.\s*([A-Za-z_][A-Za-z0-9_$]*)\b/g;
5983
- var SECURITY_DEFINER_RE = /\bSECURITY\s+DEFINER\b/i;
5984
- var SEARCH_PATH_LOCK_RE = /\bSET\s+search_path\s*(?:=|TO)\s*''/i;
5985
- var MANAGED_BOUNDARY_SCHEMAS = [
5986
- "auth",
5987
- "storage",
5988
- "extensions",
5989
- "net",
5990
- "supabase_functions"
5991
- ];
5992
- var TRIGGER_GUIDANCE_SUPPRESSED_FUNCTIONS = /* @__PURE__ */ new Set(["public.handle_updated_at()"]);
5993
- var MAX_SCHEMA_GUIDANCE_TARGETS_PER_FILE = 3;
5994
- function makeGraphVersion(graph) {
5995
- const canonical = JSON.stringify(graph);
5996
- const hash = createHash("sha256").update(canonical).digest("hex");
5997
- return `sha256:${hash}`;
5998
- }
5999
- function currentIsoTimestamp() {
6000
- return (/* @__PURE__ */ new Date()).toISOString();
6001
- }
6002
- function stableSorted4(values, map) {
6003
- return [...values].sort((a, b) => map(a).localeCompare(map(b)));
6004
- }
6005
- function normalizeFileList2(files) {
6006
- return [...new Set(files)].sort((a, b) => a.localeCompare(b));
6007
- }
6008
- function normalizePolicyCommand(input) {
6009
- switch (input.toLowerCase()) {
6010
- case "select":
6011
- case "insert":
6012
- case "update":
6013
- case "delete":
6014
- return input.toLowerCase();
6015
- default:
6016
- return "all";
6017
- }
5985
+ return stableSorted4(warnings, (value) => `${value.proposedTable}.${value.suppressionKey}`);
6018
5986
  }
6019
5987
 
6020
5988
  // src/commands/db/sync/schema-guardrail-graph-nodes.ts
@@ -6060,8 +6028,8 @@ function collectQualifiedObjectRefs(params) {
6060
6028
  schemas.add(schema);
6061
6029
  }
6062
6030
  return {
6063
- refs: stableSorted4(refs, (value) => value),
6064
- schemas: stableSorted4(schemas, (value) => value)
6031
+ refs: stableSorted(refs, (value) => value),
6032
+ schemas: stableSorted(schemas, (value) => value)
6065
6033
  };
6066
6034
  }
6067
6035
  function isSearchPathLocked(statement) {
@@ -6099,7 +6067,7 @@ function buildDefinedFunctionMetadataByFile(params) {
6099
6067
  }
6100
6068
  metadataByFile.set(
6101
6069
  file.relativePath,
6102
- stableSorted4(fileMetadata, (value) => value.qualifiedSignature)
6070
+ stableSorted(fileMetadata, (value) => value.qualifiedSignature)
6103
6071
  );
6104
6072
  }
6105
6073
  return metadataByFile;
@@ -6193,13 +6161,13 @@ async function buildDeclarativeFileRecord(file) {
6193
6161
  file,
6194
6162
  declaredSchemas: [...declaredSchemas].sort((a, b) => a.localeCompare(b)),
6195
6163
  createSchemaClaims: [...createSchemaClaims].sort((a, b) => a.localeCompare(b)),
6196
- tables: stableSorted4(
6164
+ tables: stableSorted(
6197
6165
  document.tables.map((table) => ({
6198
6166
  schema: table.schema,
6199
6167
  name: table.name,
6200
6168
  qualifiedName: table.qualifiedName,
6201
6169
  lineNumber: table.lineNumber,
6202
- columns: stableSorted4(table.columns, (value) => value.name).map((value) => value.name),
6170
+ columns: stableSorted(table.columns, (value) => value.name).map((value) => value.name),
6203
6171
  outboundForeignKeys: table.foreignKeys.map((fk) => ({
6204
6172
  column: fk.column,
6205
6173
  referencesTable: fk.referencesTable,
@@ -6210,7 +6178,7 @@ async function buildDeclarativeFileRecord(file) {
6210
6178
  })),
6211
6179
  (value) => value.qualifiedName
6212
6180
  ),
6213
- policies: stableSorted4(
6181
+ policies: stableSorted(
6214
6182
  document.policies.map((policy) => ({
6215
6183
  name: policy.name,
6216
6184
  targetTable: `${policy.schema}.${policy.table}`,
@@ -6264,10 +6232,10 @@ function collectDeclarativeClaims(records) {
6264
6232
  };
6265
6233
  }
6266
6234
  function createDuplicateTableOwners(tableOwnerClaims) {
6267
- return stableSorted4(
6235
+ return stableSorted(
6268
6236
  [...tableOwnerClaims.entries()].filter(([, files]) => files.size > 1).map(([qualifiedName, files]) => ({
6269
6237
  qualifiedName,
6270
- files: normalizeFileList2(files)
6238
+ files: normalizeFileList(files)
6271
6239
  })),
6272
6240
  (value) => value.qualifiedName
6273
6241
  );
@@ -6281,7 +6249,7 @@ function buildFunctionValidationArtifacts(params) {
6281
6249
  ...buildFunctionBodyHashMap(params.declarativeFiles, "declarative"),
6282
6250
  ...buildFunctionBodyHashMap(params.idempotentFiles, "idempotent")
6283
6251
  ]);
6284
- const duplicateFunctionOwners = stableSorted4(
6252
+ const duplicateFunctionOwners = stableSorted(
6285
6253
  functionAnalysis.findings.filter(
6286
6254
  (finding) => !isAllowlistedDuplicateFunction({
6287
6255
  finding,
@@ -6291,16 +6259,16 @@ function buildFunctionValidationArtifacts(params) {
6291
6259
  ).map((finding) => ({
6292
6260
  qualifiedName: finding.qualifiedName,
6293
6261
  signature: finding.signature,
6294
- declarativeFiles: normalizeFileList2(
6262
+ declarativeFiles: normalizeFileList(
6295
6263
  finding.declarativeDefinitions.map((value) => value.file)
6296
6264
  ),
6297
- idempotentFiles: normalizeFileList2(
6265
+ idempotentFiles: normalizeFileList(
6298
6266
  finding.idempotentDefinitions.map((value) => value.file)
6299
6267
  )
6300
6268
  })),
6301
6269
  (value) => `${value.qualifiedName}.${value.signature ?? ""}`
6302
6270
  );
6303
- const functionClaims = stableSorted4(
6271
+ const functionClaims = stableSorted(
6304
6272
  [
6305
6273
  ...functionAnalysis.definitions.declarative.map((definition) => ({
6306
6274
  qualifiedName: definition.qualifiedName,
@@ -6329,7 +6297,7 @@ function buildFunctionValidationArtifacts(params) {
6329
6297
  function buildOwnerFileByTable(tableOwnerClaims) {
6330
6298
  const ownerFileByTable = /* @__PURE__ */ new Map();
6331
6299
  for (const [qualifiedName, files] of tableOwnerClaims.entries()) {
6332
- const normalizedFiles = normalizeFileList2(files);
6300
+ const normalizedFiles = normalizeFileList(files);
6333
6301
  if (normalizedFiles[0]) {
6334
6302
  ownerFileByTable.set(qualifiedName, normalizedFiles[0]);
6335
6303
  }
@@ -6349,7 +6317,7 @@ function buildPolicyOwnershipConflicts(params) {
6349
6317
  conflicts.push({
6350
6318
  policyName: policyClaim.name,
6351
6319
  targetTable: policyClaim.targetTable,
6352
- files: normalizeFileList2([policyClaim.sourceFile]),
6320
+ files: normalizeFileList([policyClaim.sourceFile]),
6353
6321
  tableOwnerFile: ownerFile
6354
6322
  });
6355
6323
  }
@@ -6360,11 +6328,11 @@ function buildPolicyOwnershipConflicts(params) {
6360
6328
  conflicts.push({
6361
6329
  policyName,
6362
6330
  targetTable,
6363
- files: normalizeFileList2(files),
6331
+ files: normalizeFileList(files),
6364
6332
  tableOwnerFile: params.ownerFileByTable.get(targetTable) ?? ""
6365
6333
  });
6366
6334
  }
6367
- return stableSorted4(
6335
+ return stableSorted(
6368
6336
  conflicts,
6369
6337
  (value) => `${value.targetTable}.${value.policyName}.${value.files.join(",")}`
6370
6338
  );
@@ -6380,16 +6348,16 @@ function buildTableNodesByName(params) {
6380
6348
  ownerFile: record.file.relativePath,
6381
6349
  lineNumber: table.lineNumber,
6382
6350
  columns: table.columns,
6383
- outboundForeignKeys: stableSorted4(
6351
+ outboundForeignKeys: stableSorted(
6384
6352
  table.outboundForeignKeys,
6385
6353
  (value) => `${value.referencesTable}.${value.column}`
6386
6354
  ),
6387
6355
  inboundForeignKeys: [],
6388
- policies: stableSorted4(
6356
+ policies: stableSorted(
6389
6357
  params.tablePolicies.get(table.qualifiedName) ?? [],
6390
6358
  (value) => value.name
6391
6359
  ),
6392
- triggers: stableSorted4(
6360
+ triggers: stableSorted(
6393
6361
  record.triggersByTable.get(table.qualifiedName) ?? [],
6394
6362
  (value) => value.name
6395
6363
  )
@@ -6413,7 +6381,7 @@ function attachInboundForeignKeys(tableNodesByName) {
6413
6381
  }
6414
6382
  }
6415
6383
  for (const tableNode of tableNodesByName.values()) {
6416
- tableNode.inboundForeignKeys = stableSorted4(
6384
+ tableNode.inboundForeignKeys = stableSorted(
6417
6385
  tableNode.inboundForeignKeys,
6418
6386
  (value) => `${value.fromTable}.${value.fromColumn}`
6419
6387
  );
@@ -6432,12 +6400,12 @@ function buildFileDependencies(params) {
6432
6400
  fileDependencyMap.set(tableNode.ownerFile, edges);
6433
6401
  }
6434
6402
  }
6435
- return stableSorted4(
6403
+ return stableSorted(
6436
6404
  [...fileDependencyMap.entries()].flatMap(
6437
6405
  ([fromFile, toMap]) => [...toMap.entries()].map(([toFile, viaTables]) => ({
6438
6406
  fromFile,
6439
6407
  toFile,
6440
- viaTables: normalizeFileList2(viaTables)
6408
+ viaTables: normalizeFileList(viaTables)
6441
6409
  }))
6442
6410
  ),
6443
6411
  (value) => `${value.fromFile}->${value.toFile}`
@@ -6459,7 +6427,7 @@ function buildFileNodes(params) {
6459
6427
  ["22_observability_cron.sql", "cron-registration"],
6460
6428
  ["25_storage_seed_bucket.sql", "storage-bootstrap"]
6461
6429
  ]);
6462
- return stableSorted4(
6430
+ return stableSorted(
6463
6431
  [
6464
6432
  ...params.records.map((record) => {
6465
6433
  const definedFunctions = params.definedFunctionMetadataByFile.get(record.file.relativePath) ?? [];
@@ -6469,7 +6437,7 @@ function buildFileNodes(params) {
6469
6437
  schemas: [],
6470
6438
  refs: []
6471
6439
  };
6472
- const triggerFunctions = stableSorted4(
6440
+ const triggerFunctions = stableSorted(
6473
6441
  new Set(
6474
6442
  [...record.triggersByTable.values()].flat().map((trigger) => normalizeTriggerFunctionToken(trigger.functionName)).filter((value) => value !== null)
6475
6443
  ),
@@ -6482,7 +6450,7 @@ function buildFileNodes(params) {
6482
6450
  domainName: path12.basename(record.file.relativePath, ".sql"),
6483
6451
  declaredSchemas: record.declaredSchemas,
6484
6452
  ownedTables: record.tables.map((table) => table.qualifiedName),
6485
- forwardDependsOnFiles: stableSorted4(
6453
+ forwardDependsOnFiles: stableSorted(
6486
6454
  params.fileDependencies.filter((edge) => edge.fromFile === record.file.relativePath).map((edge) => edge.toFile),
6487
6455
  (value) => value
6488
6456
  ),
@@ -6490,7 +6458,7 @@ function buildFileNodes(params) {
6490
6458
  securityDefinerFunctions: definedFunctions.filter((value) => value.securityDefiner).map((value) => value.qualifiedSignature),
6491
6459
  securityDefinerContracts: definedFunctions.filter((value) => value.securityDefiner && value.searchPathLocked).map((value) => value.qualifiedSignature),
6492
6460
  triggerFunctions,
6493
- functionCrossSchemaRefs: stableSorted4(
6461
+ functionCrossSchemaRefs: stableSorted(
6494
6462
  new Set(definedFunctions.flatMap((value) => value.crossSchemaRefs)),
6495
6463
  (value) => value
6496
6464
  ),
@@ -6500,7 +6468,7 @@ function buildFileNodes(params) {
6500
6468
  touchedExtensions: [],
6501
6469
  touchedFunctions: [],
6502
6470
  touchedPolicies: [],
6503
- policyCrossSchemaRefs: stableSorted4(
6471
+ policyCrossSchemaRefs: stableSorted(
6504
6472
  new Set(
6505
6473
  collectPolicyCrossSchemaReferences({
6506
6474
  content: record.file.content,
@@ -6537,7 +6505,7 @@ function buildFileNodes(params) {
6537
6505
  securityDefinerFunctions: definedFunctions.filter((value) => value.securityDefiner).map((value) => value.qualifiedSignature),
6538
6506
  securityDefinerContracts: definedFunctions.filter((value) => value.securityDefiner && value.searchPathLocked).map((value) => value.qualifiedSignature),
6539
6507
  triggerFunctions: [],
6540
- functionCrossSchemaRefs: stableSorted4(
6508
+ functionCrossSchemaRefs: stableSorted(
6541
6509
  new Set(definedFunctions.flatMap((value) => value.crossSchemaRefs)),
6542
6510
  (value) => value
6543
6511
  ),
@@ -6700,7 +6668,7 @@ function extractTouchedSchemas(content) {
6700
6668
  }
6701
6669
  }
6702
6670
  }
6703
- return stableSorted4(touched, (value) => value);
6671
+ return stableSorted(touched, (value) => value);
6704
6672
  }
6705
6673
  function extractTouchedFunctions(content) {
6706
6674
  const touched = /* @__PURE__ */ new Set();
@@ -6717,7 +6685,7 @@ function extractTouchedFunctions(content) {
6717
6685
  }
6718
6686
  }
6719
6687
  }
6720
- return stableSorted4(touched, (value) => value);
6688
+ return stableSorted(touched, (value) => value);
6721
6689
  }
6722
6690
  function normalizeExtensionIdentifier(identifier) {
6723
6691
  const trimmed = identifier.trim();
@@ -6740,7 +6708,7 @@ function extractTouchedExtensions(content) {
6740
6708
  }
6741
6709
  touched.add(normalizeExtensionIdentifier(identifier));
6742
6710
  }
6743
- return stableSorted4(touched, (value) => value);
6711
+ return stableSorted(touched, (value) => value);
6744
6712
  }
6745
6713
  function extractTouchedPolicies(content) {
6746
6714
  const touched = /* @__PURE__ */ new Set();
@@ -6754,7 +6722,7 @@ function extractTouchedPolicies(content) {
6754
6722
  }
6755
6723
  touched.add(`${schemaName}.${tableName}.${policyName}`);
6756
6724
  }
6757
- return stableSorted4(touched, (value) => value);
6725
+ return stableSorted(touched, (value) => value);
6758
6726
  }
6759
6727
  function extractIdempotentTouchMetadata(file) {
6760
6728
  const sanitizedContent = sanitizeIdempotentTouchScanContent(file.content);
@@ -6772,7 +6740,7 @@ function buildIdempotentTouchMetadata(files) {
6772
6740
  // src/commands/db/sync/schema-guardrail-graph-guidance.ts
6773
6741
  init_esm_shims();
6774
6742
  function summarizeBoundaryTargets(targets) {
6775
- const sortedTargets = stableSorted4(new Set(targets), (value) => value);
6743
+ const sortedTargets = stableSorted(new Set(targets), (value) => value);
6776
6744
  if (sortedTargets.length <= 2) {
6777
6745
  return sortedTargets.join(", ");
6778
6746
  }
@@ -6925,7 +6893,7 @@ function buildUnlockedSecurityDefinerGuidanceWarnings(params) {
6925
6893
  return [];
6926
6894
  }
6927
6895
  const lockedContracts = new Set(params.fileNode.securityDefinerContracts);
6928
- const unlockedFunctions = stableSorted4(
6896
+ const unlockedFunctions = stableSorted(
6929
6897
  params.fileNode.securityDefinerFunctions.filter(
6930
6898
  (qualifiedName) => !lockedContracts.has(qualifiedName)
6931
6899
  ),
@@ -6989,7 +6957,7 @@ function buildSecurityDefinerGuidanceWarnings(params) {
6989
6957
  if (!suggestedIdempotentFile || !targets) {
6990
6958
  return [];
6991
6959
  }
6992
- const touchedSecurityDefiners = stableSorted4(
6960
+ const touchedSecurityDefiners = stableSorted(
6993
6961
  new Set(targets.filter((target) => securityDefinerSet.has(target))),
6994
6962
  (value) => value
6995
6963
  );
@@ -7077,7 +7045,7 @@ function buildBoundaryGuidanceWarnings(params) {
7077
7045
  );
7078
7046
  continue;
7079
7047
  }
7080
- const touchedSchemas = stableSorted4(new Set(fileNode.touchedSchemas), (value) => value);
7048
+ const touchedSchemas = stableSorted(new Set(fileNode.touchedSchemas), (value) => value);
7081
7049
  if (touchedSchemas.length <= MAX_SCHEMA_GUIDANCE_TARGETS_PER_FILE) {
7082
7050
  for (const schema of touchedSchemas) {
7083
7051
  const ownerFile = schemaOwnerByName.get(schema);
@@ -7114,7 +7082,7 @@ function buildBoundaryGuidanceWarnings(params) {
7114
7082
  reason: "This idempotent file applies policy DDL against a table that is structurally owned in declarative SQL."
7115
7083
  });
7116
7084
  }
7117
- return stableSorted4(
7085
+ return stableSorted(
7118
7086
  warnings,
7119
7087
  (value) => `${value.sourceFile}.${value.kind}.${value.suggestedDeclarativeFile ?? ""}.${value.suggestedIdempotentFile ?? ""}.${value.target}`
7120
7088
  );
@@ -7190,7 +7158,7 @@ function validateDispatchCoverage(argsByFunction, sources) {
7190
7158
  }
7191
7159
  }
7192
7160
  }
7193
- return stableSorted4(warnings, (w) => `${w.sourceFile}:${w.target}`);
7161
+ return stableSorted(warnings, (w) => `${w.sourceFile}:${w.target}`);
7194
7162
  }
7195
7163
  var CREATE_INDEX_PATTERN = /^\s*CREATE\s+(?:UNIQUE\s+)?(?:INDEX\s+)?(?:CONCURRENTLY\s+)?(?:IF\s+NOT\s+EXISTS\s+)?(?:"([^"]+)"|([A-Za-z_]\w*))\s+ON\b/gim;
7196
7164
  function extractIndexNames(content) {
@@ -7225,7 +7193,7 @@ function buildCrossLayerDuplicateIndexWarnings(sources) {
7225
7193
  }
7226
7194
  }
7227
7195
  }
7228
- return stableSorted4(warnings, (w) => `${w.sourceFile}:${w.target}`);
7196
+ return stableSorted(warnings, (w) => `${w.sourceFile}:${w.target}`);
7229
7197
  }
7230
7198
 
7231
7199
  // src/commands/db/sync/schema-guardrail-graph.ts
@@ -7236,11 +7204,11 @@ function loadSqlSources(targetDir, config) {
7236
7204
  };
7237
7205
  }
7238
7206
  function buildSchemaNodes(params) {
7239
- return stableSorted4(
7207
+ return stableSorted(
7240
7208
  [...params.schemaClaims.entries()].map(([name, files]) => ({
7241
7209
  name,
7242
- claimFiles: normalizeFileList2(files),
7243
- createSchemaFiles: normalizeFileList2(params.createSchemaClaims.get(name) ?? [])
7210
+ claimFiles: normalizeFileList(files),
7211
+ createSchemaFiles: normalizeFileList(params.createSchemaClaims.get(name) ?? [])
7244
7212
  })),
7245
7213
  (value) => value.name
7246
7214
  );
@@ -7253,9 +7221,9 @@ function createSchemaGraphManifest(params) {
7253
7221
  generatorVersion: GENERATOR_VERSION,
7254
7222
  files: params.fileNodes,
7255
7223
  schemas: params.schemaNodes,
7256
- tables: stableSorted4(params.tableNodesByName.values(), (value) => value.qualifiedName),
7224
+ tables: stableSorted(params.tableNodesByName.values(), (value) => value.qualifiedName),
7257
7225
  functionClaims: params.functionClaims,
7258
- policyClaims: stableSorted4(
7226
+ policyClaims: stableSorted(
7259
7227
  params.policyClaims,
7260
7228
  (value) => `${value.targetTable}.${value.name}.${value.sourceFile}`
7261
7229
  ),
@@ -7282,7 +7250,12 @@ async function buildStaticGraph(targetDir, config, sources) {
7282
7250
  const records = await Promise.all(
7283
7251
  declarativeFiles.map((file) => buildDeclarativeFileRecord(file))
7284
7252
  );
7253
+ const functionAclManifest = buildFunctionAclManifestFromSqlFiles(declarativeFiles);
7285
7254
  const idempotentTouchMetadata = buildIdempotentTouchMetadata(idempotentFiles);
7255
+ idempotentTouchMetadata.set(
7256
+ FUNCTION_ACL_RECONCILIATION_RELATIVE_PATH,
7257
+ buildFunctionAclIdempotentTouchMetadata(functionAclManifest)
7258
+ );
7286
7259
  const { tableOwnerClaims, schemaClaims, createSchemaClaims, tablePolicies, policyClaims } = collectDeclarativeClaims(records);
7287
7260
  const duplicateTableOwners = createDuplicateTableOwners(tableOwnerClaims);
7288
7261
  const { duplicateFunctionOwners, functionClaims } = buildFunctionValidationArtifacts({
@@ -7344,7 +7317,7 @@ async function buildStaticGraph(targetDir, config, sources) {
7344
7317
  policyClaims,
7345
7318
  fileDependencies
7346
7319
  });
7347
- const multiFileSchemas = stableSorted4(
7320
+ const multiFileSchemas = stableSorted(
7348
7321
  graph.schemas.filter((schemaNode) => schemaNode.claimFiles.length > 1).map((schemaNode) => ({
7349
7322
  schema: schemaNode.name,
7350
7323
  files: schemaNode.claimFiles
@@ -7376,6 +7349,7 @@ async function buildStaticGraph(targetDir, config, sources) {
7376
7349
  });
7377
7350
  return {
7378
7351
  graph,
7352
+ functionAclManifest,
7379
7353
  duplicateTableOwners,
7380
7354
  duplicateFunctionOwners,
7381
7355
  policyOwnershipConflicts,
@@ -7392,8 +7366,8 @@ var GUARDRAIL_PHASE_LABELS = {
7392
7366
  load_sources: "Load declarative SQL sources",
7393
7367
  build_static_graph: "Build static SQL graph",
7394
7368
  validate_ownership: "Validate ownership",
7395
- compare_generated_headers: "Compare generated headers",
7396
- refresh_generated_headers: "Refresh generated headers",
7369
+ compare_generated_headers: "Compare generated SQL artifacts",
7370
+ refresh_generated_headers: "Refresh generated SQL artifacts",
7397
7371
  handoff_db_sync: "Hand off to db sync",
7398
7372
  runtime_reconcile: "Runtime reconcile",
7399
7373
  publish_report: "Publish report"
@@ -7482,7 +7456,7 @@ function createCheckModePhases(report) {
7482
7456
  details: {
7483
7457
  file: block.file,
7484
7458
  target: block.target,
7485
- repair: "Run `runa db sync` to auto-regenerate headers"
7459
+ repair: "Run `runa db sync` to auto-regenerate managed SQL artifacts"
7486
7460
  }
7487
7461
  }))
7488
7462
  })
@@ -7984,12 +7958,35 @@ function buildHeaderRewritePlans(params) {
7984
7958
  }
7985
7959
  function loadHeaderRewritePlans(params) {
7986
7960
  try {
7987
- return buildHeaderRewritePlans({
7961
+ const headerPlans = buildHeaderRewritePlans({
7988
7962
  targetDir: params.targetDir,
7989
7963
  graph: params.graph,
7990
7964
  tableHeaderMaxWidth: params.config.tableHeaderMaxWidth,
7991
7965
  generatedHeaderRewriteTargets: params.config.generatedHeaderRewriteTargets
7992
7966
  });
7967
+ const generatedFileResult = buildGeneratedFileRewritePlans({
7968
+ targetDir: params.targetDir,
7969
+ manifest: params.functionAclManifest
7970
+ });
7971
+ if ("failure" in generatedFileResult) {
7972
+ const failureMessage = generatedFileResult.failure ?? "Unknown function ACL migration failure";
7973
+ return {
7974
+ failure: {
7975
+ graph: params.graph,
7976
+ report: setFailure2(
7977
+ params.report,
7978
+ "compare_generated_headers",
7979
+ "function_acl_migration_required",
7980
+ failureMessage
7981
+ )
7982
+ }
7983
+ };
7984
+ }
7985
+ return {
7986
+ staleBlocks: [...headerPlans.staleBlocks, ...generatedFileResult.staleBlocks],
7987
+ rewritePlans: headerPlans.rewritePlans,
7988
+ generatedFileRewritePlans: generatedFileResult.rewritePlans
7989
+ };
7993
7990
  } catch (error) {
7994
7991
  const message = error instanceof Error ? error.message : String(error);
7995
7992
  return {
@@ -8018,7 +8015,7 @@ function finalizeCheckModeReport(params) {
8018
8015
  params.report,
8019
8016
  "compare_generated_headers",
8020
8017
  "stale_generated_header",
8021
- `Generated headers are stale in ${params.report.staleBlocks.map((value) => `${value.file}:${value.kind}`).join(", ")}`
8018
+ `Generated SQL artifacts are stale in ${params.report.staleBlocks.map((value) => `${value.file}:${value.kind}`).join(", ")}`
8022
8019
  )
8023
8020
  };
8024
8021
  }
@@ -8037,6 +8034,15 @@ function rewriteManagedHeaders(params) {
8037
8034
  writeFileSync(path12.join(params.targetDir, plan.filePath), rewrittenSql, "utf-8");
8038
8035
  params.report.headersRewritten.push(plan.filePath);
8039
8036
  }
8037
+ for (const plan of params.generatedFileRewritePlans) {
8038
+ const absolutePath = path12.join(params.targetDir, plan.filePath);
8039
+ const currentSql = existsSync(absolutePath) ? readFileSync(absolutePath, "utf-8") : "";
8040
+ if (normalizeMultilineText(currentSql) === normalizeMultilineText(plan.expectedSql)) {
8041
+ continue;
8042
+ }
8043
+ writeFileSync(absolutePath, plan.expectedSql, "utf-8");
8044
+ params.report.headersRewritten.push(plan.filePath);
8045
+ }
8040
8046
  } catch (error) {
8041
8047
  const message = error instanceof Error ? error.message : String(error);
8042
8048
  return {
@@ -8054,6 +8060,41 @@ function rewriteManagedHeaders(params) {
8054
8060
  params.report.staleBlocks = [];
8055
8061
  return null;
8056
8062
  }
8063
+ function buildGeneratedFileRewritePlans(params) {
8064
+ const absolutePath = path12.join(params.targetDir, FUNCTION_ACL_RECONCILIATION_RELATIVE_PATH);
8065
+ const fileExists = existsSync(absolutePath);
8066
+ const existingSql = fileExists ? readFileSync(absolutePath, "utf-8") : "";
8067
+ if (!fileExists && !functionAclManifestHasEntries(params.manifest)) {
8068
+ return {
8069
+ staleBlocks: [],
8070
+ rewritePlans: []
8071
+ };
8072
+ }
8073
+ if (fileExists) {
8074
+ const migrationGaps = validateFunctionAclMigration(params.manifest, existingSql);
8075
+ if (migrationGaps.length > 0) {
8076
+ return {
8077
+ failure: `Function ACL migration is required before auto-generation can proceed. Add declarative annotations for: ${migrationGaps.join(", ")}`
8078
+ };
8079
+ }
8080
+ }
8081
+ const staleBlocks = !fileExists || isManagedFunctionAclFileContentStale(params.manifest, existingSql) ? [
8082
+ {
8083
+ file: FUNCTION_ACL_RECONCILIATION_RELATIVE_PATH,
8084
+ kind: "generated-file",
8085
+ target: `file:${FUNCTION_ACL_RECONCILIATION_RELATIVE_PATH}`
8086
+ }
8087
+ ] : [];
8088
+ return {
8089
+ staleBlocks,
8090
+ rewritePlans: [
8091
+ {
8092
+ filePath: FUNCTION_ACL_RECONCILIATION_RELATIVE_PATH,
8093
+ expectedSql: renderFunctionAclFile(params.manifest)
8094
+ }
8095
+ ]
8096
+ };
8097
+ }
8057
8098
 
8058
8099
  // src/commands/db/sync/schema-guardrail.ts
8059
8100
  function createEmptyReport(mode) {
@@ -8125,7 +8166,7 @@ function validateLocalBlindSpotBlockers(report, graph) {
8125
8166
  if (!primary) {
8126
8167
  return null;
8127
8168
  }
8128
- const failureCode = primary.kind === "cross-schema-rls" ? "raw_cross_schema_rls_blocked" : primary.kind === "dynamic-sql" ? "dynamic_sql_blocked" : "extension_placement_blocked";
8169
+ const failureCode = primary.kind === "cross-schema-rls" ? "raw_cross_schema_rls_blocked" : primary.kind === "dynamic-sql" || primary.kind === "dynamic-sql-infra" ? "dynamic_sql_blocked" : "extension_placement_blocked";
8129
8170
  return {
8130
8171
  graph,
8131
8172
  report: setFailure3(report, "validate_ownership", failureCode, primary.details)
@@ -8216,6 +8257,7 @@ async function runSchemaGuardrailStatic(input) {
8216
8257
  const headerPlanResult = loadHeaderRewritePlans({
8217
8258
  targetDir: input.targetDir,
8218
8259
  graph: staticGraphResult.graph,
8260
+ functionAclManifest: staticGraphResult.functionAclManifest,
8219
8261
  config,
8220
8262
  report
8221
8263
  });
@@ -8237,6 +8279,7 @@ async function runSchemaGuardrailStatic(input) {
8237
8279
  const rewriteFailure = rewriteManagedHeaders({
8238
8280
  targetDir: input.targetDir,
8239
8281
  rewritePlans: headerPlanResult.rewritePlans,
8282
+ generatedFileRewritePlans: headerPlanResult.generatedFileRewritePlans,
8240
8283
  report
8241
8284
  });
8242
8285
  if (rewriteFailure) {
@@ -8388,6 +8431,37 @@ function tryGetProductionAdminUrl(targetDir) {
8388
8431
  }
8389
8432
  return void 0;
8390
8433
  }
8434
+ function validateProductionPlan(planOutput, log) {
8435
+ if (!planOutput.trim() || planOutput.includes("No changes")) {
8436
+ log.info("\u2705 Production schema is up-to-date (no changes needed)");
8437
+ return;
8438
+ }
8439
+ const plan = parsePlanOutput(planOutput);
8440
+ const orderIssues = validateDependencyOrder(plan);
8441
+ if (orderIssues.length > 0) {
8442
+ for (const issue of orderIssues) {
8443
+ logger3.error(issue);
8444
+ }
8445
+ throw new Error(
8446
+ `\u274C Production DDL ordering issue detected (${orderIssues.length} problem(s)):
8447
+ ` + orderIssues.map((i) => ` \u2022 ${i}`).join("\n") + "\n\nThis plan would fail during production deploy. The automatic reorder will attempt to fix this, but review the ordering."
8448
+ );
8449
+ }
8450
+ log.info("\u2705 Production DDL ordering verified");
8451
+ }
8452
+ async function resolveTempDbDsnForProductionCheck(targetDir) {
8453
+ const envDsn = process.env.PG_SCHEMA_DIFF_TEMP_DB_DSN?.trim();
8454
+ if (envDsn) return envDsn;
8455
+ try {
8456
+ const { buildLocalDatabaseUrl: buildLocalDatabaseUrl2 } = await import('./local-supabase-KTTC3O2L.js');
8457
+ const { verifyDatabaseConnection } = await import('./helpers-PDT3WQNF.js');
8458
+ const localDsn = buildLocalDatabaseUrl2(targetDir);
8459
+ await verifyDatabaseConnection(localDsn, { maxRetries: 0 });
8460
+ return localDsn;
8461
+ } catch {
8462
+ }
8463
+ return void 0;
8464
+ }
8391
8465
  async function runProductionDdlOrderCheck(params) {
8392
8466
  const productionUrl = tryGetProductionAdminUrl(params.targetDir);
8393
8467
  if (productionUrl) {
@@ -8407,30 +8481,16 @@ async function runProductionDdlOrderCheck(params) {
8407
8481
  params.logger.info("\u{1F50D} Checking production DDL ordering...");
8408
8482
  try {
8409
8483
  const { executePgSchemaDiffPlan } = await import('./pg-schema-diff-helpers-JZO4GAQG.js');
8484
+ const tempDbDsn = await resolveTempDbDsnForProductionCheck(params.targetDir);
8410
8485
  const { planOutput } = executePgSchemaDiffPlan(
8411
8486
  productionUrl,
8412
8487
  schemasDir,
8413
8488
  includeSchemas,
8414
8489
  false,
8415
8490
  // not verbose
8416
- { targetDir: params.targetDir }
8491
+ { targetDir: params.targetDir, tempDbDsn }
8417
8492
  );
8418
- if (!planOutput.trim() || planOutput.includes("No changes")) {
8419
- params.logger.info("\u2705 Production schema is up-to-date (no changes needed)");
8420
- return;
8421
- }
8422
- const plan = parsePlanOutput(planOutput);
8423
- const orderIssues = validateDependencyOrder(plan);
8424
- if (orderIssues.length > 0) {
8425
- for (const issue of orderIssues) {
8426
- logger3.error(issue);
8427
- }
8428
- throw new Error(
8429
- `\u274C Production DDL ordering issue detected (${orderIssues.length} problem(s)):
8430
- ` + orderIssues.map((i) => ` \u2022 ${i}`).join("\n") + "\n\nThis plan would fail during production deploy. The automatic reorder will attempt to fix this, but review the ordering."
8431
- );
8432
- }
8433
- params.logger.info("\u2705 Production DDL ordering verified");
8493
+ validateProductionPlan(planOutput, params.logger);
8434
8494
  } catch (error) {
8435
8495
  if (error instanceof Error && error.message.includes("DDL ordering issue")) {
8436
8496
  throw error;