@biffo/cli 0.283.4 → 0.284.1

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/dist/index.js CHANGED
@@ -10782,14 +10782,160 @@ async function runBranchProtectionCheck(explicitRepo, options = {}) {
10782
10782
  console.log(`\u2713 branch-protection guard: ${owner}/${repo} (${audited.join(", ")}) OK`);
10783
10783
  }
10784
10784
 
10785
- // src/scripts/check-codeql-suppression.ts
10786
- import { existsSync as existsSync39 } from "fs";
10787
- import { join as join41, relative as relative8 } from "path";
10785
+ // src/scripts/check-claim-invocation.ts
10788
10786
  import { execa as execa10 } from "execa";
10789
10787
 
10790
- // src/lib/codeql-suppression-guard.ts
10791
- import { readdirSync as readdirSync16, readFileSync as readFileSync29, statSync as statSync9 } from "fs";
10788
+ // src/lib/claim-invocation-parity.ts
10789
+ import { existsSync as existsSync39, readFileSync as readFileSync29, readdirSync as readdirSync16 } from "fs";
10792
10790
  import { join as join40 } from "path";
10791
+ function distributedAgentsDocs(root) {
10792
+ const docs = [];
10793
+ const own = join40(root, "AGENTS.md");
10794
+ if (existsSync39(own)) docs.push({ path: "AGENTS.md", text: readFileSync29(own, "utf8") });
10795
+ const skeletons = join40(root, "_skeletons");
10796
+ if (existsSync39(skeletons)) {
10797
+ for (const name of readdirSync16(skeletons).sort()) {
10798
+ const abs = join40(skeletons, name, "AGENTS.md");
10799
+ if (!existsSync39(abs)) continue;
10800
+ docs.push({ path: `_skeletons/${name}/AGENTS.md`, text: readFileSync29(abs, "utf8") });
10801
+ }
10802
+ }
10803
+ return docs;
10804
+ }
10805
+ function isClaimInvocation(line) {
10806
+ return /\b(?:biffo\.sh|claim\.sh)\s+claim\b|\bclaim\.sh\s+\d|\bclaim\s+<issue-number>/.test(line);
10807
+ }
10808
+ function claimBlock(text) {
10809
+ const lines = text.split("\n");
10810
+ const out = [];
10811
+ let fenced = false;
10812
+ for (const raw of lines) {
10813
+ if (/^\s*```/.test(raw)) {
10814
+ fenced = !fenced;
10815
+ continue;
10816
+ }
10817
+ if (!fenced) continue;
10818
+ if (isClaimInvocation(raw)) out.push(raw.trimEnd());
10819
+ }
10820
+ return out;
10821
+ }
10822
+ function claimInvocations(text) {
10823
+ const found = [];
10824
+ let fenced = false;
10825
+ for (const raw of text.split("\n")) {
10826
+ if (/^\s*```/.test(raw)) {
10827
+ fenced = !fenced;
10828
+ continue;
10829
+ }
10830
+ if (fenced) {
10831
+ if (isClaimInvocation(raw)) found.push(raw.trimEnd());
10832
+ continue;
10833
+ }
10834
+ for (const match of raw.matchAll(/`([^`]+)`/g)) {
10835
+ const span = match[1];
10836
+ if (span !== void 0 && isClaimInvocation(span)) found.push(span.trim());
10837
+ }
10838
+ }
10839
+ return found;
10840
+ }
10841
+ function isTokened(invocation) {
10842
+ return /--as\b|--release\b|--guard\b/.test(invocation);
10843
+ }
10844
+ function auditClaimInvocationParity(docs) {
10845
+ const violations = [];
10846
+ if (docs.length === 0) {
10847
+ return [
10848
+ {
10849
+ rule: "no-copies",
10850
+ path: "(none)",
10851
+ detail: "no distributed AGENTS.md found \u2014 a guard with an empty input set passes against anything"
10852
+ }
10853
+ ];
10854
+ }
10855
+ const [canonical, ...rest] = docs;
10856
+ const canonicalBlock = claimBlock(canonical.text);
10857
+ if (canonicalBlock.length === 0) {
10858
+ violations.push({
10859
+ rule: "missing-form",
10860
+ path: canonical.path,
10861
+ detail: "documents no claim invocation at all"
10862
+ });
10863
+ }
10864
+ for (const doc of rest) {
10865
+ const block = claimBlock(doc.text);
10866
+ if (block.join("\n") !== canonicalBlock.join("\n")) {
10867
+ violations.push({
10868
+ rule: "block-drift",
10869
+ path: doc.path,
10870
+ detail: `claim block differs from ${canonical.path}
10871
+ ${canonical.path}:
10872
+ ${canonicalBlock.map((l) => ` ${l}`).join("\n")}
10873
+ ${doc.path}:
10874
+ ${block.map((l) => ` ${l}`).join("\n")}`
10875
+ });
10876
+ }
10877
+ }
10878
+ for (const doc of docs) {
10879
+ const invocations = claimInvocations(doc.text);
10880
+ for (const invocation of invocations) {
10881
+ if (!isTokened(invocation)) {
10882
+ violations.push({
10883
+ rule: "untokened-form",
10884
+ path: doc.path,
10885
+ detail: `documents a claim with no --as token: ${invocation.trim()}`
10886
+ });
10887
+ }
10888
+ }
10889
+ if (!invocations.some((i) => /--as\b/.test(i))) {
10890
+ violations.push({
10891
+ rule: "missing-form",
10892
+ path: doc.path,
10893
+ detail: "never documents `claim <issue-number> --as <token>`"
10894
+ });
10895
+ }
10896
+ if (!invocations.some((i) => /--release\b/.test(i))) {
10897
+ violations.push({
10898
+ rule: "missing-form",
10899
+ path: doc.path,
10900
+ detail: "never documents `claim <issue-number> --release <token>`"
10901
+ });
10902
+ }
10903
+ }
10904
+ return violations;
10905
+ }
10906
+ function formatParityViolations(violations) {
10907
+ return violations.map((v) => ` [${v.rule}] ${v.path}: ${v.detail}`).join("\n");
10908
+ }
10909
+
10910
+ // src/scripts/check-claim-invocation.ts
10911
+ async function runClaimInvocationCheck() {
10912
+ const root = (await execa10("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
10913
+ const docs = distributedAgentsDocs(root);
10914
+ console.log(
10915
+ `audited ${docs.length} distributed AGENTS.md (${docs.map((d) => d.path).join(", ") || "none"}) under ${root}`
10916
+ );
10917
+ const violations = auditClaimInvocationParity(docs);
10918
+ if (violations.length > 0) {
10919
+ console.error("\u2717 Claim-invocation guard: the distributed AGENTS.md copies disagree\n");
10920
+ console.error(formatParityViolations(violations));
10921
+ console.error(
10922
+ "\nEvery copy must document the same invocation, and `--as <token>` is mandatory (#1562). Fix the skeletons too \u2014 they are what satellites receive."
10923
+ );
10924
+ process.exit(1);
10925
+ }
10926
+ console.log(
10927
+ "\u2713 Claim-invocation guard: every distributed AGENTS.md documents the same, tokened, claim"
10928
+ );
10929
+ }
10930
+
10931
+ // src/scripts/check-codeql-suppression.ts
10932
+ import { existsSync as existsSync40 } from "fs";
10933
+ import { join as join42, relative as relative8 } from "path";
10934
+ import { execa as execa11 } from "execa";
10935
+
10936
+ // src/lib/codeql-suppression-guard.ts
10937
+ import { readdirSync as readdirSync17, readFileSync as readFileSync30, statSync as statSync9 } from "fs";
10938
+ import { join as join41 } from "path";
10793
10939
  var SKIP_DIRS = /* @__PURE__ */ new Set([
10794
10940
  ".git",
10795
10941
  ".worktrees",
@@ -10815,12 +10961,12 @@ function walkSourceFiles(root) {
10815
10961
  const walk2 = (dir) => {
10816
10962
  let entries;
10817
10963
  try {
10818
- entries = readdirSync16(dir);
10964
+ entries = readdirSync17(dir);
10819
10965
  } catch {
10820
10966
  return;
10821
10967
  }
10822
10968
  for (const entry of entries) {
10823
- const p = join40(dir, entry);
10969
+ const p = join41(dir, entry);
10824
10970
  let st;
10825
10971
  try {
10826
10972
  st = statSync9(p);
@@ -10846,7 +10992,7 @@ function countSourceFiles(root) {
10846
10992
  function sweepCodeqlSuppressionComments(root) {
10847
10993
  const hits = [];
10848
10994
  for (const path of walkSourceFiles(root)) {
10849
- const text = readFileSync29(path, "utf8");
10995
+ const text = readFileSync30(path, "utf8");
10850
10996
  for (const line of findCodeqlSuppressionComments(text)) {
10851
10997
  hits.push({ path, line, text: text.split("\n")[line - 1] ?? "" });
10852
10998
  }
@@ -10856,9 +11002,9 @@ function sweepCodeqlSuppressionComments(root) {
10856
11002
 
10857
11003
  // src/scripts/check-codeql-suppression.ts
10858
11004
  async function runCodeqlSuppressionCheck() {
10859
- const root = (await execa10("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
10860
- const scanRoot = join41(root, "cli", "src");
10861
- if (!existsSync39(scanRoot)) {
11005
+ const root = (await execa11("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
11006
+ const scanRoot = join42(root, "cli", "src");
11007
+ if (!existsSync40(scanRoot)) {
10862
11008
  console.log(
10863
11009
  "\u2014 codeql-suppression guard: skipped \u2014 no cli/src in this repo, so there is no CLI source to scan."
10864
11010
  );
@@ -10882,11 +11028,11 @@ async function runCodeqlSuppressionCheck() {
10882
11028
  }
10883
11029
 
10884
11030
  // src/scripts/check-cognito-invite-template.ts
10885
- import { execa as execa11 } from "execa";
11031
+ import { execa as execa12 } from "execa";
10886
11032
 
10887
11033
  // src/lib/cognito-invite-template-guard.ts
10888
- import { readdirSync as readdirSync17, readFileSync as readFileSync30, statSync as statSync10 } from "fs";
10889
- import { join as join42 } from "path";
11034
+ import { readdirSync as readdirSync18, readFileSync as readFileSync31, statSync as statSync10 } from "fs";
11035
+ import { join as join43 } from "path";
10890
11036
  var REQUIRED_INVITE_MEMBERS = ["email_subject", "email_message", "sms_message"];
10891
11037
  var REQUIRED_INVITE_PLACEHOLDERS = ["{username}", "{####}"];
10892
11038
  var PLACEHOLDER_MEMBERS = ["email_message", "sms_message"];
@@ -10963,13 +11109,13 @@ function findModuleTerraformFiles(repoRoot) {
10963
11109
  const walk2 = (dir, relative11) => {
10964
11110
  let entries;
10965
11111
  try {
10966
- entries = readdirSync17(dir);
11112
+ entries = readdirSync18(dir);
10967
11113
  } catch {
10968
11114
  return;
10969
11115
  }
10970
11116
  for (const entry of entries) {
10971
11117
  if (entry === "node_modules" || entry === ".git" || entry === ".worktrees") continue;
10972
- const full = join42(dir, entry);
11118
+ const full = join43(dir, entry);
10973
11119
  const rel = `${relative11}/${entry}`;
10974
11120
  if (statSync10(full).isDirectory()) {
10975
11121
  walk2(full, rel);
@@ -10978,18 +11124,18 @@ function findModuleTerraformFiles(repoRoot) {
10978
11124
  }
10979
11125
  }
10980
11126
  };
10981
- walk2(join42(repoRoot, "modules"), "modules");
11127
+ walk2(join43(repoRoot, "modules"), "modules");
10982
11128
  return found.sort();
10983
11129
  }
10984
11130
  function checkCognitoInviteTemplates(repoRoot) {
10985
11131
  return findModuleTerraformFiles(repoRoot).flatMap(
10986
- (file) => checkInviteTemplateSource(file, readFileSync30(join42(repoRoot, file), "utf8"))
11132
+ (file) => checkInviteTemplateSource(file, readFileSync31(join43(repoRoot, file), "utf8"))
10987
11133
  );
10988
11134
  }
10989
11135
 
10990
11136
  // src/scripts/check-cognito-invite-template.ts
10991
11137
  async function runCognitoInviteTemplateCheck() {
10992
- const root = (await execa11("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
11138
+ const root = (await execa12("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
10993
11139
  const files = findModuleTerraformFiles(root);
10994
11140
  console.log(`audited ${files.length} .tf file(s) under modules/ under ${root}`);
10995
11141
  if (files.length === 0) {
@@ -11011,12 +11157,12 @@ async function runCognitoInviteTemplateCheck() {
11011
11157
  }
11012
11158
 
11013
11159
  // src/scripts/check-core-direct-paths.ts
11014
- import { join as join44 } from "path";
11015
- import { execa as execa12 } from "execa";
11160
+ import { join as join45 } from "path";
11161
+ import { execa as execa13 } from "execa";
11016
11162
 
11017
11163
  // src/lib/core-direct-paths-audit.ts
11018
- import { existsSync as existsSync40, readFileSync as readFileSync31, readdirSync as readdirSync18, statSync as statSync11 } from "fs";
11019
- import { join as join43 } from "path";
11164
+ import { existsSync as existsSync41, readFileSync as readFileSync32, readdirSync as readdirSync19, statSync as statSync11 } from "fs";
11165
+ import { join as join44 } from "path";
11020
11166
  var EXTERNAL_BASE_IDENTIFIERS = ["CORE_API_URL"];
11021
11167
  var API_ROUTE_PREFIX = "/api/v1";
11022
11168
  var TEST_FILE_SUFFIXES = [".test.ts", ".test.tsx", ".spec.ts", ".spec.tsx"];
@@ -11175,12 +11321,12 @@ function walkFiles(root, accept, skipDir) {
11175
11321
  const walk2 = (dir) => {
11176
11322
  let entries;
11177
11323
  try {
11178
- entries = readdirSync18(dir);
11324
+ entries = readdirSync19(dir);
11179
11325
  } catch {
11180
11326
  return;
11181
11327
  }
11182
11328
  for (const entry of entries) {
11183
- const p = join43(dir, entry);
11329
+ const p = join44(dir, entry);
11184
11330
  let st;
11185
11331
  try {
11186
11332
  st = statSync11(p);
@@ -11210,7 +11356,7 @@ function auditFrontendExtraction(frontendSrcDir, externalBases = EXTERNAL_BASE_I
11210
11356
  const extracted = [];
11211
11357
  let rawTotal = 0;
11212
11358
  for (const file of files) {
11213
- const text = readFileSync31(file, "utf8");
11359
+ const text = readFileSync32(file, "utf8");
11214
11360
  rawTotal += countRawExternalOccurrences(text, externalBases);
11215
11361
  extracted.push(...extractCoreDirectPaths(text, file, externalBases));
11216
11362
  }
@@ -11259,7 +11405,7 @@ function auditCoreRouteExtraction(apiSrcDir) {
11259
11405
  const prefixSet = /* @__PURE__ */ new Set();
11260
11406
  let rawApiRouterCount = 0;
11261
11407
  for (const file of files) {
11262
- const text = readFileSync31(file, "utf8");
11408
+ const text = readFileSync32(file, "utf8");
11263
11409
  const extraction = extractCoreRoutePrefixes(text);
11264
11410
  rawApiRouterCount += extraction.rawApiRouterCount;
11265
11411
  for (const p of extraction.prefixes) prefixSet.add(normalizePrefix(p));
@@ -11275,10 +11421,10 @@ function pathMatchesAnyCorePrefix(normalized, corePrefixes, apiRoutePrefix = API
11275
11421
  }
11276
11422
  function resolveSiblingCoreSrc(params) {
11277
11423
  const { estateDir, sibling } = params;
11278
- const configPath = join43(estateDir, sibling, "biffo.sibling.json");
11424
+ const configPath = join44(estateDir, sibling, "biffo.sibling.json");
11279
11425
  let raw;
11280
11426
  try {
11281
- raw = readFileSync31(configPath, "utf8");
11427
+ raw = readFileSync32(configPath, "utf8");
11282
11428
  } catch (err) {
11283
11429
  throw new Error(
11284
11430
  `cannot resolve ${sibling}'s core: ${configPath} does not exist or is unreadable (${err.message}) -- refusing to guess which core serves this sibling.`
@@ -11298,8 +11444,8 @@ function resolveSiblingCoreSrc(params) {
11298
11444
  `cannot resolve ${sibling}'s core: ${configPath} has no non-empty "core_project" field.`
11299
11445
  );
11300
11446
  }
11301
- const coreApiSrcDir = join43(estateDir, coreProject, "services", "api", "src");
11302
- if (!existsSync40(coreApiSrcDir)) {
11447
+ const coreApiSrcDir = join44(estateDir, coreProject, "services", "api", "src");
11448
+ if (!existsSync41(coreApiSrcDir)) {
11303
11449
  throw new Error(
11304
11450
  `cannot resolve ${sibling}'s core: biffo.sibling.json names core_project "${coreProject}", but ${coreApiSrcDir} does not exist -- the instance is missing from this estate checkout, not merely unmatched. Refusing to silently skip ${sibling} and shrink the audit's denominator.`
11305
11451
  );
@@ -11340,9 +11486,9 @@ function auditSiblingCoreDirectPaths(params) {
11340
11486
 
11341
11487
  // src/scripts/check-core-direct-paths.ts
11342
11488
  async function runCoreDirectPathsCheck(opts = {}) {
11343
- const root = (await execa12("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
11489
+ const root = (await execa13("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
11344
11490
  const sibling = opts.sibling ?? "sibling-template (self-check)";
11345
- const frontendSrcDir = opts.frontendSrc ?? join44(root, "_skeletons", "sibling-template", "apps", "frontend", "src");
11491
+ const frontendSrcDir = opts.frontendSrc ?? join45(root, "_skeletons", "sibling-template", "apps", "frontend", "src");
11346
11492
  let coreApiSrcDir;
11347
11493
  let coreProject = null;
11348
11494
  if (opts.coreSrc) {
@@ -11358,7 +11504,7 @@ async function runCoreDirectPathsCheck(opts = {}) {
11358
11504
  coreApiSrcDir = resolution.coreApiSrcDir;
11359
11505
  coreProject = resolution.coreProject;
11360
11506
  } else {
11361
- coreApiSrcDir = join44(root, "services", "api", "src");
11507
+ coreApiSrcDir = join45(root, "services", "api", "src");
11362
11508
  }
11363
11509
  const report = auditSiblingCoreDirectPaths({ sibling, frontendSrcDir, coreApiSrcDir });
11364
11510
  console.log(
@@ -11394,7 +11540,7 @@ async function runCoreDirectPathsCheck(opts = {}) {
11394
11540
  }
11395
11541
 
11396
11542
  // src/scripts/check-core-ownership.ts
11397
- import { execa as execa13 } from "execa";
11543
+ import { execa as execa14 } from "execa";
11398
11544
  var BOLD = "\x1B[1m";
11399
11545
  var DIM = "\x1B[2m";
11400
11546
  var RED = "\x1B[31m";
@@ -11405,7 +11551,7 @@ async function runOwnershipCheck(argv) {
11405
11551
  const stagedFlag = args.indexOf("--staged");
11406
11552
  const staged = stagedFlag !== -1;
11407
11553
  const messageFile = staged ? args[stagedFlag + 1] : void 0;
11408
- const root = (await execa13("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
11554
+ const root = (await execa14("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
11409
11555
  const ownership = classifyRepoOwnership(root);
11410
11556
  if (ownership === "template") {
11411
11557
  console.log("\u2713 core ownership guard: skipped \u2014 this is the template, which owns these paths.");
@@ -11421,11 +11567,11 @@ async function runOwnershipCheck(argv) {
11421
11567
  let deletedFiles = [];
11422
11568
  let commitMessage = "";
11423
11569
  if (staged) {
11424
- const { stdout } = await execa13("git", ["diff", "--cached", "--name-status"], { cwd: root });
11570
+ const { stdout } = await execa14("git", ["diff", "--cached", "--name-status"], { cwd: root });
11425
11571
  ({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
11426
11572
  if (messageFile) {
11427
- const { readFileSync: readFileSync41, existsSync: existsSync50 } = await import("fs");
11428
- if (existsSync50(messageFile)) commitMessage = readFileSync41(messageFile, "utf8");
11573
+ const { readFileSync: readFileSync42, existsSync: existsSync51 } = await import("fs");
11574
+ if (existsSync51(messageFile)) commitMessage = readFileSync42(messageFile, "utf8");
11429
11575
  }
11430
11576
  } else {
11431
11577
  const base = process.env["GITHUB_BASE_REF"] ?? args[0];
@@ -11433,18 +11579,18 @@ async function runOwnershipCheck(argv) {
11433
11579
  console.error("No base ref: set GITHUB_BASE_REF or pass a base branch as the first argument.");
11434
11580
  process.exit(2);
11435
11581
  }
11436
- await execa13("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
11437
- const { stdout } = await execa13("git", ["diff", "--name-status", `origin/${base}...HEAD`], {
11582
+ await execa14("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
11583
+ const { stdout } = await execa14("git", ["diff", "--name-status", `origin/${base}...HEAD`], {
11438
11584
  cwd: root
11439
11585
  });
11440
11586
  ({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
11441
- const { stdout: log2 } = await execa13("git", ["log", "--format=%B", `origin/${base}..HEAD`], {
11587
+ const { stdout: log2 } = await execa14("git", ["log", "--format=%B", `origin/${base}..HEAD`], {
11442
11588
  cwd: root,
11443
11589
  reject: false
11444
11590
  });
11445
11591
  commitMessage = log2;
11446
11592
  }
11447
- const { stdout: gitBranch } = await execa13("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
11593
+ const { stdout: gitBranch } = await execa14("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
11448
11594
  cwd: root,
11449
11595
  reject: false
11450
11596
  });
@@ -11526,11 +11672,11 @@ ${BOLD}If the divergence is deliberate${OFF}
11526
11672
  }
11527
11673
 
11528
11674
  // src/scripts/check-eventbridge-log-permissions.ts
11529
- import { execa as execa14 } from "execa";
11675
+ import { execa as execa15 } from "execa";
11530
11676
 
11531
11677
  // src/lib/eventbridge-log-permission-guard.ts
11532
- import { readFileSync as readFileSync32, readdirSync as readdirSync19, statSync as statSync12 } from "fs";
11533
- import { join as join45 } from "path";
11678
+ import { readFileSync as readFileSync33, readdirSync as readdirSync20, statSync as statSync12 } from "fs";
11679
+ import { join as join46 } from "path";
11534
11680
  var SKIP_DIRS2 = /* @__PURE__ */ new Set(["node_modules", ".git", ".terraform", ".worktrees", "dist"]);
11535
11681
  var EVENT_TARGET_TYPE = "aws_cloudwatch_event_target";
11536
11682
  var LOG_RESOURCE_POLICY_TYPE = "aws_cloudwatch_log_resource_policy";
@@ -11602,12 +11748,12 @@ function walkTerraformFiles(root) {
11602
11748
  const walk2 = (dir) => {
11603
11749
  let entries;
11604
11750
  try {
11605
- entries = readdirSync19(dir);
11751
+ entries = readdirSync20(dir);
11606
11752
  } catch {
11607
11753
  return;
11608
11754
  }
11609
11755
  for (const entry of entries) {
11610
- const p = join45(dir, entry);
11756
+ const p = join46(dir, entry);
11611
11757
  let st;
11612
11758
  try {
11613
11759
  st = statSync12(p);
@@ -11650,7 +11796,7 @@ function auditEventBridgeLogPermissions(root) {
11650
11796
  let rawEventTargetCount = 0;
11651
11797
  let rawLogPolicyCount = 0;
11652
11798
  for (const file of files) {
11653
- const text = readFileSync32(file, "utf8");
11799
+ const text = readFileSync33(file, "utf8");
11654
11800
  rawEventTargetCount += countRawResourceDeclarations(text, EVENT_TARGET_TYPE);
11655
11801
  rawLogPolicyCount += countRawResourceDeclarations(text, LOG_RESOURCE_POLICY_TYPE);
11656
11802
  eventTargetBlocks.push(...findResourceBlocks(text, file, EVENT_TARGET_TYPE));
@@ -11703,7 +11849,7 @@ function auditEventBridgeLogPermissions(root) {
11703
11849
 
11704
11850
  // src/scripts/check-eventbridge-log-permissions.ts
11705
11851
  async function runEventBridgeLogPermissionCheck() {
11706
- const root = (await execa14("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
11852
+ const root = (await execa15("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
11707
11853
  let report;
11708
11854
  try {
11709
11855
  report = auditEventBridgeLogPermissions(root);
@@ -11740,15 +11886,15 @@ async function runEventBridgeLogPermissionCheck() {
11740
11886
  }
11741
11887
 
11742
11888
  // src/scripts/check-lambda-output.ts
11743
- import { execa as execa15 } from "execa";
11889
+ import { execa as execa16 } from "execa";
11744
11890
 
11745
11891
  // src/lib/lambda-output-guard.ts
11746
- import { readFileSync as readFileSync34 } from "fs";
11747
- import { join as join47 } from "path";
11892
+ import { readFileSync as readFileSync35 } from "fs";
11893
+ import { join as join48 } from "path";
11748
11894
 
11749
11895
  // src/lib/terraform-input-guard.ts
11750
- import { existsSync as existsSync41, readdirSync as readdirSync20, readFileSync as readFileSync33, statSync as statSync13 } from "fs";
11751
- import { join as join46 } from "path";
11896
+ import { existsSync as existsSync42, readdirSync as readdirSync21, readFileSync as readFileSync34, statSync as statSync13 } from "fs";
11897
+ import { join as join47 } from "path";
11752
11898
  var GUARDED_SUBCOMMANDS = [
11753
11899
  "init",
11754
11900
  "plan",
@@ -11762,18 +11908,18 @@ function stripComments2(source) {
11762
11908
  return source.split("\n").map((line) => line.replace(/(^|\s)#.*$/, "$1")).join("\n");
11763
11909
  }
11764
11910
  function vendoredPluginServiceDirs(repoRoot) {
11765
- const servicesDir = join46(repoRoot, "services");
11911
+ const servicesDir = join47(repoRoot, "services");
11766
11912
  const result = /* @__PURE__ */ new Set();
11767
11913
  let entries;
11768
11914
  try {
11769
- entries = readdirSync20(servicesDir);
11915
+ entries = readdirSync21(servicesDir);
11770
11916
  } catch {
11771
11917
  return result;
11772
11918
  }
11773
11919
  for (const entry of entries) {
11774
- const full = join46(servicesDir, entry);
11775
- if (!existsSync41(full) || !statSync13(full).isDirectory()) continue;
11776
- if (existsSync41(join46(full, "biffo.plugin.json"))) {
11920
+ const full = join47(servicesDir, entry);
11921
+ if (!existsSync42(full) || !statSync13(full).isDirectory()) continue;
11922
+ if (existsSync42(join47(full, "biffo.plugin.json"))) {
11777
11923
  result.add(entry);
11778
11924
  }
11779
11925
  }
@@ -11785,7 +11931,7 @@ function findWorkflowFiles(repoRoot) {
11785
11931
  const walk2 = (dir, relative11) => {
11786
11932
  let entries;
11787
11933
  try {
11788
- entries = readdirSync20(dir);
11934
+ entries = readdirSync21(dir);
11789
11935
  } catch {
11790
11936
  return;
11791
11937
  }
@@ -11794,7 +11940,7 @@ function findWorkflowFiles(repoRoot) {
11794
11940
  if (entry === ".github" && relative11.startsWith("services/") && vendoredPluginDirs.has(relative11.slice("services/".length))) {
11795
11941
  continue;
11796
11942
  }
11797
- const full = join46(dir, entry);
11943
+ const full = join47(dir, entry);
11798
11944
  const rel = relative11 ? `${relative11}/${entry}` : entry;
11799
11945
  if (statSync13(full).isDirectory()) {
11800
11946
  walk2(full, rel);
@@ -11838,7 +11984,7 @@ function checkWorkflowSource(file, rawSource) {
11838
11984
  }
11839
11985
  function checkTerraformInput(repoRoot) {
11840
11986
  return findWorkflowFiles(repoRoot).flatMap(
11841
- (file) => checkWorkflowSource(file, readFileSync33(join46(repoRoot, file), "utf8"))
11987
+ (file) => checkWorkflowSource(file, readFileSync34(join47(repoRoot, file), "utf8"))
11842
11988
  );
11843
11989
  }
11844
11990
 
@@ -11896,13 +12042,13 @@ function checkWorkflowSource2(file, rawSource) {
11896
12042
  }
11897
12043
  function checkLambdaOutput(repoRoot) {
11898
12044
  return findWorkflowFiles(repoRoot).flatMap(
11899
- (file) => checkWorkflowSource2(file, readFileSync34(join47(repoRoot, file), "utf8"))
12045
+ (file) => checkWorkflowSource2(file, readFileSync35(join48(repoRoot, file), "utf8"))
11900
12046
  );
11901
12047
  }
11902
12048
 
11903
12049
  // src/scripts/check-lambda-output.ts
11904
12050
  async function runLambdaOutputCheck() {
11905
- const root = (await execa15("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
12051
+ const root = (await execa16("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
11906
12052
  const files = findWorkflowFiles(root);
11907
12053
  console.log(`audited ${files.length} workflow file(s) under ${root}`);
11908
12054
  if (files.length === 0) {
@@ -11924,9 +12070,9 @@ async function runLambdaOutputCheck() {
11924
12070
  }
11925
12071
 
11926
12072
  // src/scripts/check-pipe-trap.ts
11927
- import { readFileSync as readFileSync35, readdirSync as readdirSync21 } from "fs";
11928
- import { join as join48, relative as relative9 } from "path";
11929
- import { execa as execa16 } from "execa";
12073
+ import { readFileSync as readFileSync36, readdirSync as readdirSync22 } from "fs";
12074
+ import { join as join49, relative as relative9 } from "path";
12075
+ import { execa as execa17 } from "execa";
11930
12076
 
11931
12077
  // src/lib/pipe-trap-guard.ts
11932
12078
  var STATUS_BEARING = [
@@ -12022,23 +12168,23 @@ function findPipeTraps(source) {
12022
12168
  function shellFiles(root) {
12023
12169
  const out = [];
12024
12170
  for (const dir of ["scripts", ".githooks"]) {
12025
- const full = join48(root, dir);
12171
+ const full = join49(root, dir);
12026
12172
  let entries;
12027
12173
  try {
12028
- entries = readdirSync21(full, { withFileTypes: true });
12174
+ entries = readdirSync22(full, { withFileTypes: true });
12029
12175
  } catch {
12030
12176
  continue;
12031
12177
  }
12032
12178
  for (const entry of entries) {
12033
12179
  if (!entry.isFile()) continue;
12034
12180
  if (dir === "scripts" && !entry.name.endsWith(".sh")) continue;
12035
- out.push(join48(full, entry.name));
12181
+ out.push(join49(full, entry.name));
12036
12182
  }
12037
12183
  }
12038
12184
  return out;
12039
12185
  }
12040
12186
  async function runPipeTrapCheck() {
12041
- const root = (await execa16("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
12187
+ const root = (await execa17("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
12042
12188
  const files = shellFiles(root);
12043
12189
  console.log(`audited ${files.length} shell file(s) under scripts/ and .githooks/ under ${root}`);
12044
12190
  if (files.length === 0) {
@@ -12048,7 +12194,7 @@ async function runPipeTrapCheck() {
12048
12194
  process.exit(1);
12049
12195
  }
12050
12196
  const findings = files.flatMap(
12051
- (file) => findPipeTraps(readFileSync35(file, "utf8")).map(
12197
+ (file) => findPipeTraps(readFileSync36(file, "utf8")).map(
12052
12198
  (t) => `${relative9(root, file)}:${t.line} ${t.text}
12053
12199
  ${t.reason}`
12054
12200
  )
@@ -12065,11 +12211,11 @@ async function runPipeTrapCheck() {
12065
12211
  }
12066
12212
 
12067
12213
  // src/scripts/check-plugin-allowlist-convention.ts
12068
- import { execa as execa17 } from "execa";
12214
+ import { execa as execa18 } from "execa";
12069
12215
 
12070
12216
  // src/lib/plugin-allowlist-convention.ts
12071
- import { readFileSync as readFileSync36 } from "fs";
12072
- import { join as join49 } from "path";
12217
+ import { readFileSync as readFileSync37 } from "fs";
12218
+ import { join as join50 } from "path";
12073
12219
  var COMPUTE_MAIN_TF = "modules/cloud/aws/compute/main.tf";
12074
12220
  var PLUGIN_TEMPLATE_MAIN_TF = "modules/plugins/_template/main.tf";
12075
12221
  var ALLOWLIST_MAIN_TF = "modules/cloud/aws/plugin-allowlist/main.tf";
@@ -12080,7 +12226,7 @@ var PLUGIN = "<plugin>";
12080
12226
  var ACCOUNT = "<account>";
12081
12227
  function read(repoRoot, relative11) {
12082
12228
  try {
12083
- return readFileSync36(join49(repoRoot, relative11), "utf8");
12229
+ return readFileSync37(join50(repoRoot, relative11), "utf8");
12084
12230
  } catch {
12085
12231
  throw new Error(`plugin-allowlist drift guard: cannot read ${relative11}`);
12086
12232
  }
@@ -12176,7 +12322,7 @@ Plugins would be rejected by require_service_principal (ADR-0009). Fix the glob,
12176
12322
 
12177
12323
  // src/scripts/check-plugin-allowlist-convention.ts
12178
12324
  async function runPluginAllowlistConventionCheck() {
12179
- const root = (await execa17("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
12325
+ const root = (await execa18("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
12180
12326
  let violations;
12181
12327
  try {
12182
12328
  violations = checkAllowlistConvention(root);
@@ -12201,34 +12347,34 @@ async function runPluginAllowlistConventionCheck() {
12201
12347
  }
12202
12348
 
12203
12349
  // src/scripts/check-plugin-collisions.ts
12204
- import { existsSync as existsSync43 } from "fs";
12205
- import { join as join51 } from "path";
12206
- import { execa as execa18 } from "execa";
12350
+ import { existsSync as existsSync44 } from "fs";
12351
+ import { join as join52 } from "path";
12352
+ import { execa as execa19 } from "execa";
12207
12353
 
12208
12354
  // src/lib/plugin-collision-guard.ts
12209
- import { existsSync as existsSync42, readdirSync as readdirSync22, statSync as statSync14 } from "fs";
12210
- import { join as join50 } from "path";
12355
+ import { existsSync as existsSync43, readdirSync as readdirSync23, statSync as statSync14 } from "fs";
12356
+ import { join as join51 } from "path";
12211
12357
  var PYTEST_SPECIAL = /* @__PURE__ */ new Set(["conftest.py"]);
12212
12358
  var IGNORED_DIRS = /* @__PURE__ */ new Set([".venv", "node_modules", "__pycache__", ".git", "dist", "build"]);
12213
12359
  function subdirectories(dir) {
12214
- if (!existsSync42(dir)) return [];
12215
- return readdirSync22(dir).filter((entry) => {
12360
+ if (!existsSync43(dir)) return [];
12361
+ return readdirSync23(dir).filter((entry) => {
12216
12362
  if (IGNORED_DIRS.has(entry) || entry.startsWith(".")) return false;
12217
12363
  try {
12218
- return statSync14(join50(dir, entry)).isDirectory();
12364
+ return statSync14(join51(dir, entry)).isDirectory();
12219
12365
  } catch {
12220
12366
  return false;
12221
12367
  }
12222
12368
  });
12223
12369
  }
12224
12370
  function regularPackagesOf(pluginDir2) {
12225
- return subdirectories(pluginDir2).filter((name) => existsSync42(join50(pluginDir2, name, "__init__.py"))).sort();
12371
+ return subdirectories(pluginDir2).filter((name) => existsSync43(join51(pluginDir2, name, "__init__.py"))).sort();
12226
12372
  }
12227
12373
  function bareTestModulesOf(pluginDir2) {
12228
- const testsDir = join50(pluginDir2, "tests");
12229
- if (!existsSync42(testsDir)) return [];
12230
- if (existsSync42(join50(testsDir, "__init__.py"))) return [];
12231
- return readdirSync22(testsDir).filter((f) => f.endsWith(".py") && !PYTEST_SPECIAL.has(f)).sort();
12374
+ const testsDir = join51(pluginDir2, "tests");
12375
+ if (!existsSync43(testsDir)) return [];
12376
+ if (existsSync43(join51(testsDir, "__init__.py"))) return [];
12377
+ return readdirSync23(testsDir).filter((f) => f.endsWith(".py") && !PYTEST_SPECIAL.has(f)).sort();
12232
12378
  }
12233
12379
  function findCollisions(servicesDir, pluginDirs) {
12234
12380
  const plugins = (pluginDirs ?? subdirectories(servicesDir)).filter((name) => !name.startsWith("_")).filter((name) => name !== "api").sort();
@@ -12236,7 +12382,7 @@ function findCollisions(servicesDir, pluginDirs) {
12236
12382
  const gather = (kind, namesOf) => {
12237
12383
  const claims = /* @__PURE__ */ new Map();
12238
12384
  for (const plugin of plugins) {
12239
- for (const name of namesOf(join50(servicesDir, plugin))) {
12385
+ for (const name of namesOf(join51(servicesDir, plugin))) {
12240
12386
  claims.set(name, [...claims.get(name) ?? [], plugin]);
12241
12387
  }
12242
12388
  }
@@ -12273,9 +12419,9 @@ function formatCollisions(collisions) {
12273
12419
 
12274
12420
  // src/scripts/check-plugin-collisions.ts
12275
12421
  async function runPluginCollisionCheck() {
12276
- const root = (await execa18("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
12277
- const servicesDir = join51(root, "services");
12278
- if (!existsSync43(servicesDir)) {
12422
+ const root = (await execa19("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
12423
+ const servicesDir = join52(root, "services");
12424
+ if (!existsSync44(servicesDir)) {
12279
12425
  console.log("\u2713 plugin collision guard: no services/ directory \u2014 nothing to compare");
12280
12426
  return;
12281
12427
  }
@@ -12292,11 +12438,11 @@ async function runPluginCollisionCheck() {
12292
12438
  }
12293
12439
 
12294
12440
  // src/scripts/check-plugin-terraform.ts
12295
- import { execa as execa19 } from "execa";
12441
+ import { execa as execa20 } from "execa";
12296
12442
 
12297
12443
  // src/lib/plugin-terraform-guard.ts
12298
- import { existsSync as existsSync44, readFileSync as readFileSync37, readdirSync as readdirSync23 } from "fs";
12299
- import { dirname as dirname10, join as join52, relative as relative10, sep as sep4 } from "path";
12444
+ import { existsSync as existsSync45, readFileSync as readFileSync38, readdirSync as readdirSync24 } from "fs";
12445
+ import { dirname as dirname10, join as join53, relative as relative10, sep as sep4 } from "path";
12300
12446
  var SKIP_DIRS3 = /* @__PURE__ */ new Set(["node_modules", ".git", ".worktrees", "dist", ".venv", "__pycache__"]);
12301
12447
  var PLUGIN_MANIFEST_FILE2 = "biffo.plugin.json";
12302
12448
  function findPluginManifests(root) {
@@ -12304,16 +12450,16 @@ function findPluginManifests(root) {
12304
12450
  const walk2 = (dir) => {
12305
12451
  let entries;
12306
12452
  try {
12307
- entries = readdirSync23(dir, { withFileTypes: true });
12453
+ entries = readdirSync24(dir, { withFileTypes: true });
12308
12454
  } catch {
12309
12455
  return;
12310
12456
  }
12311
12457
  for (const entry of entries) {
12312
12458
  if (entry.isDirectory()) {
12313
12459
  if (SKIP_DIRS3.has(entry.name)) continue;
12314
- walk2(join52(dir, entry.name));
12460
+ walk2(join53(dir, entry.name));
12315
12461
  } else if (entry.isFile() && entry.name === PLUGIN_MANIFEST_FILE2) {
12316
- found.push(relative10(root, join52(dir, entry.name)).split(sep4).join("/"));
12462
+ found.push(relative10(root, join53(dir, entry.name)).split(sep4).join("/"));
12317
12463
  }
12318
12464
  }
12319
12465
  };
@@ -12323,7 +12469,7 @@ function findPluginManifests(root) {
12323
12469
  function readSubscriptions(absManifestPath) {
12324
12470
  let parsed;
12325
12471
  try {
12326
- parsed = JSON.parse(readFileSync37(absManifestPath, "utf8"));
12472
+ parsed = JSON.parse(readFileSync38(absManifestPath, "utf8"));
12327
12473
  } catch {
12328
12474
  return null;
12329
12475
  }
@@ -12338,14 +12484,14 @@ function readSubscriptions(absManifestPath) {
12338
12484
  }
12339
12485
  function checkPluginTerraform(root) {
12340
12486
  const violations = [];
12341
- const coreManifest = existsSync44(join52(root, CORE_MANIFEST_FILE)) ? readCoreManifest(root) : null;
12487
+ const coreManifest = existsSync45(join53(root, CORE_MANIFEST_FILE)) ? readCoreManifest(root) : null;
12342
12488
  for (const manifest of findPluginManifests(root)) {
12343
12489
  if (coreManifest && !isTemplateOwned(manifest, coreManifest)) continue;
12344
- const absManifest = join52(root, manifest);
12490
+ const absManifest = join53(root, manifest);
12345
12491
  const subscriptions = readSubscriptions(absManifest);
12346
12492
  if (subscriptions === null) continue;
12347
12493
  const pluginDir2 = dirname10(absManifest);
12348
- if (existsSync44(join52(pluginDir2, "terraform"))) continue;
12494
+ if (existsSync45(join53(pluginDir2, "terraform"))) continue;
12349
12495
  const relPluginDir = relative10(root, pluginDir2).split(sep4).join("/");
12350
12496
  violations.push({
12351
12497
  manifest,
@@ -12365,7 +12511,7 @@ function formatViolations(violations) {
12365
12511
 
12366
12512
  // src/scripts/check-plugin-terraform.ts
12367
12513
  async function runPluginTerraformCheck() {
12368
- const root = (await execa19("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
12514
+ const root = (await execa20("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
12369
12515
  const violations = checkPluginTerraform(root);
12370
12516
  if (violations.length > 0) {
12371
12517
  console.error("\u2717 plugin Terraform guard: event subscriptions with no infrastructure\n");
@@ -12376,13 +12522,13 @@ async function runPluginTerraformCheck() {
12376
12522
  }
12377
12523
 
12378
12524
  // src/scripts/check-plugin-tool-supply.ts
12379
- import { existsSync as existsSync46 } from "fs";
12380
- import { join as join54 } from "path";
12381
- import { execa as execa20 } from "execa";
12525
+ import { existsSync as existsSync47 } from "fs";
12526
+ import { join as join55 } from "path";
12527
+ import { execa as execa21 } from "execa";
12382
12528
 
12383
12529
  // src/lib/plugin-tool-supply-audit.ts
12384
- import { existsSync as existsSync45, readFileSync as readFileSync38, readdirSync as readdirSync24, statSync as statSync15 } from "fs";
12385
- import { join as join53 } from "path";
12530
+ import { existsSync as existsSync46, readFileSync as readFileSync39, readdirSync as readdirSync25, statSync as statSync15 } from "fs";
12531
+ import { join as join54 } from "path";
12386
12532
 
12387
12533
  // src/lib/openrouter-model-snapshot.ts
12388
12534
  var OPENROUTER_MODEL_SNAPSHOT_FETCHED_AT = "2026-08-10T06:39:01Z";
@@ -12793,13 +12939,13 @@ var OPENROUTER_MODEL_IDS = [
12793
12939
  function listDirs(root) {
12794
12940
  let entries;
12795
12941
  try {
12796
- entries = readdirSync24(root);
12942
+ entries = readdirSync25(root);
12797
12943
  } catch {
12798
12944
  return [];
12799
12945
  }
12800
12946
  return entries.filter((e) => {
12801
12947
  try {
12802
- return statSync15(join53(root, e)).isDirectory();
12948
+ return statSync15(join54(root, e)).isDirectory();
12803
12949
  } catch {
12804
12950
  return false;
12805
12951
  }
@@ -12810,12 +12956,12 @@ function walkFiles2(root, accept, skipDir) {
12810
12956
  const walk2 = (dir) => {
12811
12957
  let entries;
12812
12958
  try {
12813
- entries = readdirSync24(dir);
12959
+ entries = readdirSync25(dir);
12814
12960
  } catch {
12815
12961
  return;
12816
12962
  }
12817
12963
  for (const entry of entries) {
12818
- const p = join53(dir, entry);
12964
+ const p = join54(dir, entry);
12819
12965
  let st;
12820
12966
  try {
12821
12967
  st = statSync15(p);
@@ -12841,14 +12987,14 @@ function pluginPythonFiles(pluginDir2) {
12841
12987
  );
12842
12988
  }
12843
12989
  function pluginTerraformFiles(pluginDir2) {
12844
- const tfDir = join53(pluginDir2, "terraform");
12990
+ const tfDir = join54(pluginDir2, "terraform");
12845
12991
  let entries;
12846
12992
  try {
12847
- entries = readdirSync24(tfDir);
12993
+ entries = readdirSync25(tfDir);
12848
12994
  } catch {
12849
12995
  return [];
12850
12996
  }
12851
- return entries.filter((e) => e.endsWith(".tf")).map((e) => join53(tfDir, e)).sort();
12997
+ return entries.filter((e) => e.endsWith(".tf")).map((e) => join54(tfDir, e)).sort();
12852
12998
  }
12853
12999
  function extractManifestTools(manifestText) {
12854
13000
  let parsed;
@@ -13100,8 +13246,8 @@ function isSnapshotStale(fetchedAt, now) {
13100
13246
  function normalizeModelId(id) {
13101
13247
  return id.endsWith(":online") ? id.slice(0, -":online".length) : id;
13102
13248
  }
13103
- var CONFIG_PY_PATH = join53("services", "api", "src", "api", "config.py");
13104
- var ORCHESTRATION_SCHEMA_PATH = join53(
13249
+ var CONFIG_PY_PATH = join54("services", "api", "src", "api", "config.py");
13250
+ var ORCHESTRATION_SCHEMA_PATH = join54(
13105
13251
  "services",
13106
13252
  "api",
13107
13253
  "src",
@@ -13113,10 +13259,10 @@ function auditDeclaredModelIds(repoRoot, options = {}) {
13113
13259
  const knownModelIds = options.knownModelIds ?? OPENROUTER_MODEL_IDS;
13114
13260
  const snapshotFetchedAt = options.snapshotFetchedAt ?? OPENROUTER_MODEL_SNAPSHOT_FETCHED_AT;
13115
13261
  const now = options.now ?? /* @__PURE__ */ new Date();
13116
- const configPath = join53(repoRoot, CONFIG_PY_PATH);
13117
- const orchestrationPath = join53(repoRoot, ORCHESTRATION_SCHEMA_PATH);
13118
- const configMissing = !existsSync45(configPath);
13119
- const orchestrationSchemaMissing = !existsSync45(orchestrationPath);
13262
+ const configPath = join54(repoRoot, CONFIG_PY_PATH);
13263
+ const orchestrationPath = join54(repoRoot, ORCHESTRATION_SCHEMA_PATH);
13264
+ const configMissing = !existsSync46(configPath);
13265
+ const orchestrationSchemaMissing = !existsSync46(orchestrationPath);
13120
13266
  const knownSet = new Set(knownModelIds);
13121
13267
  const snapshotEmpty = knownModelIds.length === 0;
13122
13268
  const snapshotStale = isSnapshotStale(snapshotFetchedAt, now);
@@ -13134,13 +13280,13 @@ function auditDeclaredModelIds(repoRoot, options = {}) {
13134
13280
  };
13135
13281
  let settingsBlind = false;
13136
13282
  if (!configMissing) {
13137
- const settingsFields = extractSettingsModelFields(readFileSync38(configPath, "utf8"));
13283
+ const settingsFields = extractSettingsModelFields(readFileSync39(configPath, "utf8"));
13138
13284
  if (settingsFields.length === 0) settingsBlind = true;
13139
13285
  for (const { field, value } of settingsFields) record(`${CONFIG_PY_PATH}#${field}`, value);
13140
13286
  }
13141
13287
  let curatedFieldsBlind = false;
13142
13288
  if (!orchestrationSchemaMissing) {
13143
- const curated = extractCuratedModelFields(readFileSync38(orchestrationPath, "utf8"));
13289
+ const curated = extractCuratedModelFields(readFileSync39(orchestrationPath, "utf8"));
13144
13290
  if (curated.rawFieldCount > 0 && curated.fields.every((f) => f.defaultValue === null && f.optionValues.length === 0)) {
13145
13291
  curatedFieldsBlind = true;
13146
13292
  }
@@ -13187,7 +13333,7 @@ function auditDeclaredModelIds(repoRoot, options = {}) {
13187
13333
  function discoverPluginDirs(pluginsRoot) {
13188
13334
  return listDirs(pluginsRoot).filter((name) => {
13189
13335
  try {
13190
- return statSync15(join53(pluginsRoot, name, "biffo.plugin.json")).isFile();
13336
+ return statSync15(join54(pluginsRoot, name, "biffo.plugin.json")).isFile();
13191
13337
  } catch {
13192
13338
  return false;
13193
13339
  }
@@ -13200,8 +13346,8 @@ function auditPluginToolSupply(pluginsRoot) {
13200
13346
  let terraformBlind = false;
13201
13347
  let totalDeclaredTools = 0;
13202
13348
  for (const name of pluginNames) {
13203
- const pluginDir2 = join53(pluginsRoot, name);
13204
- const manifestText = readFileSync38(join53(pluginDir2, "biffo.plugin.json"), "utf8");
13349
+ const pluginDir2 = join54(pluginsRoot, name);
13350
+ const manifestText = readFileSync39(join54(pluginDir2, "biffo.plugin.json"), "utf8");
13205
13351
  const manifest = extractManifestTools(manifestText);
13206
13352
  if (manifest.parseError) {
13207
13353
  findings.push({
@@ -13219,13 +13365,13 @@ function auditPluginToolSupply(pluginsRoot) {
13219
13365
  totalDeclaredTools += manifest.tools.length;
13220
13366
  const pySources = pluginPythonFiles(pluginDir2).map((f) => ({
13221
13367
  file: f,
13222
- text: readFileSync38(f, "utf8")
13368
+ text: readFileSync39(f, "utf8")
13223
13369
  }));
13224
13370
  const resolver = buildSymbolResolver(pySources);
13225
13371
  const registry = extractToolRegistryEntries(pySources, resolver);
13226
13372
  if (registry.rawToolDefinitionCount > 0 && registry.entries.length === 0) registryBlind = true;
13227
13373
  const tfFiles = pluginTerraformFiles(pluginDir2);
13228
- const tfText = tfFiles.map((f) => readFileSync38(f, "utf8")).join("\n");
13374
+ const tfText = tfFiles.map((f) => readFileSync39(f, "utf8")).join("\n");
13229
13375
  const terraform = extractTerraformEnvKeys(tfText);
13230
13376
  if (terraform.rawMarkerCount > 0 && terraform.resolvedBlockCount === 0) terraformBlind = true;
13231
13377
  for (const toolName of manifest.tools) {
@@ -13299,7 +13445,7 @@ function auditPluginToolSupply(pluginsRoot) {
13299
13445
  requiredEnvVars: envResult.envVars,
13300
13446
  missingEnvVars: anyWired ? [] : envResult.envVars,
13301
13447
  status: anyWired ? "ok" : "missing-env",
13302
- detail: anyWired ? `${entry.predicate}() is satisfiable: at least one of ${JSON.stringify(envResult.envVars)} is wired in Terraform` : `${entry.predicate}() reads ${JSON.stringify(envResult.envVars)} \u2014 NONE of these are wired by any environment_variables block under ${join53(pluginDir2, "terraform")}, so this deployment can never supply it`
13448
+ detail: anyWired ? `${entry.predicate}() is satisfiable: at least one of ${JSON.stringify(envResult.envVars)} is wired in Terraform` : `${entry.predicate}() reads ${JSON.stringify(envResult.envVars)} \u2014 NONE of these are wired by any environment_variables block under ${join54(pluginDir2, "terraform")}, so this deployment can never supply it`
13303
13449
  });
13304
13450
  }
13305
13451
  }
@@ -13330,10 +13476,10 @@ function auditPluginToolSupply(pluginsRoot) {
13330
13476
 
13331
13477
  // src/scripts/check-plugin-tool-supply.ts
13332
13478
  async function runPluginToolSupplyCheck() {
13333
- const root = (await execa20("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
13479
+ const root = (await execa21("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
13334
13480
  let allOk = true;
13335
- const pluginsRoot = join54(root, "services", "_plugins");
13336
- if (!existsSync46(pluginsRoot)) {
13481
+ const pluginsRoot = join55(root, "services", "_plugins");
13482
+ if (!existsSync47(pluginsRoot)) {
13337
13483
  console.log("\u2713 plugin tool-supply guard: no services/_plugins/ \u2014 nothing to audit");
13338
13484
  } else {
13339
13485
  const report = auditPluginToolSupply(pluginsRoot);
@@ -13363,8 +13509,8 @@ async function runPluginToolSupplyCheck() {
13363
13509
  console.log(`\u2713 plugin tool-supply guard: ${report.summary}`);
13364
13510
  }
13365
13511
  }
13366
- const servicesApiRoot = join54(root, "services", "api");
13367
- if (!existsSync46(servicesApiRoot)) {
13512
+ const servicesApiRoot = join55(root, "services", "api");
13513
+ if (!existsSync47(servicesApiRoot)) {
13368
13514
  console.log("\u2713 plugin model-id guard: no services/api/ \u2014 nothing to audit");
13369
13515
  } else {
13370
13516
  const modelReport = auditDeclaredModelIds(root);
@@ -13410,7 +13556,7 @@ async function runPluginToolSupplyCheck() {
13410
13556
  }
13411
13557
 
13412
13558
  // src/scripts/check-release-subject.ts
13413
- import { execa as execa21 } from "execa";
13559
+ import { execa as execa22 } from "execa";
13414
13560
 
13415
13561
  // src/lib/release-version.ts
13416
13562
  var MINOR_TYPES = /* @__PURE__ */ new Set(["feat"]);
@@ -13447,7 +13593,7 @@ async function fetchPrTitleViaGh({
13447
13593
  PR_NUMBER,
13448
13594
  GH_REPO
13449
13595
  }) {
13450
- const { stdout } = await execa21(
13596
+ const { stdout } = await execa22(
13451
13597
  "gh",
13452
13598
  ["pr", "view", PR_NUMBER, "--repo", GH_REPO, "--json", "title", "--jq", ".title"],
13453
13599
  { env: { ...process.env, GH_TOKEN } }
@@ -13483,7 +13629,7 @@ async function resolveReleaseSubject({
13483
13629
  );
13484
13630
  }
13485
13631
  }
13486
- return (await execa21("git", ["log", "-1", "--format=%s"], { cwd })).stdout.trim();
13632
+ return (await execa22("git", ["log", "-1", "--format=%s"], { cwd })).stdout.trim();
13487
13633
  }
13488
13634
  async function runReleaseSubjectCheck(argv) {
13489
13635
  const base = process.env["GITHUB_BASE_REF"] ?? argv[0];
@@ -13491,9 +13637,9 @@ async function runReleaseSubjectCheck(argv) {
13491
13637
  console.error("No base ref: set GITHUB_BASE_REF or pass a base branch as the first argument.");
13492
13638
  process.exit(2);
13493
13639
  }
13494
- const root = (await execa21("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
13495
- await execa21("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
13496
- const { stdout } = await execa21("git", ["diff", "--name-only", `origin/${base}...HEAD`], {
13640
+ const root = (await execa22("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
13641
+ await execa22("git", ["fetch", "--quiet", "origin", base], { cwd: root, reject: false });
13642
+ const { stdout } = await execa22("git", ["diff", "--name-only", `origin/${base}...HEAD`], {
13497
13643
  cwd: root
13498
13644
  });
13499
13645
  const changedFiles = stdout.split("\n").map((s) => s.trim()).filter(Boolean);
@@ -13541,13 +13687,13 @@ async function runReleaseSubjectCheck(argv) {
13541
13687
  }
13542
13688
 
13543
13689
  // src/scripts/check-skeleton-drift.ts
13544
- import { existsSync as existsSync47, readdirSync as readdirSync26 } from "fs";
13545
- import { join as join56 } from "path";
13546
- import { execa as execa22 } from "execa";
13690
+ import { existsSync as existsSync48, readdirSync as readdirSync27 } from "fs";
13691
+ import { join as join57 } from "path";
13692
+ import { execa as execa23 } from "execa";
13547
13693
 
13548
13694
  // src/lib/skeleton-drift-guard.ts
13549
- import { readFileSync as readFileSync39, readdirSync as readdirSync25, statSync as statSync16 } from "fs";
13550
- import { join as join55 } from "path";
13695
+ import { readFileSync as readFileSync40, readdirSync as readdirSync26, statSync as statSync16 } from "fs";
13696
+ import { join as join56 } from "path";
13551
13697
  var isWorkflow = (rel) => rel.startsWith(".github/workflows/") && (rel.endsWith(".yml") || rel.endsWith(".yaml"));
13552
13698
  var isRootLayout = (rel) => rel.endsWith("src/app/layout.tsx");
13553
13699
  var uncommented = (contents) => contents.split("\n").filter((line) => !/^\s*(\/\/|\/\*|\*)/.test(line)).join("\n");
@@ -13605,13 +13751,13 @@ function walk(dir, base = dir) {
13605
13751
  const out = [];
13606
13752
  let entries;
13607
13753
  try {
13608
- entries = readdirSync25(dir);
13754
+ entries = readdirSync26(dir);
13609
13755
  } catch {
13610
13756
  return out;
13611
13757
  }
13612
13758
  for (const entry of entries) {
13613
13759
  if (entry === ".venv" || entry === "node_modules" || entry === ".git") continue;
13614
- const abs = join55(dir, entry);
13760
+ const abs = join56(dir, entry);
13615
13761
  let isDir;
13616
13762
  try {
13617
13763
  isDir = statSync16(abs).isDirectory();
@@ -13633,7 +13779,7 @@ function auditSkeleton(skeletonRoot, name, rules = SKELETON_RULES) {
13633
13779
  if (!rule.appliesTo(rel)) continue;
13634
13780
  let contents;
13635
13781
  try {
13636
- contents = readFileSync39(join55(skeletonRoot, rel), "utf8");
13782
+ contents = readFileSync40(join56(skeletonRoot, rel), "utf8");
13637
13783
  } catch {
13638
13784
  continue;
13639
13785
  }
@@ -13662,23 +13808,23 @@ function formatViolations2(violations) {
13662
13808
 
13663
13809
  // src/scripts/check-skeleton-drift.ts
13664
13810
  function discoverSkeletons(root) {
13665
- const skeletonsDir = join56(root, "_skeletons");
13811
+ const skeletonsDir = join57(root, "_skeletons");
13666
13812
  let entries;
13667
13813
  try {
13668
- entries = readdirSync26(skeletonsDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
13814
+ entries = readdirSync27(skeletonsDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
13669
13815
  } catch {
13670
13816
  return [];
13671
13817
  }
13672
- return entries.filter((name) => existsSync47(join56(skeletonsDir, name, ".github", "workflows", "ci.yml"))).sort();
13818
+ return entries.filter((name) => existsSync48(join57(skeletonsDir, name, ".github", "workflows", "ci.yml"))).sort();
13673
13819
  }
13674
13820
  async function runSkeletonDriftCheck() {
13675
- const root = (await execa22("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
13821
+ const root = (await execa23("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
13676
13822
  const skeletons = discoverSkeletons(root);
13677
13823
  let filesConsidered = 0;
13678
13824
  for (const name of skeletons) {
13679
- const skeletonRoot = join56(root, "_skeletons", name);
13825
+ const skeletonRoot = join57(root, "_skeletons", name);
13680
13826
  filesConsidered += findWorkflowFiles(skeletonRoot).length;
13681
- if (existsSync47(join56(skeletonRoot, "apps", "frontend", "src", "app", "layout.tsx"))) {
13827
+ if (existsSync48(join57(skeletonRoot, "apps", "frontend", "src", "app", "layout.tsx"))) {
13682
13828
  filesConsidered += 1;
13683
13829
  }
13684
13830
  }
@@ -13692,7 +13838,7 @@ async function runSkeletonDriftCheck() {
13692
13838
  process.exit(1);
13693
13839
  }
13694
13840
  const violations = skeletons.flatMap(
13695
- (name) => auditSkeleton(join56(root, "_skeletons", name), name)
13841
+ (name) => auditSkeleton(join57(root, "_skeletons", name), name)
13696
13842
  );
13697
13843
  if (violations.length > 0) {
13698
13844
  console.error("\u2717 Skeleton-drift guard: drift found between this repo and its scaffolding\n");
@@ -13704,9 +13850,9 @@ async function runSkeletonDriftCheck() {
13704
13850
  }
13705
13851
 
13706
13852
  // src/scripts/check-terraform-input.ts
13707
- import { execa as execa23 } from "execa";
13853
+ import { execa as execa24 } from "execa";
13708
13854
  async function runTerraformInputCheck() {
13709
- const root = (await execa23("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
13855
+ const root = (await execa24("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
13710
13856
  const files = findWorkflowFiles(root);
13711
13857
  console.log(`audited ${files.length} workflow file(s) under ${root}`);
13712
13858
  if (files.length === 0) {
@@ -13796,6 +13942,11 @@ checkCommand.command("codeql-suppression").description(
13796
13942
  ).action(async () => {
13797
13943
  await runCodeqlSuppressionCheck();
13798
13944
  });
13945
+ checkCommand.command("claim-invocation").description(
13946
+ "Refuse a distributed AGENTS.md that documents a different claim invocation from the others, or an untokened `claim <issue>` (#1562) \u2014 `--as` reached one of three copies, so it was documented in zero satellites while working perfectly"
13947
+ ).action(async () => {
13948
+ await runClaimInvocationCheck();
13949
+ });
13799
13950
  checkCommand.command("skeleton-drift").description(
13800
13951
  "Refuse a fix this repo made for itself that never reached _skeletons/ \u2014 a hardcoded runner, the paid gitleaks action, an unhardened dependency audit, a hard-coded app title"
13801
13952
  ).action(async () => {
@@ -13830,8 +13981,8 @@ function rawArgsAfter(subcommand) {
13830
13981
  }
13831
13982
 
13832
13983
  // src/commands/doctor.ts
13833
- import { existsSync as existsSync48, readFileSync as readFileSync40 } from "fs";
13834
- import { join as join57, resolve as resolve20 } from "path";
13984
+ import { existsSync as existsSync49, readFileSync as readFileSync41 } from "fs";
13985
+ import { join as join58, resolve as resolve20 } from "path";
13835
13986
  import chalk21 from "chalk";
13836
13987
  import { Command as Command25 } from "commander";
13837
13988
 
@@ -14010,10 +14161,10 @@ async function runDoctor(options, deps = { git: new GitAdapter() }) {
14010
14161
  return runDoctorChecks(facts);
14011
14162
  }
14012
14163
  function readLocalCoreVersion(cwd) {
14013
- const path = join57(cwd, INSTANCE_CORE_FILE);
14014
- if (!existsSync48(path)) return null;
14164
+ const path = join58(cwd, INSTANCE_CORE_FILE);
14165
+ if (!existsSync49(path)) return null;
14015
14166
  try {
14016
- return extractVersionField(readFileSync40(path, "utf8"));
14167
+ return extractVersionField(readFileSync41(path, "utf8"));
14017
14168
  } catch {
14018
14169
  return null;
14019
14170
  }
@@ -14033,10 +14184,10 @@ function extractVersionField(contents) {
14033
14184
  return match?.[1] ?? null;
14034
14185
  }
14035
14186
  function readFossil(cwd) {
14036
- const path = join57(cwd, CORE_VERSION_FILE);
14037
- if (!existsSync48(path)) return null;
14187
+ const path = join58(cwd, CORE_VERSION_FILE);
14188
+ if (!existsSync49(path)) return null;
14038
14189
  try {
14039
- const value = readFileSync40(path, "utf8").trim();
14190
+ const value = readFileSync41(path, "utf8").trim();
14040
14191
  return value === "" ? null : value;
14041
14192
  } catch {
14042
14193
  return null;
@@ -14485,13 +14636,13 @@ import { fileURLToPath as fileURLToPath6 } from "url";
14485
14636
  import { Command as Command27 } from "commander";
14486
14637
 
14487
14638
  // src/lib/packaged-scripts.ts
14488
- import { existsSync as existsSync49 } from "fs";
14489
- import { dirname as dirname11, join as join58 } from "path";
14639
+ import { existsSync as existsSync50 } from "fs";
14640
+ import { dirname as dirname11, join as join59 } from "path";
14490
14641
  function findPackagedScript(startDir, relativePath) {
14491
14642
  let dir = startDir;
14492
14643
  for (; ; ) {
14493
- const candidate = join58(dir, relativePath);
14494
- if (existsSync49(candidate)) return candidate;
14644
+ const candidate = join59(dir, relativePath);
14645
+ if (existsSync50(candidate)) return candidate;
14495
14646
  const parent = dirname11(dir);
14496
14647
  if (parent === dir) return null;
14497
14648
  dir = parent;