@standards-kit/conform 0.1.3 → 0.3.0

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 (90) hide show
  1. package/dist/{chunk-PZ2NVKI7.js → chunk-FJZMUGYW.js} +30 -13
  2. package/dist/chunk-FJZMUGYW.js.map +1 -0
  3. package/dist/chunk-O745CMWG.js +29 -0
  4. package/dist/chunk-O745CMWG.js.map +1 -0
  5. package/dist/chunk-RHM53NLG.js +49 -0
  6. package/dist/chunk-RHM53NLG.js.map +1 -0
  7. package/dist/{chunk-RXA4FO7L.js → chunk-YKKWXHYS.js} +13 -9
  8. package/dist/chunk-YKKWXHYS.js.map +1 -0
  9. package/dist/cli/index.d.ts +3 -0
  10. package/dist/cli/process.d.ts +2 -0
  11. package/dist/cli/utils.d.ts +19 -0
  12. package/dist/cli/validate.d.ts +2 -0
  13. package/dist/cli.js +3905 -3875
  14. package/dist/cli.js.map +1 -1
  15. package/dist/{cloudwatch-KSZ4A256.js → cloudwatch-3LTDYG6G.js} +6 -10
  16. package/dist/cloudwatch-3LTDYG6G.js.map +1 -0
  17. package/dist/constants.d.ts +69 -0
  18. package/dist/core/schema.d.ts +170 -1684
  19. package/dist/{core-KB2W6SE2.js → core-LFX2BFLG.js} +3 -2
  20. package/dist/{dynamodb-5KVESCVJ.js → dynamodb-HQH3IMAI.js} +6 -10
  21. package/dist/dynamodb-HQH3IMAI.js.map +1 -0
  22. package/dist/{ec2-HKPE6GZV.js → ec2-AEPT735A.js} +6 -10
  23. package/dist/ec2-AEPT735A.js.map +1 -0
  24. package/dist/{ecs-OS3NJZTA.js → ecs-UHKCH5A7.js} +6 -10
  25. package/dist/ecs-UHKCH5A7.js.map +1 -0
  26. package/dist/{elasticache-7TCRHYYM.js → elasticache-5Y6K7GKJ.js} +6 -10
  27. package/dist/elasticache-5Y6K7GKJ.js.map +1 -0
  28. package/dist/{elb-PEDLXW5R.js → elb-CN6ELVM5.js} +6 -10
  29. package/dist/elb-CN6ELVM5.js.map +1 -0
  30. package/dist/{iam-7H5HFWVQ.js → iam-YXMHK2MV.js} +6 -2
  31. package/dist/iam-YXMHK2MV.js.map +1 -0
  32. package/dist/index.d.ts +1 -1
  33. package/dist/index.js +93 -121
  34. package/dist/index.js.map +1 -1
  35. package/dist/infra/checkers/client-factory.d.ts +45 -0
  36. package/dist/infra/schemas.d.ts +41 -533
  37. package/dist/{infra-ZQRXX7AW.js → infra-RFEWGWPW.js} +20 -18
  38. package/dist/{infra-ZQRXX7AW.js.map → infra-RFEWGWPW.js.map} +1 -1
  39. package/dist/{lambda-NFB5UILT.js → lambda-YTJOCYV5.js} +6 -10
  40. package/dist/lambda-YTJOCYV5.js.map +1 -0
  41. package/dist/mcp/standards/parser.d.ts +2 -14
  42. package/dist/{mcp-WXYRFNEV.js → mcp-T2JFU4E2.js} +4 -3
  43. package/dist/{mcp-WXYRFNEV.js.map → mcp-T2JFU4E2.js.map} +1 -1
  44. package/dist/projects/tier-loader.d.ts +10 -3
  45. package/dist/projects/types.d.ts +4 -4
  46. package/dist/{rds-KLG5O5SI.js → rds-GZ5RVPIU.js} +6 -10
  47. package/dist/rds-GZ5RVPIU.js.map +1 -0
  48. package/dist/{registry-7CDIMOLZ.js → registry-J2LVW3M2.js} +3 -2
  49. package/dist/{s3-2DH7PRVR.js → s3-53UELUWT.js} +16 -12
  50. package/dist/s3-53UELUWT.js.map +1 -0
  51. package/dist/s3-S4GXNR7H.js +53 -0
  52. package/dist/s3-S4GXNR7H.js.map +1 -0
  53. package/dist/{scan-IKEHLZXV.js → scan-BZH5IR3Z.js} +4 -3
  54. package/dist/scan-BZH5IR3Z.js.map +1 -0
  55. package/dist/{secretsmanager-MOOIHLAO.js → secretsmanager-FJKTPIXI.js} +6 -10
  56. package/dist/secretsmanager-FJKTPIXI.js.map +1 -0
  57. package/dist/{sns-Y36LVTWA.js → sns-RV64OMK2.js} +6 -10
  58. package/dist/sns-RV64OMK2.js.map +1 -0
  59. package/dist/{sqs-RRS3GRHK.js → sqs-MHBW6UFC.js} +6 -10
  60. package/dist/sqs-MHBW6UFC.js.map +1 -0
  61. package/dist/{standards-RXK5G4IG.js → standards-ALMA4VIU.js} +3 -2
  62. package/dist/{sync-XV6XBLVZ.js → sync-EGJ2CSYK.js} +3 -2
  63. package/dist/sync-EGJ2CSYK.js.map +1 -0
  64. package/dist/validate/index.d.ts +1 -1
  65. package/dist/validate/tier.d.ts +3 -0
  66. package/dist/validate/types.d.ts +3 -9
  67. package/dist/{validate-DKEJICCK.js → validate-X4K2SHYT.js} +53 -84
  68. package/dist/validate-X4K2SHYT.js.map +1 -0
  69. package/package.json +10 -16
  70. package/dist/chunk-PZ2NVKI7.js.map +0 -1
  71. package/dist/chunk-RXA4FO7L.js.map +0 -1
  72. package/dist/cloudwatch-KSZ4A256.js.map +0 -1
  73. package/dist/dynamodb-5KVESCVJ.js.map +0 -1
  74. package/dist/ec2-HKPE6GZV.js.map +0 -1
  75. package/dist/ecs-OS3NJZTA.js.map +0 -1
  76. package/dist/elasticache-7TCRHYYM.js.map +0 -1
  77. package/dist/elb-PEDLXW5R.js.map +0 -1
  78. package/dist/iam-7H5HFWVQ.js.map +0 -1
  79. package/dist/lambda-NFB5UILT.js.map +0 -1
  80. package/dist/rds-KLG5O5SI.js.map +0 -1
  81. package/dist/s3-2DH7PRVR.js.map +0 -1
  82. package/dist/scan-IKEHLZXV.js.map +0 -1
  83. package/dist/secretsmanager-MOOIHLAO.js.map +0 -1
  84. package/dist/sns-Y36LVTWA.js.map +0 -1
  85. package/dist/sqs-RRS3GRHK.js.map +0 -1
  86. package/dist/sync-XV6XBLVZ.js.map +0 -1
  87. package/dist/validate-DKEJICCK.js.map +0 -1
  88. /package/dist/{core-KB2W6SE2.js.map → core-LFX2BFLG.js.map} +0 -0
  89. /package/dist/{registry-7CDIMOLZ.js.map → registry-J2LVW3M2.js.map} +0 -0
  90. /package/dist/{standards-RXK5G4IG.js.map → standards-ALMA4VIU.js.map} +0 -0
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  getProjectRoot,
27
27
  loadConfig,
