@biffo/cli 0.302.0 → 0.302.2
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 +108 -92
- package/package.json +1 -1
- package/scripts/verify.sh +22 -0
package/dist/index.js
CHANGED
|
@@ -11965,8 +11965,8 @@ async function runOwnershipCheck(argv) {
|
|
|
11965
11965
|
const { stdout } = await execa("git", ["diff", "--cached", "--name-status"], { cwd: root });
|
|
11966
11966
|
({ changed: changedFiles, deleted: deletedFiles } = parseNameStatus(stdout));
|
|
11967
11967
|
if (messageFile) {
|
|
11968
|
-
const { readFileSync: readFileSync46, existsSync:
|
|
11969
|
-
if (
|
|
11968
|
+
const { readFileSync: readFileSync46, existsSync: existsSync57 } = await import("fs");
|
|
11969
|
+
if (existsSync57(messageFile)) commitMessage = readFileSync46(messageFile, "utf8");
|
|
11970
11970
|
}
|
|
11971
11971
|
} else {
|
|
11972
11972
|
const base = process.env["GITHUB_BASE_REF"] ?? args[0];
|
|
@@ -12066,6 +12066,10 @@ ${BOLD}If the divergence is deliberate${OFF}
|
|
|
12066
12066
|
process.exit(1);
|
|
12067
12067
|
}
|
|
12068
12068
|
|
|
12069
|
+
// src/scripts/check-distribution-inventory.ts
|
|
12070
|
+
import { existsSync as existsSync44 } from "fs";
|
|
12071
|
+
import { join as join48 } from "path";
|
|
12072
|
+
|
|
12069
12073
|
// src/lib/distribution-inventory.ts
|
|
12070
12074
|
import { existsSync as existsSync43, readFileSync as readFileSync34 } from "fs";
|
|
12071
12075
|
import { join as join47 } from "path";
|
|
@@ -12231,6 +12235,18 @@ async function fetchRemoteContentViaGh(repo, path, ref, execCommand) {
|
|
|
12231
12235
|
// src/scripts/check-distribution-inventory.ts
|
|
12232
12236
|
async function runDistributionInventoryCheck(root) {
|
|
12233
12237
|
const repoRoot = root ?? (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12238
|
+
if (isInstanceRepo(repoRoot)) {
|
|
12239
|
+
console.log(
|
|
12240
|
+
`\u2713 distribution-inventory: skipped \u2014 this is an instance (${INSTANCE_CORE_FILE} present). ${INVENTORY_FILENAME} is a template-only registry of the channels biffo-template itself uses to distribute to OTHER repos; it is not declared template-owned or user-owned in core-manifest.json, so biffo core upgrade never carries it and no instance is meant to hold one. Nothing to check here.`
|
|
12241
|
+
);
|
|
12242
|
+
return;
|
|
12243
|
+
}
|
|
12244
|
+
if (!existsSync44(join48(repoRoot, INVENTORY_FILENAME))) {
|
|
12245
|
+
console.log(
|
|
12246
|
+
`\u2713 distribution-inventory: skipped \u2014 no ${INVENTORY_FILENAME} at ${repoRoot}. This is a template-only registry; a checkout that legitimately has none has nothing for this guard to check.`
|
|
12247
|
+
);
|
|
12248
|
+
return;
|
|
12249
|
+
}
|
|
12234
12250
|
const inventory = loadDistributionInventory(repoRoot);
|
|
12235
12251
|
const violations = validateInventory(inventory);
|
|
12236
12252
|
console.log(
|
|
@@ -12251,7 +12267,7 @@ async function runDistributionInventoryCheck(root) {
|
|
|
12251
12267
|
}
|
|
12252
12268
|
|
|
12253
12269
|
// src/scripts/check-distribution-remote-state.ts
|
|
12254
|
-
import { join as
|
|
12270
|
+
import { join as join49 } from "path";
|
|
12255
12271
|
async function ghExecCommand(file, args) {
|
|
12256
12272
|
const result = await execa(file, args, { reject: false });
|
|
12257
12273
|
return { stdout: String(result.stdout ?? ""), exitCode: result.exitCode ?? null };
|
|
@@ -12266,7 +12282,7 @@ async function runDistributionRemoteStateCheck(root) {
|
|
|
12266
12282
|
}
|
|
12267
12283
|
}
|
|
12268
12284
|
console.log(
|
|
12269
|
-
`distribution-remote-state: examined ${assertions.length} remote content assertion(s) declared across ${inventory.entries.length} inventory entries (${
|
|
12285
|
+
`distribution-remote-state: examined ${assertions.length} remote content assertion(s) declared across ${inventory.entries.length} inventory entries (${join49(repoRoot, "distribution-inventory.json")})`
|
|
12270
12286
|
);
|
|
12271
12287
|
if (assertions.length === 0) {
|
|
12272
12288
|
console.log("\u2713 distribution-remote-state: nothing declared to check");
|
|
@@ -12312,7 +12328,7 @@ ${assertion.ref}`;
|
|
|
12312
12328
|
|
|
12313
12329
|
// src/lib/eventbridge-log-permission-guard.ts
|
|
12314
12330
|
import { readFileSync as readFileSync35, readdirSync as readdirSync20, statSync as statSync12 } from "fs";
|
|
12315
|
-
import { join as
|
|
12331
|
+
import { join as join50 } from "path";
|
|
12316
12332
|
var SKIP_DIRS2 = /* @__PURE__ */ new Set(["node_modules", ".git", ".terraform", ".worktrees", "dist"]);
|
|
12317
12333
|
var EVENT_TARGET_TYPE = "aws_cloudwatch_event_target";
|
|
12318
12334
|
var LOG_RESOURCE_POLICY_TYPE = "aws_cloudwatch_log_resource_policy";
|
|
@@ -12389,7 +12405,7 @@ function walkTerraformFiles(root) {
|
|
|
12389
12405
|
return;
|
|
12390
12406
|
}
|
|
12391
12407
|
for (const entry of entries) {
|
|
12392
|
-
const p =
|
|
12408
|
+
const p = join50(dir, entry);
|
|
12393
12409
|
let st;
|
|
12394
12410
|
try {
|
|
12395
12411
|
st = statSync12(p);
|
|
@@ -12522,8 +12538,8 @@ async function runEventBridgeLogPermissionCheck() {
|
|
|
12522
12538
|
}
|
|
12523
12539
|
|
|
12524
12540
|
// src/scripts/check-instance-adoption.ts
|
|
12525
|
-
import { existsSync as
|
|
12526
|
-
import { join as
|
|
12541
|
+
import { existsSync as existsSync45 } from "fs";
|
|
12542
|
+
import { join as join51 } from "path";
|
|
12527
12543
|
async function runInstanceAdoptionCheck(opts = {}) {
|
|
12528
12544
|
if (!opts.instanceDir) {
|
|
12529
12545
|
console.error(
|
|
@@ -12531,7 +12547,7 @@ async function runInstanceAdoptionCheck(opts = {}) {
|
|
|
12531
12547
|
);
|
|
12532
12548
|
process.exit(2);
|
|
12533
12549
|
}
|
|
12534
|
-
if (!
|
|
12550
|
+
if (!existsSync45(opts.instanceDir)) {
|
|
12535
12551
|
console.error(
|
|
12536
12552
|
`\u2717 instance-adoption guard: --instance-dir ${opts.instanceDir} does not exist \u2014 cannot tell whether it is adopted, and that is not the same as a clean pass.`
|
|
12537
12553
|
);
|
|
@@ -12539,7 +12555,7 @@ async function runInstanceAdoptionCheck(opts = {}) {
|
|
|
12539
12555
|
}
|
|
12540
12556
|
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
12541
12557
|
const theirsDir = opts.theirsDir ?? root;
|
|
12542
|
-
const instanceLabel = opts.instance ??
|
|
12558
|
+
const instanceLabel = opts.instance ?? join51(opts.instanceDir).split("/").filter(Boolean).pop();
|
|
12543
12559
|
const report = checkInstanceAdoption(theirsDir, opts.instanceDir);
|
|
12544
12560
|
console.log(
|
|
12545
12561
|
`examined ${report.examinedInstances} instance (${instanceLabel}) against ${report.registeredPairs} registered pair(s), ${report.applicablePairs} applicable to this instance, against template tree ${theirsDir}`
|
|
@@ -12562,11 +12578,11 @@ async function runInstanceAdoptionCheck(opts = {}) {
|
|
|
12562
12578
|
|
|
12563
12579
|
// src/lib/lambda-output-guard.ts
|
|
12564
12580
|
import { readFileSync as readFileSync37 } from "fs";
|
|
12565
|
-
import { join as
|
|
12581
|
+
import { join as join53 } from "path";
|
|
12566
12582
|
|
|
12567
12583
|
// src/lib/terraform-input-guard.ts
|
|
12568
|
-
import { existsSync as
|
|
12569
|
-
import { join as
|
|
12584
|
+
import { existsSync as existsSync46, readdirSync as readdirSync21, readFileSync as readFileSync36, statSync as statSync13 } from "fs";
|
|
12585
|
+
import { join as join52 } from "path";
|
|
12570
12586
|
var GUARDED_SUBCOMMANDS = [
|
|
12571
12587
|
"init",
|
|
12572
12588
|
"plan",
|
|
@@ -12580,7 +12596,7 @@ function stripComments2(source) {
|
|
|
12580
12596
|
return source.split("\n").map((line) => line.replace(/(^|\s)#.*$/, "$1")).join("\n");
|
|
12581
12597
|
}
|
|
12582
12598
|
function vendoredPluginServiceDirs(repoRoot) {
|
|
12583
|
-
const servicesDir =
|
|
12599
|
+
const servicesDir = join52(repoRoot, "services");
|
|
12584
12600
|
const result = /* @__PURE__ */ new Set();
|
|
12585
12601
|
let entries;
|
|
12586
12602
|
try {
|
|
@@ -12589,9 +12605,9 @@ function vendoredPluginServiceDirs(repoRoot) {
|
|
|
12589
12605
|
return result;
|
|
12590
12606
|
}
|
|
12591
12607
|
for (const entry of entries) {
|
|
12592
|
-
const full =
|
|
12593
|
-
if (!
|
|
12594
|
-
if (
|
|
12608
|
+
const full = join52(servicesDir, entry);
|
|
12609
|
+
if (!existsSync46(full) || !statSync13(full).isDirectory()) continue;
|
|
12610
|
+
if (existsSync46(join52(full, "biffo.plugin.json"))) {
|
|
12595
12611
|
result.add(entry);
|
|
12596
12612
|
}
|
|
12597
12613
|
}
|
|
@@ -12613,7 +12629,7 @@ function findWorkflowFiles(repoRoot) {
|
|
|
12613
12629
|
if (entry === ".github" && relative11.startsWith("services/") && vendoredPluginDirs.has(relative11.slice("services/".length))) {
|
|
12614
12630
|
continue;
|
|
12615
12631
|
}
|
|
12616
|
-
const full =
|
|
12632
|
+
const full = join52(dir, entry);
|
|
12617
12633
|
const rel = relative11 ? `${relative11}/${entry}` : entry;
|
|
12618
12634
|
let isDir;
|
|
12619
12635
|
try {
|
|
@@ -12663,7 +12679,7 @@ function checkWorkflowSource(file, rawSource) {
|
|
|
12663
12679
|
}
|
|
12664
12680
|
function checkTerraformInput(repoRoot) {
|
|
12665
12681
|
return findWorkflowFiles(repoRoot).flatMap(
|
|
12666
|
-
(file) => checkWorkflowSource(file, readFileSync36(
|
|
12682
|
+
(file) => checkWorkflowSource(file, readFileSync36(join52(repoRoot, file), "utf8"))
|
|
12667
12683
|
);
|
|
12668
12684
|
}
|
|
12669
12685
|
|
|
@@ -12721,7 +12737,7 @@ function checkWorkflowSource2(file, rawSource) {
|
|
|
12721
12737
|
}
|
|
12722
12738
|
function checkLambdaOutput(repoRoot) {
|
|
12723
12739
|
return findWorkflowFiles(repoRoot).flatMap(
|
|
12724
|
-
(file) => checkWorkflowSource2(file, readFileSync37(
|
|
12740
|
+
(file) => checkWorkflowSource2(file, readFileSync37(join53(repoRoot, file), "utf8"))
|
|
12725
12741
|
);
|
|
12726
12742
|
}
|
|
12727
12743
|
|
|
@@ -12749,8 +12765,8 @@ async function runLambdaOutputCheck() {
|
|
|
12749
12765
|
}
|
|
12750
12766
|
|
|
12751
12767
|
// src/scripts/check-migration-body-change.ts
|
|
12752
|
-
import { existsSync as
|
|
12753
|
-
import { join as
|
|
12768
|
+
import { existsSync as existsSync47 } from "fs";
|
|
12769
|
+
import { join as join54 } from "path";
|
|
12754
12770
|
|
|
12755
12771
|
// src/lib/migration-body-change-guard.ts
|
|
12756
12772
|
function checkMigrationBodyChangeMarkers(diffs) {
|
|
@@ -12816,7 +12832,7 @@ async function runMigrationBodyChangeCheck(argv) {
|
|
|
12816
12832
|
);
|
|
12817
12833
|
return;
|
|
12818
12834
|
}
|
|
12819
|
-
if (!
|
|
12835
|
+
if (!existsSync47(join54(root, MIGRATIONS_VERSIONS_DIR))) {
|
|
12820
12836
|
console.log(`\u2713 migration body-change guard: no ${MIGRATIONS_VERSIONS_DIR} in this repo.`);
|
|
12821
12837
|
return;
|
|
12822
12838
|
}
|
|
@@ -12918,7 +12934,7 @@ ${BOLD2}What to do${OFF2}
|
|
|
12918
12934
|
}
|
|
12919
12935
|
|
|
12920
12936
|
// src/scripts/check-orphan-ratchet.ts
|
|
12921
|
-
import { existsSync as
|
|
12937
|
+
import { existsSync as existsSync48 } from "fs";
|
|
12922
12938
|
import { basename as basename3 } from "path";
|
|
12923
12939
|
function reportOrphan(entry, manifest) {
|
|
12924
12940
|
console.error(` ${entry.path}`);
|
|
@@ -12941,7 +12957,7 @@ function reportOrphan(entry, manifest) {
|
|
|
12941
12957
|
}
|
|
12942
12958
|
}
|
|
12943
12959
|
async function runOrphanRatchetCheck(opts = {}) {
|
|
12944
|
-
if (opts.instanceDir !== void 0 && !
|
|
12960
|
+
if (opts.instanceDir !== void 0 && !existsSync48(opts.instanceDir)) {
|
|
12945
12961
|
console.error(
|
|
12946
12962
|
`\u2717 orphan-ratchet guard: --instance-dir ${opts.instanceDir} does not exist \u2014 cannot tell whether it carries unsanctioned files, and that is not the same as a clean pass.`
|
|
12947
12963
|
);
|
|
@@ -12984,7 +13000,7 @@ baseline was ${String(ratchet.baseline)}, now ${String(ratchet.count)}. See biff
|
|
|
12984
13000
|
|
|
12985
13001
|
// src/scripts/check-pipe-trap.ts
|
|
12986
13002
|
import { readFileSync as readFileSync38, readdirSync as readdirSync22 } from "fs";
|
|
12987
|
-
import { join as
|
|
13003
|
+
import { join as join55, relative as relative9 } from "path";
|
|
12988
13004
|
|
|
12989
13005
|
// src/lib/pipe-trap-guard.ts
|
|
12990
13006
|
var STATUS_BEARING = [
|
|
@@ -13080,7 +13096,7 @@ function findPipeTraps(source) {
|
|
|
13080
13096
|
function shellFiles(root) {
|
|
13081
13097
|
const out = [];
|
|
13082
13098
|
for (const dir of ["scripts", ".githooks"]) {
|
|
13083
|
-
const full =
|
|
13099
|
+
const full = join55(root, dir);
|
|
13084
13100
|
let entries;
|
|
13085
13101
|
try {
|
|
13086
13102
|
entries = readdirSync22(full, { withFileTypes: true });
|
|
@@ -13090,7 +13106,7 @@ function shellFiles(root) {
|
|
|
13090
13106
|
for (const entry of entries) {
|
|
13091
13107
|
if (!entry.isFile()) continue;
|
|
13092
13108
|
if (dir === "scripts" && !entry.name.endsWith(".sh")) continue;
|
|
13093
|
-
out.push(
|
|
13109
|
+
out.push(join55(full, entry.name));
|
|
13094
13110
|
}
|
|
13095
13111
|
}
|
|
13096
13112
|
return out;
|
|
@@ -13124,7 +13140,7 @@ async function runPipeTrapCheck() {
|
|
|
13124
13140
|
|
|
13125
13141
|
// src/lib/plugin-allowlist-convention.ts
|
|
13126
13142
|
import { readFileSync as readFileSync39 } from "fs";
|
|
13127
|
-
import { join as
|
|
13143
|
+
import { join as join56 } from "path";
|
|
13128
13144
|
var COMPUTE_MAIN_TF = "modules/cloud/aws/compute/main.tf";
|
|
13129
13145
|
var PLUGIN_TEMPLATE_MAIN_TF = "modules/plugins/_template/main.tf";
|
|
13130
13146
|
var ALLOWLIST_MAIN_TF = "modules/cloud/aws/plugin-allowlist/main.tf";
|
|
@@ -13135,7 +13151,7 @@ var PLUGIN = "<plugin>";
|
|
|
13135
13151
|
var ACCOUNT = "<account>";
|
|
13136
13152
|
function read(repoRoot, relative11) {
|
|
13137
13153
|
try {
|
|
13138
|
-
return readFileSync39(
|
|
13154
|
+
return readFileSync39(join56(repoRoot, relative11), "utf8");
|
|
13139
13155
|
} catch {
|
|
13140
13156
|
throw new Error(`plugin-allowlist drift guard: cannot read ${relative11}`);
|
|
13141
13157
|
}
|
|
@@ -13256,32 +13272,32 @@ async function runPluginAllowlistConventionCheck() {
|
|
|
13256
13272
|
}
|
|
13257
13273
|
|
|
13258
13274
|
// src/scripts/check-plugin-collisions.ts
|
|
13259
|
-
import { existsSync as
|
|
13260
|
-
import { join as
|
|
13275
|
+
import { existsSync as existsSync50 } from "fs";
|
|
13276
|
+
import { join as join58 } from "path";
|
|
13261
13277
|
|
|
13262
13278
|
// src/lib/plugin-collision-guard.ts
|
|
13263
|
-
import { existsSync as
|
|
13264
|
-
import { join as
|
|
13279
|
+
import { existsSync as existsSync49, readdirSync as readdirSync23, statSync as statSync14 } from "fs";
|
|
13280
|
+
import { join as join57 } from "path";
|
|
13265
13281
|
var PYTEST_SPECIAL = /* @__PURE__ */ new Set(["conftest.py"]);
|
|
13266
13282
|
var IGNORED_DIRS = /* @__PURE__ */ new Set([".venv", "node_modules", "__pycache__", ".git", "dist", "build"]);
|
|
13267
13283
|
function subdirectories(dir) {
|
|
13268
|
-
if (!
|
|
13284
|
+
if (!existsSync49(dir)) return [];
|
|
13269
13285
|
return readdirSync23(dir).filter((entry) => {
|
|
13270
13286
|
if (IGNORED_DIRS.has(entry) || entry.startsWith(".")) return false;
|
|
13271
13287
|
try {
|
|
13272
|
-
return statSync14(
|
|
13288
|
+
return statSync14(join57(dir, entry)).isDirectory();
|
|
13273
13289
|
} catch {
|
|
13274
13290
|
return false;
|
|
13275
13291
|
}
|
|
13276
13292
|
});
|
|
13277
13293
|
}
|
|
13278
13294
|
function regularPackagesOf(pluginDir2) {
|
|
13279
|
-
return subdirectories(pluginDir2).filter((name) =>
|
|
13295
|
+
return subdirectories(pluginDir2).filter((name) => existsSync49(join57(pluginDir2, name, "__init__.py"))).sort();
|
|
13280
13296
|
}
|
|
13281
13297
|
function bareTestModulesOf(pluginDir2) {
|
|
13282
|
-
const testsDir =
|
|
13283
|
-
if (!
|
|
13284
|
-
if (
|
|
13298
|
+
const testsDir = join57(pluginDir2, "tests");
|
|
13299
|
+
if (!existsSync49(testsDir)) return [];
|
|
13300
|
+
if (existsSync49(join57(testsDir, "__init__.py"))) return [];
|
|
13285
13301
|
return readdirSync23(testsDir).filter((f) => f.endsWith(".py") && !PYTEST_SPECIAL.has(f)).sort();
|
|
13286
13302
|
}
|
|
13287
13303
|
function findCollisions(servicesDir, pluginDirs) {
|
|
@@ -13290,7 +13306,7 @@ function findCollisions(servicesDir, pluginDirs) {
|
|
|
13290
13306
|
const gather = (kind, namesOf) => {
|
|
13291
13307
|
const claims = /* @__PURE__ */ new Map();
|
|
13292
13308
|
for (const plugin of plugins) {
|
|
13293
|
-
for (const name of namesOf(
|
|
13309
|
+
for (const name of namesOf(join57(servicesDir, plugin))) {
|
|
13294
13310
|
claims.set(name, [...claims.get(name) ?? [], plugin]);
|
|
13295
13311
|
}
|
|
13296
13312
|
}
|
|
@@ -13328,8 +13344,8 @@ function formatCollisions(collisions) {
|
|
|
13328
13344
|
// src/scripts/check-plugin-collisions.ts
|
|
13329
13345
|
async function runPluginCollisionCheck() {
|
|
13330
13346
|
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
13331
|
-
const servicesDir =
|
|
13332
|
-
if (!
|
|
13347
|
+
const servicesDir = join58(root, "services");
|
|
13348
|
+
if (!existsSync50(servicesDir)) {
|
|
13333
13349
|
console.log("\u2713 plugin collision guard: no services/ directory \u2014 nothing to compare");
|
|
13334
13350
|
return;
|
|
13335
13351
|
}
|
|
@@ -13346,8 +13362,8 @@ async function runPluginCollisionCheck() {
|
|
|
13346
13362
|
}
|
|
13347
13363
|
|
|
13348
13364
|
// src/lib/plugin-terraform-guard.ts
|
|
13349
|
-
import { existsSync as
|
|
13350
|
-
import { dirname as dirname10, join as
|
|
13365
|
+
import { existsSync as existsSync51, readFileSync as readFileSync40, readdirSync as readdirSync24 } from "fs";
|
|
13366
|
+
import { dirname as dirname10, join as join59, relative as relative10, sep as sep4 } from "path";
|
|
13351
13367
|
var SKIP_DIRS3 = /* @__PURE__ */ new Set(["node_modules", ".git", ".worktrees", "dist", ".venv", "__pycache__"]);
|
|
13352
13368
|
var PLUGIN_MANIFEST_FILE2 = "biffo.plugin.json";
|
|
13353
13369
|
function findPluginManifests(root) {
|
|
@@ -13362,9 +13378,9 @@ function findPluginManifests(root) {
|
|
|
13362
13378
|
for (const entry of entries) {
|
|
13363
13379
|
if (entry.isDirectory()) {
|
|
13364
13380
|
if (SKIP_DIRS3.has(entry.name)) continue;
|
|
13365
|
-
walk2(
|
|
13381
|
+
walk2(join59(dir, entry.name));
|
|
13366
13382
|
} else if (entry.isFile() && entry.name === PLUGIN_MANIFEST_FILE2) {
|
|
13367
|
-
found.push(relative10(root,
|
|
13383
|
+
found.push(relative10(root, join59(dir, entry.name)).split(sep4).join("/"));
|
|
13368
13384
|
}
|
|
13369
13385
|
}
|
|
13370
13386
|
};
|
|
@@ -13389,14 +13405,14 @@ function readSubscriptions(absManifestPath) {
|
|
|
13389
13405
|
}
|
|
13390
13406
|
function checkPluginTerraform(root) {
|
|
13391
13407
|
const violations = [];
|
|
13392
|
-
const coreManifest =
|
|
13408
|
+
const coreManifest = existsSync51(join59(root, CORE_MANIFEST_FILE)) ? readCoreManifest(root) : null;
|
|
13393
13409
|
for (const manifest of findPluginManifests(root)) {
|
|
13394
13410
|
if (coreManifest && !isTemplateOwned(manifest, coreManifest)) continue;
|
|
13395
|
-
const absManifest =
|
|
13411
|
+
const absManifest = join59(root, manifest);
|
|
13396
13412
|
const subscriptions = readSubscriptions(absManifest);
|
|
13397
13413
|
if (subscriptions === null) continue;
|
|
13398
13414
|
const pluginDir2 = dirname10(absManifest);
|
|
13399
|
-
if (
|
|
13415
|
+
if (existsSync51(join59(pluginDir2, "terraform"))) continue;
|
|
13400
13416
|
const relPluginDir = relative10(root, pluginDir2).split(sep4).join("/");
|
|
13401
13417
|
violations.push({
|
|
13402
13418
|
manifest,
|
|
@@ -13427,12 +13443,12 @@ async function runPluginTerraformCheck() {
|
|
|
13427
13443
|
}
|
|
13428
13444
|
|
|
13429
13445
|
// src/scripts/check-plugin-tool-supply.ts
|
|
13430
|
-
import { existsSync as
|
|
13431
|
-
import { join as
|
|
13446
|
+
import { existsSync as existsSync53 } from "fs";
|
|
13447
|
+
import { join as join61 } from "path";
|
|
13432
13448
|
|
|
13433
13449
|
// src/lib/plugin-tool-supply-audit.ts
|
|
13434
|
-
import { existsSync as
|
|
13435
|
-
import { join as
|
|
13450
|
+
import { existsSync as existsSync52, readFileSync as readFileSync41, readdirSync as readdirSync25, statSync as statSync15 } from "fs";
|
|
13451
|
+
import { join as join60 } from "path";
|
|
13436
13452
|
|
|
13437
13453
|
// src/lib/openrouter-model-snapshot.ts
|
|
13438
13454
|
var OPENROUTER_MODEL_SNAPSHOT_FETCHED_AT = "2026-08-10T06:39:01Z";
|
|
@@ -13849,7 +13865,7 @@ function listDirs(root) {
|
|
|
13849
13865
|
}
|
|
13850
13866
|
return entries.filter((e) => {
|
|
13851
13867
|
try {
|
|
13852
|
-
return statSync15(
|
|
13868
|
+
return statSync15(join60(root, e)).isDirectory();
|
|
13853
13869
|
} catch {
|
|
13854
13870
|
return false;
|
|
13855
13871
|
}
|
|
@@ -13865,7 +13881,7 @@ function walkFiles2(root, accept, skipDir) {
|
|
|
13865
13881
|
return;
|
|
13866
13882
|
}
|
|
13867
13883
|
for (const entry of entries) {
|
|
13868
|
-
const p =
|
|
13884
|
+
const p = join60(dir, entry);
|
|
13869
13885
|
let st;
|
|
13870
13886
|
try {
|
|
13871
13887
|
st = statSync15(p);
|
|
@@ -13891,14 +13907,14 @@ function pluginPythonFiles(pluginDir2) {
|
|
|
13891
13907
|
);
|
|
13892
13908
|
}
|
|
13893
13909
|
function pluginTerraformFiles(pluginDir2) {
|
|
13894
|
-
const tfDir =
|
|
13910
|
+
const tfDir = join60(pluginDir2, "terraform");
|
|
13895
13911
|
let entries;
|
|
13896
13912
|
try {
|
|
13897
13913
|
entries = readdirSync25(tfDir);
|
|
13898
13914
|
} catch {
|
|
13899
13915
|
return [];
|
|
13900
13916
|
}
|
|
13901
|
-
return entries.filter((e) => e.endsWith(".tf")).map((e) =>
|
|
13917
|
+
return entries.filter((e) => e.endsWith(".tf")).map((e) => join60(tfDir, e)).sort();
|
|
13902
13918
|
}
|
|
13903
13919
|
function extractManifestTools(manifestText) {
|
|
13904
13920
|
let parsed;
|
|
@@ -14150,8 +14166,8 @@ function isSnapshotStale(fetchedAt, now) {
|
|
|
14150
14166
|
function normalizeModelId(id) {
|
|
14151
14167
|
return id.endsWith(":online") ? id.slice(0, -":online".length) : id;
|
|
14152
14168
|
}
|
|
14153
|
-
var CONFIG_PY_PATH =
|
|
14154
|
-
var ORCHESTRATION_SCHEMA_PATH =
|
|
14169
|
+
var CONFIG_PY_PATH = join60("services", "api", "src", "api", "config.py");
|
|
14170
|
+
var ORCHESTRATION_SCHEMA_PATH = join60(
|
|
14155
14171
|
"services",
|
|
14156
14172
|
"api",
|
|
14157
14173
|
"src",
|
|
@@ -14163,10 +14179,10 @@ function auditDeclaredModelIds(repoRoot, options = {}) {
|
|
|
14163
14179
|
const knownModelIds = options.knownModelIds ?? OPENROUTER_MODEL_IDS;
|
|
14164
14180
|
const snapshotFetchedAt = options.snapshotFetchedAt ?? OPENROUTER_MODEL_SNAPSHOT_FETCHED_AT;
|
|
14165
14181
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
14166
|
-
const configPath =
|
|
14167
|
-
const orchestrationPath =
|
|
14168
|
-
const configMissing = !
|
|
14169
|
-
const orchestrationSchemaMissing = !
|
|
14182
|
+
const configPath = join60(repoRoot, CONFIG_PY_PATH);
|
|
14183
|
+
const orchestrationPath = join60(repoRoot, ORCHESTRATION_SCHEMA_PATH);
|
|
14184
|
+
const configMissing = !existsSync52(configPath);
|
|
14185
|
+
const orchestrationSchemaMissing = !existsSync52(orchestrationPath);
|
|
14170
14186
|
const knownSet = new Set(knownModelIds);
|
|
14171
14187
|
const snapshotEmpty = knownModelIds.length === 0;
|
|
14172
14188
|
const snapshotStale = isSnapshotStale(snapshotFetchedAt, now);
|
|
@@ -14237,7 +14253,7 @@ function auditDeclaredModelIds(repoRoot, options = {}) {
|
|
|
14237
14253
|
function discoverPluginDirs(pluginsRoot) {
|
|
14238
14254
|
return listDirs(pluginsRoot).filter((name) => {
|
|
14239
14255
|
try {
|
|
14240
|
-
return statSync15(
|
|
14256
|
+
return statSync15(join60(pluginsRoot, name, "biffo.plugin.json")).isFile();
|
|
14241
14257
|
} catch {
|
|
14242
14258
|
return false;
|
|
14243
14259
|
}
|
|
@@ -14250,8 +14266,8 @@ function auditPluginToolSupply(pluginsRoot) {
|
|
|
14250
14266
|
let terraformBlind = false;
|
|
14251
14267
|
let totalDeclaredTools = 0;
|
|
14252
14268
|
for (const name of pluginNames) {
|
|
14253
|
-
const pluginDir2 =
|
|
14254
|
-
const manifestText = readFileSync41(
|
|
14269
|
+
const pluginDir2 = join60(pluginsRoot, name);
|
|
14270
|
+
const manifestText = readFileSync41(join60(pluginDir2, "biffo.plugin.json"), "utf8");
|
|
14255
14271
|
const manifest = extractManifestTools(manifestText);
|
|
14256
14272
|
if (manifest.parseError) {
|
|
14257
14273
|
findings.push({
|
|
@@ -14349,7 +14365,7 @@ function auditPluginToolSupply(pluginsRoot) {
|
|
|
14349
14365
|
requiredEnvVars: envResult.envVars,
|
|
14350
14366
|
missingEnvVars: anyWired ? [] : envResult.envVars,
|
|
14351
14367
|
status: anyWired ? "ok" : "missing-env",
|
|
14352
|
-
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 ${
|
|
14368
|
+
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 ${join60(pluginDir2, "terraform")}, so this deployment can never supply it`
|
|
14353
14369
|
});
|
|
14354
14370
|
}
|
|
14355
14371
|
}
|
|
@@ -14382,8 +14398,8 @@ function auditPluginToolSupply(pluginsRoot) {
|
|
|
14382
14398
|
async function runPluginToolSupplyCheck() {
|
|
14383
14399
|
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
14384
14400
|
let allOk = true;
|
|
14385
|
-
const pluginsRoot =
|
|
14386
|
-
if (!
|
|
14401
|
+
const pluginsRoot = join61(root, "services", "_plugins");
|
|
14402
|
+
if (!existsSync53(pluginsRoot)) {
|
|
14387
14403
|
console.log("\u2713 plugin tool-supply guard: no services/_plugins/ \u2014 nothing to audit");
|
|
14388
14404
|
} else {
|
|
14389
14405
|
const report = auditPluginToolSupply(pluginsRoot);
|
|
@@ -14413,8 +14429,8 @@ async function runPluginToolSupplyCheck() {
|
|
|
14413
14429
|
console.log(`\u2713 plugin tool-supply guard: ${report.summary}`);
|
|
14414
14430
|
}
|
|
14415
14431
|
}
|
|
14416
|
-
const servicesApiRoot =
|
|
14417
|
-
if (!
|
|
14432
|
+
const servicesApiRoot = join61(root, "services", "api");
|
|
14433
|
+
if (!existsSync53(servicesApiRoot)) {
|
|
14418
14434
|
console.log("\u2713 plugin model-id guard: no services/api/ \u2014 nothing to audit");
|
|
14419
14435
|
} else {
|
|
14420
14436
|
const modelReport = auditDeclaredModelIds(root);
|
|
@@ -14791,12 +14807,12 @@ async function runSharedFileReductionCheck(args) {
|
|
|
14791
14807
|
}
|
|
14792
14808
|
|
|
14793
14809
|
// src/scripts/check-skeleton-drift.ts
|
|
14794
|
-
import { existsSync as
|
|
14795
|
-
import { join as
|
|
14810
|
+
import { existsSync as existsSync54, readdirSync as readdirSync27 } from "fs";
|
|
14811
|
+
import { join as join63 } from "path";
|
|
14796
14812
|
|
|
14797
14813
|
// src/lib/skeleton-drift-guard.ts
|
|
14798
14814
|
import { readFileSync as readFileSync44, readdirSync as readdirSync26, statSync as statSync16 } from "fs";
|
|
14799
|
-
import { join as
|
|
14815
|
+
import { join as join62 } from "path";
|
|
14800
14816
|
var isWorkflow = (rel) => rel.startsWith(".github/workflows/") && (rel.endsWith(".yml") || rel.endsWith(".yaml"));
|
|
14801
14817
|
var isRootLayout = (rel) => rel.endsWith("src/app/layout.tsx");
|
|
14802
14818
|
var uncommented = (contents) => contents.split("\n").filter((line) => !/^\s*(\/\/|\/\*|\*)/.test(line)).join("\n");
|
|
@@ -14860,7 +14876,7 @@ function walk(dir, base = dir) {
|
|
|
14860
14876
|
}
|
|
14861
14877
|
for (const entry of entries) {
|
|
14862
14878
|
if (entry === ".venv" || entry === "node_modules" || entry === ".git") continue;
|
|
14863
|
-
const abs =
|
|
14879
|
+
const abs = join62(dir, entry);
|
|
14864
14880
|
let isDir;
|
|
14865
14881
|
try {
|
|
14866
14882
|
isDir = statSync16(abs).isDirectory();
|
|
@@ -14882,7 +14898,7 @@ function auditSkeleton(skeletonRoot, name, rules = SKELETON_RULES) {
|
|
|
14882
14898
|
if (!rule.appliesTo(rel)) continue;
|
|
14883
14899
|
let contents;
|
|
14884
14900
|
try {
|
|
14885
|
-
contents = readFileSync44(
|
|
14901
|
+
contents = readFileSync44(join62(skeletonRoot, rel), "utf8");
|
|
14886
14902
|
} catch {
|
|
14887
14903
|
continue;
|
|
14888
14904
|
}
|
|
@@ -14911,23 +14927,23 @@ function formatViolations2(violations) {
|
|
|
14911
14927
|
|
|
14912
14928
|
// src/scripts/check-skeleton-drift.ts
|
|
14913
14929
|
function discoverSkeletons(root) {
|
|
14914
|
-
const skeletonsDir =
|
|
14930
|
+
const skeletonsDir = join63(root, "_skeletons");
|
|
14915
14931
|
let entries;
|
|
14916
14932
|
try {
|
|
14917
14933
|
entries = readdirSync27(skeletonsDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
14918
14934
|
} catch {
|
|
14919
14935
|
return [];
|
|
14920
14936
|
}
|
|
14921
|
-
return entries.filter((name) =>
|
|
14937
|
+
return entries.filter((name) => existsSync54(join63(skeletonsDir, name, ".github", "workflows", "ci.yml"))).sort();
|
|
14922
14938
|
}
|
|
14923
14939
|
async function runSkeletonDriftCheck() {
|
|
14924
14940
|
const root = (await execa("git", ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
14925
14941
|
const skeletons = discoverSkeletons(root);
|
|
14926
14942
|
let filesConsidered = 0;
|
|
14927
14943
|
for (const name of skeletons) {
|
|
14928
|
-
const skeletonRoot =
|
|
14944
|
+
const skeletonRoot = join63(root, "_skeletons", name);
|
|
14929
14945
|
filesConsidered += findWorkflowFiles(skeletonRoot).length;
|
|
14930
|
-
if (
|
|
14946
|
+
if (existsSync54(join63(skeletonRoot, "apps", "frontend", "src", "app", "layout.tsx"))) {
|
|
14931
14947
|
filesConsidered += 1;
|
|
14932
14948
|
}
|
|
14933
14949
|
}
|
|
@@ -14941,7 +14957,7 @@ async function runSkeletonDriftCheck() {
|
|
|
14941
14957
|
process.exit(1);
|
|
14942
14958
|
}
|
|
14943
14959
|
const violations = skeletons.flatMap(
|
|
14944
|
-
(name) => auditSkeleton(
|
|
14960
|
+
(name) => auditSkeleton(join63(root, "_skeletons", name), name)
|
|
14945
14961
|
);
|
|
14946
14962
|
if (violations.length > 0) {
|
|
14947
14963
|
console.error("\u2717 Skeleton-drift guard: drift found between this repo and its scaffolding\n");
|
|
@@ -15132,8 +15148,8 @@ function rawArgsAfter(subcommand) {
|
|
|
15132
15148
|
}
|
|
15133
15149
|
|
|
15134
15150
|
// src/commands/doctor.ts
|
|
15135
|
-
import { existsSync as
|
|
15136
|
-
import { join as
|
|
15151
|
+
import { existsSync as existsSync55, readFileSync as readFileSync45 } from "fs";
|
|
15152
|
+
import { join as join64, resolve as resolve20 } from "path";
|
|
15137
15153
|
import chalk21 from "chalk";
|
|
15138
15154
|
import { Command as Command25 } from "commander";
|
|
15139
15155
|
|
|
@@ -15528,8 +15544,8 @@ async function runDoctorFixBranches(cwd, facts, deps = { git: new GitAdapter(),
|
|
|
15528
15544
|
return reapAllBareBranches(cwd, facts.branches, facts.worktrees, facts.currentBranch, deps);
|
|
15529
15545
|
}
|
|
15530
15546
|
function readLocalCoreVersion(cwd) {
|
|
15531
|
-
const path =
|
|
15532
|
-
if (!
|
|
15547
|
+
const path = join64(cwd, INSTANCE_CORE_FILE);
|
|
15548
|
+
if (!existsSync55(path)) return null;
|
|
15533
15549
|
try {
|
|
15534
15550
|
return extractVersionField(readFileSync45(path, "utf8"));
|
|
15535
15551
|
} catch {
|
|
@@ -15551,8 +15567,8 @@ function extractVersionField(contents) {
|
|
|
15551
15567
|
return match?.[1] ?? null;
|
|
15552
15568
|
}
|
|
15553
15569
|
function readFossil(cwd) {
|
|
15554
|
-
const path =
|
|
15555
|
-
if (!
|
|
15570
|
+
const path = join64(cwd, CORE_VERSION_FILE);
|
|
15571
|
+
if (!existsSync55(path)) return null;
|
|
15556
15572
|
try {
|
|
15557
15573
|
const value = readFileSync45(path, "utf8").trim();
|
|
15558
15574
|
return value === "" ? null : value;
|
|
@@ -16083,13 +16099,13 @@ import { fileURLToPath as fileURLToPath6 } from "url";
|
|
|
16083
16099
|
import { Command as Command27 } from "commander";
|
|
16084
16100
|
|
|
16085
16101
|
// src/lib/packaged-scripts.ts
|
|
16086
|
-
import { existsSync as
|
|
16087
|
-
import { dirname as dirname11, join as
|
|
16102
|
+
import { existsSync as existsSync56 } from "fs";
|
|
16103
|
+
import { dirname as dirname11, join as join65 } from "path";
|
|
16088
16104
|
function findPackagedScript(startDir, relativePath) {
|
|
16089
16105
|
let dir = startDir;
|
|
16090
16106
|
for (; ; ) {
|
|
16091
|
-
const candidate =
|
|
16092
|
-
if (
|
|
16107
|
+
const candidate = join65(dir, relativePath);
|
|
16108
|
+
if (existsSync56(candidate)) return candidate;
|
|
16093
16109
|
const parent = dirname11(dir);
|
|
16094
16110
|
if (parent === dir) return null;
|
|
16095
16111
|
dir = parent;
|
package/package.json
CHANGED
package/scripts/verify.sh
CHANGED
|
@@ -1413,6 +1413,16 @@ if [ -f scripts/biffo.sh ]; then
|
|
|
1413
1413
|
run_check plugin-tool-supply sh scripts/biffo.sh check plugin-tool-supply
|
|
1414
1414
|
run_check core-direct-paths sh scripts/biffo.sh check core-direct-paths
|
|
1415
1415
|
run_check orphan-ratchet sh scripts/biffo.sh check orphan-ratchet
|
|
1416
|
+
# #1714 second remediation: the INSTANCE-mode caller, distinct from the
|
|
1417
|
+
# self-check above. It clones a real template tree pinned to
|
|
1418
|
+
# biffo.core.json's own version and compares against it -- but this repo
|
|
1419
|
+
# never carries biffo.core.json (it is the template, not an instance), so
|
|
1420
|
+
# the script itself detects that and exits 0 as a genuine skip (see its own
|
|
1421
|
+
# doc comment) rather than attempting a comparison it has no tree for. Kept
|
|
1422
|
+
# unconditional, exactly like the line above, for the same reason: ci.yml's
|
|
1423
|
+
# exact command text must appear in `verify.sh --list`'s output or the
|
|
1424
|
+
# parity test (verify-parity.test.ts, #1773) reports it uncategorised.
|
|
1425
|
+
run_check orphan-ratchet-instance sh scripts/check-orphan-ratchet-instance.sh
|
|
1416
1426
|
run_check cognito-invite sh scripts/biffo.sh check cognito-invite-template
|
|
1417
1427
|
run_check lambda-output sh scripts/biffo.sh check lambda-output
|
|
1418
1428
|
run_check pipe-trap sh scripts/biffo.sh check pipe-trap
|
|
@@ -1453,6 +1463,18 @@ fi
|
|
|
1453
1463
|
[ -f scripts/allocate-module-number.test.sh ] &&
|
|
1454
1464
|
run_check allocate-module-number sh scripts/allocate-module-number.test.sh
|
|
1455
1465
|
|
|
1466
|
+
# check-orphan-ratchet-instance.sh's own self-test (#1714, second
|
|
1467
|
+
# remediation): real throwaway git fixtures standing in for "the template at
|
|
1468
|
+
# a pinned version" and "a live instance", exercising the wrapper end to end
|
|
1469
|
+
# via THIS repo's own already-built local CLI through tsx (no mocking of
|
|
1470
|
+
# planCoreUpgrade/classify()). Needs cli/node_modules/.bin/tsx -- present
|
|
1471
|
+
# once `pnpm install` has run in this checkout, same as every other
|
|
1472
|
+
# JS-backed check above; the test itself fails with a clear "run pnpm
|
|
1473
|
+
# install" message rather than a cryptic tsx-not-found if it hasn't.
|
|
1474
|
+
# Measured here: ~1.6s.
|
|
1475
|
+
[ -f scripts/check-orphan-ratchet-instance.test.sh ] &&
|
|
1476
|
+
run_check orphan-ratchet-instance-selftest sh scripts/check-orphan-ratchet-instance.test.sh
|
|
1477
|
+
|
|
1456
1478
|
# The append-only corpus guard (#778). CI runs it in Release Guards, and it was
|
|
1457
1479
|
# invisible to the parity test until #897 widened the harvester -- it is neither
|
|
1458
1480
|
# `pnpm`, `uv`, `terraform` nor `sh scripts/`, so the guard whose property is
|