28
28
  loadConfigAsync
29
- } from "./chunk-PZ2NVKI7.js";
29
+ } from "./chunk-FJZMUGYW.js";
30
30
  import {
31
31
  AccountIdSchema,
32
32
  AccountKeySchema,
@@ -71,6 +71,14 @@ import {
71
71
  validateMultiAccountManifest,
72
72
  validateStackExport
73
73
  } from "./chunk-M7G73Q6P.js";
74
+ import {
75
+ AWS_DEFAULTS,
76
+ CACHE,
77
+ CONCURRENCY,
78
+ GITHUB_API,
79
+ STANDARDS_REPO,
80
+ TIMEOUTS
81
+ } from "./chunk-RHM53NLG.js";
74
82
 
75
83
  // src/code/tools/base.ts
76
84
  import * as fs from "fs";
@@ -402,7 +410,7 @@ var CoverageRunRunner = class extends BaseToolRunner {
402
410
  const result = await execa(testCommand.cmd, testCommand.args, {
403
411
  cwd: projectRoot,
404
412
  reject: false,
405
- timeout: 10 * 60 * 1e3,
413
+ timeout: TIMEOUTS.codeToolExtended,
406
414
  env: { ...process.env, CI: "true" }
407
415
  });
408
416
  return { exitCode: result.exitCode, stderr: result.stderr, stdout: result.stdout };
@@ -903,7 +911,7 @@ var ESLintRunner = class extends BaseToolRunner {
903
911
  const result = await execa2("npx", ["eslint", ...args], {
904
912
  cwd: projectRoot,
905
913
  reject: false,
906
- timeout: 5 * 60 * 1e3
914
+ timeout: TIMEOUTS.codeTool
907
915
  });
908
916
  const violations = this.parseOutput(result.stdout, projectRoot);
909
917
  if (violations === null && result.exitCode !== 0 && result.stderr) {
@@ -987,7 +995,7 @@ var ESLintRunner = class extends BaseToolRunner {
987
995
  const result = await execa2("npx", ["eslint", "--print-config", sampleFile], {
988
996
  cwd: projectRoot,
989
997
  reject: false,
990
- timeout: 30 * 1e3
998
+ timeout: TIMEOUTS.quick
991
999
  });
992
1000
  if (result.exitCode !== 0) {
993
1001
  return { error: `Failed to read ESLint config: ${result.stderr || "Unknown error"}` };
@@ -1311,7 +1319,7 @@ var GitleaksRunner = class extends BaseToolRunner {
1311
1319
  const result = await execa3("gitleaks", args, {
1312
1320
  cwd: projectRoot,
1313
1321
  reject: false,
1314
- timeout: 5 * 60 * 1e3
1322
+ timeout: TIMEOUTS.codeTool
1315
1323
  });
1316
1324
  return this.processResult(result, elapsed);
1317
1325
  } catch (error) {
@@ -1391,7 +1399,7 @@ var GitleaksRunner = class extends BaseToolRunner {
1391
1399
  await execa3("gitleaks", ["version"], {
1392
1400
  cwd: projectRoot,
1393
1401
  reject: true,
1394
- timeout: 10 * 1e3
1402
+ timeout: TIMEOUTS.versionCheck
1395
1403
  });
1396
1404
  return this.pass(Date.now() - startTime);
1397
1405
  } catch (error) {
@@ -1428,7 +1436,7 @@ var KnipRunner = class extends BaseToolRunner {
1428
1436
  const result = await execa4("npx", ["knip", "--reporter", "json"], {
1429
1437
  cwd: projectRoot,
1430
1438
  reject: false,
1431
- timeout: 5 * 60 * 1e3
1439
+ timeout: TIMEOUTS.codeTool
1432
1440
  });
1433
1441
  const output = result.stdout || result.stderr;
1434
1442
  const violations = this.parseOutput(output, projectRoot);
@@ -1890,13 +1898,13 @@ var PipAuditRunner = class extends BaseToolRunner {
1890
1898
  return await execa5("uvx", args, {
1891
1899
  cwd: projectRoot,
1892
1900
  reject: false,
1893
- timeout: 5 * 60 * 1e3
1901
+ timeout: TIMEOUTS.codeTool
1894
1902
  });
1895
1903
  } catch {
1896
1904
  return await execa5("pip-audit", args.slice(1), {
1897
1905
  cwd: projectRoot,
1898
1906
  reject: false,
1899
- timeout: 5 * 60 * 1e3
1907
+ timeout: TIMEOUTS.codeTool
1900
1908
  });
1901
1909
  }
1902
1910
  }
@@ -2013,7 +2021,7 @@ var PnpmAuditRunner = class extends BaseToolRunner {
2013
2021
  const result = await execa6("pnpm", args, {
2014
2022
  cwd: projectRoot,
2015
2023
  reject: false,
2016
- timeout: 5 * 60 * 1e3
2024
+ timeout: TIMEOUTS.codeTool
2017
2025
  });
2018
2026
  return this.processAuditResult(result, elapsed);
2019
2027
  } catch (error) {
@@ -2191,7 +2199,7 @@ var RuffRunner = class extends BaseToolRunner {
2191
2199
  const result = await execa7("ruff", this.buildCliArgs(), {
2192
2200
  cwd: projectRoot,
2193
2201
  reject: false,
2194
- timeout: 5 * 60 * 1e3
2202
+ timeout: TIMEOUTS.codeTool
2195
2203
  });
2196
2204
  if (this.isBinaryNotFound(result)) {
2197
2205
  return this.skipNotInstalled(Date.now() - startTime);
@@ -2357,7 +2365,7 @@ var TscRunner = class extends BaseToolRunner {
2357
2365
  return execa8("npx", ["tsc", "--noEmit"], {
2358
2366
  cwd: projectRoot,
2359
2367
  reject: false,
2360
- timeout: 5 * 60 * 1e3
2368
+ timeout: TIMEOUTS.codeTool
2361
2369
  });
2362
2370
  }
2363
2371
  processRunResult(result, projectRoot, elapsed) {
@@ -2588,7 +2596,7 @@ var TyRunner = class extends BaseToolRunner {
2588
2596
  const result = await execa9("uvx", ["ty", "check", "--output-format", "concise", "."], {
2589
2597
  cwd: projectRoot,
2590
2598
  reject: false,
2591
- timeout: 5 * 60 * 1e3
2599
+ timeout: TIMEOUTS.codeTool
2592
2600
  });
2593
2601
  return this.handleExitCode(result, projectRoot, elapsed);
2594
2602
  } catch (error) {
@@ -2737,7 +2745,7 @@ var VultureRunner = class _VultureRunner extends BaseToolRunner {
2737
2745
  const result = await execa10("vulture", [".", "--exclude", excludePatterns], {
2738
2746
  cwd: projectRoot,
2739
2747
  reject: false,
2740
- timeout: 5 * 60 * 1e3
2748
+ timeout: TIMEOUTS.codeTool
2741
2749
  });
2742
2750
  if (this.isBinaryNotFound(result)) {
2743
2751
  return this.skipNotInstalled(Date.now() - startTime);
@@ -3151,7 +3159,7 @@ var BackupsRunner = class extends BaseProcessToolRunner {
3151
3159
  }
3152
3160
  getS3Client() {
3153
3161
  return this.s3Client ?? new S3Client({
3154
- region: this.config.region ?? process.env.AWS_REGION ?? "us-east-1"
3162
+ region: this.config.region ?? process.env.AWS_REGION ?? AWS_DEFAULTS.globalRegion
3155
3163
  });
3156
3164
  }
3157
3165
  createExistsViolation() {
@@ -5246,7 +5254,7 @@ var PrRunner = class extends BaseProcessToolRunner {
5246
5254
  /** Fetch a single page of PR files from GitHub API */
5247
5255
  async fetchPrFilesPage(repo, prNumber, page, token) {
5248
5256
  const response = await fetch(
5249
- `https://api.github.com/repos/${repo}/pulls/${prNumber}/files?per_page=100&page=${page}`,
5257
+ `${GITHUB_API.baseUrl}/repos/${repo}/pulls/${prNumber}/files?per_page=${GITHUB_API.perPage}&page=${page}`,
5250
5258
  {
5251
5259
  headers: {
5252
5260
  Authorization: `Bearer ${token}`,
@@ -5577,7 +5585,6 @@ var RepoRunner = class extends BaseProcessToolRunner {
5577
5585
  violations.push(...this.checkBypassActorsSettings(ruleset, bpConfig, branch));
5578
5586
  return violations;
5579
5587
  }
5580
- // eslint-disable-next-line complexity
5581
5588
  checkPullRequestRuleSettings(prRule, bpConfig, branch) {
5582
5589
  const violations = [];
5583
5590
  const params = prRule?.parameters;
@@ -5614,7 +5621,6 @@ var RepoRunner = class extends BaseProcessToolRunner {
5614
5621
  }
5615
5622
  return violations;
5616
5623
  }
5617
- // eslint-disable-next-line complexity
5618
5624
  checkStatusChecksRuleSettings(statusRule, bpConfig, branch) {
5619
5625
  const violations = [];
5620
5626
  const params = statusRule?.parameters;
@@ -6657,7 +6663,7 @@ async function scanRepository(repo, config) {
6657
6663
  return aggregateResults(repoInfo, [rulesetsResult, filesResult]);
6658
6664
  }
6659
6665
  async function validateProcess(options) {
6660
- const { loadConfigAsync: loadConfigAsync2 } = await import("./core-KB2W6SE2.js");
6666
+ const { loadConfigAsync: loadConfigAsync2 } = await import("./core-LFX2BFLG.js");
6661
6667
  const { config } = await loadConfigAsync2(options.config);
6662
6668
  const result = await scanRepository(options.repo, config);
6663
6669
  const fs22 = await import("fs");
@@ -6968,9 +6974,7 @@ import * as fs18 from "fs";
6968
6974
  import * as os from "os";
6969
6975
  import * as path17 from "path";
6970
6976
  import { execa as execa19 } from "execa";
6971
- var DEFAULT_OWNER = "palindrom-ai";
6972
- var DEFAULT_REPO = "standards";
6973
- var CACHE_DIR = path17.join(os.tmpdir(), "cm-standards-cache");
6977
+ var CACHE_DIR = path17.join(os.tmpdir(), CACHE.standardsCacheDir);
6974
6978
  function parseGitHubSource(source) {
6975
6979
  const remainder = source.slice(7);
6976
6980
  const atIndex = remainder.indexOf("@");
@@ -7029,7 +7033,7 @@ function buildGitHubUrl(auth, owner, repo) {
7029
7033
  }
7030
7034
  async function updateExistingRepo(repoDir) {
7031
7035
  try {
7032
- await execa19("git", ["pull", "--ff-only"], { cwd: repoDir, timeout: 3e4 });
7036
+ await execa19("git", ["pull", "--ff-only"], { cwd: repoDir, timeout: TIMEOUTS.git });
7033
7037
  return true;
7034
7038
  } catch {
7035
7039
  fs18.rmSync(repoDir, { recursive: true, force: true });
@@ -7047,12 +7051,12 @@ async function cloneRepo(repoDir, owner, repo, ref) {
7047
7051
  }
7048
7052
  args.push(url, repoDir);
7049
7053
  await execa19("git", args, {
7050
- timeout: 3e4
7054
+ timeout: TIMEOUTS.git
7051
7055
  });
7052
7056
  } catch (error) {
7053
7057
  const message = error instanceof Error ? error.message : String(error);
7054
7058
  if (message.includes("timed out")) {
7055
- throw new StandardsError(`Standards repo clone timed out after 30 seconds`);
7059
+ throw new StandardsError(`Standards repo clone timed out after ${TIMEOUTS.git / 1e3} seconds`);
7056
7060
  }
7057
7061
  throw new StandardsError(`Failed to clone standards repo: ${message}`);
7058
7062
  }
@@ -7087,7 +7091,7 @@ async function fetchStandardsRepoFromSource(source, basePath) {
7087
7091
  return fetchGitHubRepo(parsed.owner, parsed.repo, parsed.ref);
7088
7092
  }
7089
7093
  async function fetchStandardsRepo() {
7090
- return fetchGitHubRepo(DEFAULT_OWNER, DEFAULT_REPO);
7094
+ return fetchGitHubRepo(STANDARDS_REPO.owner, STANDARDS_REPO.repo);
7091
7095
  }
7092
7096
  function getGuidelinesDir(repoPath) {
7093
7097
  return path17.join(repoPath, "guidelines");
@@ -7112,7 +7116,7 @@ function parseGuideline(fileContent, filename) {
7112
7116
  const { data, content } = matter2(fileContent);
7113
7117
  const result = frontmatterSchema.safeParse(data);
7114
7118
  if (!result.success) {
7115
- const errors = result.error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
7119
+ const errors = result.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
7116
7120
  throw new StandardsError(`Invalid frontmatter in ${filename}: ${errors}`);
7117
7121
  }
7118
7122
  return {
@@ -7224,63 +7228,16 @@ ${guideline.content}`;
7224
7228
  }
7225
7229
 
7226
7230
  // src/validate/tier.ts
7227
- import { execSync } from "child_process";
7228
7231
  import * as fs21 from "fs";
7229
7232
  import * as path20 from "path";
7230
7233
  import TOML from "@iarna/toml";
7231
7234
  import chalk4 from "chalk";
7232
- import * as yaml3 from "js-yaml";
7233
7235
 
7234
7236
  // src/validate/types.ts
7235
7237
  var VALID_TIERS = ["production", "internal", "prototype"];
7236
7238
 
7237
7239
  // src/validate/tier.ts
7238
7240
  var DEFAULT_TIER = "internal";
7239
- function findGitRoot(startDir) {
7240
- try {
7241
- const gitRoot = execSync("git rev-parse --show-toplevel", {
7242
- cwd: startDir,
7243
- encoding: "utf-8",
7244
- stdio: ["pipe", "pipe", "pipe"]
7245
- }).trim();
7246
- return gitRoot;
7247
- } catch {
7248
- return null;
7249
- }
7250
- }
7251
- function readFileContent2(filePath) {
7252
- if (!fs21.existsSync(filePath)) {
7253
- return null;
7254
- }
7255
- try {
7256
- return fs21.readFileSync(filePath, "utf-8");
7257
- } catch {
7258
- return null;
7259
- }
7260
- }
7261
- function parseYamlContent(content) {
7262
- try {
7263
- const parsed = yaml3.load(content);
7264
- if (parsed === void 0 || parsed === null) {
7265
- return { metadata: null, sourceDetail: "default (file empty)" };
7266
- }
7267
- return { metadata: parsed, sourceDetail: "repo-metadata.yaml" };
7268
- } catch (error) {
7269
- const parseError = error instanceof Error ? error.message : String(error);
7270
- return { metadata: null, sourceDetail: "default (parse error)", parseError };
7271
- }
7272
- }
7273
- function loadRepoMetadata(projectRoot) {
7274
- const metadataPath = path20.join(projectRoot, "repo-metadata.yaml");
7275
- const content = readFileContent2(metadataPath);
7276
- if (content === null) {
7277
- return { metadata: null, sourceDetail: "default (file not found)" };
7278
- }
7279
- if (!content.trim()) {
7280
- return { metadata: null, sourceDetail: "default (file empty)" };
7281
- }
7282
- return parseYamlContent(content);
7283
- }
7284
7241
  function loadExtendsConfig(configPath) {
7285
7242
  try {
7286
7243
  const content = fs21.readFileSync(configPath, "utf-8");
@@ -7290,24 +7247,48 @@ function loadExtendsConfig(configPath) {
7290
7247
  return null;
7291
7248
  }
7292
7249
  }
7293
- function getTier(metadataResult) {
7294
- const { metadata, sourceDetail } = metadataResult;
7295
- if (!metadata) {
7296
- return { tier: DEFAULT_TIER, source: "default", sourceDetail };
7297
- }
7298
- if (metadata.tier === void 0) {
7299
- return { tier: DEFAULT_TIER, source: "default", sourceDetail: "default (tier not specified)" };
7250
+ function loadTierFromStandardsToml(configPath) {
7251
+ if (!fs21.existsSync(configPath)) {
7252
+ return {
7253
+ tier: DEFAULT_TIER,
7254
+ source: "default",
7255
+ sourceDetail: "default (file not found)"
7256
+ };
7300
7257
  }
7301
- const tier = metadata.tier;
7302
- if (!VALID_TIERS.includes(tier)) {
7258
+ try {
7259
+ const content = fs21.readFileSync(configPath, "utf-8");
7260
+ const parsed = TOML.parse(content);
7261
+ if (!parsed.metadata) {
7262
+ return {
7263
+ tier: DEFAULT_TIER,
7264
+ source: "default",
7265
+ sourceDetail: "default (no metadata)"
7266
+ };
7267
+ }
7268
+ if (parsed.metadata.tier === void 0) {
7269
+ return {
7270
+ tier: DEFAULT_TIER,
7271
+ source: "default",
7272
+ sourceDetail: "default (tier not specified)"
7273
+ };
7274
+ }
7275
+ const tier = parsed.metadata.tier;
7276
+ if (!VALID_TIERS.includes(tier)) {
7277
+ return {
7278
+ tier: DEFAULT_TIER,
7279
+ source: "default",
7280
+ sourceDetail: "default (invalid value)",
7281
+ invalidValue: String(tier)
7282
+ };
7283
+ }
7284
+ return { tier, source: "standards.toml", sourceDetail: "standards.toml" };
7285
+ } catch {
7303
7286
  return {
7304
7287
  tier: DEFAULT_TIER,
7305
7288
  source: "default",
7306
- sourceDetail: "default (invalid value)",
7307
- invalidValue: String(tier)
7289
+ sourceDetail: "default (file not found)"
7308
7290
  };
7309
7291
  }
7310
- return { tier, source: "repo-metadata.yaml", sourceDetail: "repo-metadata.yaml" };
7311
7292
  }
7312
7293
  function findMatchingRulesets(rulesets, tier) {
7313
7294
  const suffix = `-${tier}`;
@@ -7325,6 +7306,7 @@ function createNotFoundResult() {
7325
7306
  valid: false,
7326
7307
  tier: DEFAULT_TIER,
7327
7308
  tierSource: "default",
7309
+ tierSourceDetail: "default (file not found)",
7328
7310
  rulesets: [],
7329
7311
  expectedPattern: `*-${DEFAULT_TIER}`,
7330
7312
  matchedRulesets: [],
@@ -7340,20 +7322,16 @@ function buildResult(options) {
7340
7322
  matchedRulesets,
7341
7323
  invalidTierValue,
7342
7324
  hasEmptyRulesets,
7343
- registryUrl,
7344
- parseError
7325
+ registryUrl
7345
7326
  } = options;
7346
7327
  const warnings = options.warnings ?? [];
7347
7328
  const expectedPattern = `*-${tier}`;
7348
7329
  const valid = rulesets.length === 0 || matchedRulesets.length > 0;
7349
7330
  if (invalidTierValue) {
7350
7331
  warnings.push(
7351
- `Invalid tier '${invalidTierValue}' in repo-metadata.yaml. Valid values are: ${VALID_TIERS.join(", ")}`
7332
+ `Invalid tier '${invalidTierValue}' in standards.toml [metadata]. Valid values are: ${VALID_TIERS.join(", ")}`
7352
7333
  );
7353
7334
  }
7354
- if (parseError) {
7355
- warnings.push(`Failed to parse repo-metadata.yaml: ${parseError}`);
7356
- }
7357
7335
  if (hasEmptyRulesets && registryUrl) {
7358
7336
  warnings.push(
7359
7337
  `[extends] is configured with registry '${registryUrl}' but rulesets is empty - no standards will be inherited`
@@ -7379,26 +7357,21 @@ function validateTierRuleset(options = {}) {
7379
7357
  if (!configPath) {
7380
7358
  return createNotFoundResult();
7381
7359
  }
7382
- const configDir = getProjectRoot(configPath);
7383
- const gitRoot = findGitRoot(configDir);
7384
- const metadataSearchPath = gitRoot ?? configDir;
7385
- const metadataResult = loadRepoMetadata(metadataSearchPath);
7386
- const { tier, source, sourceDetail, invalidValue } = getTier(metadataResult);
7360
+ const tierResult = loadTierFromStandardsToml(configPath);
7387
7361
  const extendsConfig = loadExtendsConfig(configPath);
7388
7362
  const rulesets = extendsConfig?.rulesets ?? [];
7389
- const matchedRulesets = rulesets.length > 0 ? findMatchingRulesets(rulesets, tier) : [];
7363
+ const matchedRulesets = rulesets.length > 0 ? findMatchingRulesets(rulesets, tierResult.tier) : [];
7390
7364
  const hasEmptyRulesets = extendsConfig !== null && rulesets.length === 0;
7391
7365
  const registryUrl = extendsConfig?.registry;
7392
7366
  return buildResult({
7393
- tier,
7394
- source,
7395
- sourceDetail,
7367
+ tier: tierResult.tier,
7368
+ source: tierResult.source,
7369
+ sourceDetail: tierResult.sourceDetail,
7396
7370
  rulesets,
7397
7371
  matchedRulesets,
7398
- invalidTierValue: invalidValue,
7372
+ invalidTierValue: tierResult.invalidValue,
7399
7373
  hasEmptyRulesets,
7400
- registryUrl,
7401
- parseError: metadataResult.parseError
7374
+ registryUrl
7402
7375
  });
7403
7376
  }
7404
7377
  function formatWarnings(warnings) {
@@ -7432,7 +7405,7 @@ function formatFailedValidation(result, sourceDisplay) {
7432
7405
  lines.push("");
7433
7406
  lines.push(
7434
7407
  chalk4.cyan(
7435
- ` Hint: Update repo-metadata.yaml to use a valid tier value: ${VALID_TIERS.join(", ")}`
7408
+ ` Hint: Update standards.toml [metadata].tier to use a valid value: ${VALID_TIERS.join(", ")}`
7436
7409
  )
7437
7410
  );
7438
7411
  }
@@ -7663,19 +7636,19 @@ function isSupportedService(service) {
7663
7636
  return SUPPORTED_SERVICES.includes(service);
7664
7637
  }
7665
7638
  var checkerFactories = {
7666
- s3: async () => (await import("./s3-2DH7PRVR.js")).S3Checker,
7667
- lambda: async () => (await import("./lambda-NFB5UILT.js")).LambdaChecker,
7668
- dynamodb: async () => (await import("./dynamodb-5KVESCVJ.js")).DynamoDBChecker,
7669
- sqs: async () => (await import("./sqs-RRS3GRHK.js")).SQSChecker,
7670
- sns: async () => (await import("./sns-Y36LVTWA.js")).SNSChecker,
7671
- iam: async () => (await import("./iam-7H5HFWVQ.js")).IAMChecker,
7672
- secretsmanager: async () => (await import("./secretsmanager-MOOIHLAO.js")).SecretsManagerChecker,
7673
- logs: async () => (await import("./cloudwatch-KSZ4A256.js")).CloudWatchLogsChecker,
7674
- ecs: async () => (await import("./ecs-OS3NJZTA.js")).ECSChecker,
7675
- rds: async () => (await import("./rds-KLG5O5SI.js")).RDSChecker,
7676
- ec2: async () => (await import("./ec2-HKPE6GZV.js")).EC2Checker,
7677
- elasticache: async () => (await import("./elasticache-7TCRHYYM.js")).ElastiCacheChecker,
7678
- elasticloadbalancing: async () => (await import("./elb-PEDLXW5R.js")).ELBChecker
7639
+ s3: async () => (await import("./s3-53UELUWT.js")).S3Checker,
7640
+ lambda: async () => (await import("./lambda-YTJOCYV5.js")).LambdaChecker,
7641
+ dynamodb: async () => (await import("./dynamodb-HQH3IMAI.js")).DynamoDBChecker,
7642
+ sqs: async () => (await import("./sqs-MHBW6UFC.js")).SQSChecker,
7643
+ sns: async () => (await import("./sns-RV64OMK2.js")).SNSChecker,
7644
+ iam: async () => (await import("./iam-YXMHK2MV.js")).IAMChecker,
7645
+ secretsmanager: async () => (await import("./secretsmanager-FJKTPIXI.js")).SecretsManagerChecker,
7646
+ logs: async () => (await import("./cloudwatch-3LTDYG6G.js")).CloudWatchLogsChecker,
7647
+ ecs: async () => (await import("./ecs-UHKCH5A7.js")).ECSChecker,
7648
+ rds: async () => (await import("./rds-GZ5RVPIU.js")).RDSChecker,
7649
+ ec2: async () => (await import("./ec2-AEPT735A.js")).EC2Checker,
7650
+ elasticache: async () => (await import("./elasticache-5Y6K7GKJ.js")).ElastiCacheChecker,
7651
+ elasticloadbalancing: async () => (await import("./elb-CN6ELVM5.js")).ELBChecker
7679
7652
  };
7680
7653
  var checkerCache = /* @__PURE__ */ new Map();
7681
7654
  async function getChecker(service) {
@@ -7719,9 +7692,8 @@ async function getGcpChecker(service) {
7719
7692
  }
7720
7693
 
7721
7694
  // src/infra/scan.ts
7722
- var DEFAULT_CONCURRENCY = 10;
7723
7695
  async function scanManifest(manifest, manifestPath, options = {}) {
7724
- const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
7696
+ const concurrency = options.concurrency ?? CONCURRENCY.infraScan;
7725
7697
  if (isMultiAccountManifest(manifest)) {
7726
7698
  return scanMultiAccountManifest(manifest, manifestPath, options);
7727
7699
  }
@@ -7736,7 +7708,7 @@ async function scanManifest(manifest, manifestPath, options = {}) {
7736
7708
  };
7737
7709
  }
7738
7710
  async function scanMultiAccountManifest(manifest, manifestPath, options = {}) {
7739
- const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
7711
+ const concurrency = options.concurrency ?? CONCURRENCY.infraScan;
7740
7712
  const accountResults = {};
7741
7713
  const allResults = [];
7742
7714
  const accountsToScan = filterAccounts(manifest, options.account);