@attalabs/vinaya 0.19.3 → 0.20.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/README.md +7 -0
- package/aeg-root/contracts/archivist-tranche-archivist.md +2 -2
- package/aeg-root/contracts/tranche-archivist-planner.md +8 -8
- package/aeg-root/enforcement.md +6 -4
- package/aeg-root/process.md +5 -5
- package/aeg-root/roles/archivist.md +9 -10
- package/aeg-root/roles/brief-author.md +1 -1
- package/aeg-root/roles/developer.md +1 -1
- package/aeg-root/roles/planner.md +1 -1
- package/aeg-root/roles/principal.md +1 -1
- package/aeg-root/roles/tranche-archivist.md +3 -16
- package/aeg-root/skills/aeg/SKILL.md +30 -1
- package/aeg-root/skills/aeg-roles/SKILL.md +1 -1
- package/aeg-root/skills/brief-authoring/SKILL.md +2 -2
- package/aeg-root/state-machine.md +8 -6
- package/aeg-root/task-model.md +1 -1
- package/aeg-root/templates/pr-report-template.md +4 -0
- package/dist/checks/bin/check-body-bare-digits.js +192 -27
- package/dist/checks/bin/check-branch-topology.js +518 -11
- package/dist/checks/bin/check-brief-shape.js +104 -11
- package/dist/checks/bin/check-closes-n.js +518 -11
- package/dist/checks/bin/check-coherence.js +526 -12
- package/dist/checks/bin/check-dead-branch-push.js +104 -11
- package/dist/checks/bin/check-dispatch-readiness.js +621 -14
- package/dist/checks/bin/check-doc-coverage-push.js +170 -20
- package/dist/checks/bin/check-doc-coverage.js +170 -20
- package/dist/checks/bin/check-doctrine-portability.js +112 -12
- package/dist/checks/bin/check-evidence-fresh.js +213 -20
- package/dist/checks/bin/check-first-push-dispatch.js +526 -12
- package/dist/checks/bin/check-issue-assignment.js +518 -11
- package/dist/checks/bin/check-main-branch-refusal.js +3724 -0
- package/dist/checks/bin/check-no-disk-state.js +104 -11
- package/dist/checks/bin/check-reader-resolvable-prose.js +186 -17
- package/dist/checks/bin/check-registry-gates.js +185 -16
- package/dist/checks/bin/check-retired-vocabulary.js +185 -16
- package/dist/checks/bin/check-review-gate.js +112 -12
- package/dist/checks/bin/check-single-plan-pr.js +104 -11
- package/dist/checks/bin/check-test-plan.js +104 -11
- package/dist/checks/bin/check-workspace-escape.js +104 -11
- package/dist/index.js +664 -56
- package/package.json +1 -1
- package/studio-standalone/_node_modules/@attalabs/aeg-core/bin/verify-coherence.ts +1089 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/required-server-files.json +5 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/api/coherence/route.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/api/coherence/route.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/{[externals]__0pvgf28._.js → [externals]__1agj1ww._.js} +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/[root-of-the-server]__02a-3g8._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/1q96_modules_@clerk_nextjs_dist_esm_app-router_client_keyless-creator-reader_0lom2js.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0053k9k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0112h-k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0o771t1._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0puovz5._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__03jepya._.js → [root-of-the-server]__16cuydh._.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1wc4-ip._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_03x_w6q._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0gvm3og._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0lwxg63._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1n0cnq-._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3noqvds-2bvrd.js → 0ea8-8nopz29h.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0la0hhmjprdxm.css +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1lk7h-0buf4ab.js +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3gehliafvmjo9.js → 2twnwe77d4n-m.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/server.js +1 -1
- package/aeg-root/coordination.md +0 -292
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/2iysedx-n06xc.js +0 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/42wxpzjhw7oy4.css +0 -1
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{5Lv83SnT--7YJDjSbxona → b2VfZK2AItZwlghK_pUN0}/_buildManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{5Lv83SnT--7YJDjSbxona → b2VfZK2AItZwlghK_pUN0}/_clientMiddlewareManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{5Lv83SnT--7YJDjSbxona → b2VfZK2AItZwlghK_pUN0}/_ssgManifest.js +0 -0
|
@@ -5,17 +5,17 @@ import { execFileSync as execFileSync4 } from "node:child_process";
|
|
|
5
5
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
6
6
|
// ../../packages/aeg-core/src/gate-audience.ts
|
|
7
7
|
var GATE_AUDIENCE = {
|
|
8
|
-
"check-branch-topology": { shippedAs: "branch-topology" },
|
|
9
|
-
"check-first-push-dispatch": { shippedAs: "first-push-dispatch" },
|
|
10
|
-
"check-no-disk-state": { shippedAs: "no-disk-state" },
|
|
11
|
-
"verify-brief": { shippedAs: "brief-shape" },
|
|
12
|
-
"verify-coherence": { shippedAs: "coherence" },
|
|
13
|
-
"verify-dispatch": { shippedAs: "dispatch-readiness" },
|
|
14
|
-
"verify-docs": { shippedAs: ["doc-coverage", "doc-coverage-push"] },
|
|
15
|
-
"verify-registry": { shippedAs: "registry-gates" },
|
|
16
|
-
"verify-review-gate": { shippedAs: "review-gate" },
|
|
17
|
-
"verify-single-plan-pr": { shippedAs: "single-plan-pr" },
|
|
18
|
-
"verify-test-plan": { shippedAs: "test-plan" },
|
|
8
|
+
"check-branch-topology": { shippedAs: "branch-topology", ring: 0 },
|
|
9
|
+
"check-first-push-dispatch": { shippedAs: "first-push-dispatch", ring: 0 },
|
|
10
|
+
"check-no-disk-state": { shippedAs: "no-disk-state", ring: 0 },
|
|
11
|
+
"verify-brief": { shippedAs: "brief-shape", ring: 0 },
|
|
12
|
+
"verify-coherence": { shippedAs: "coherence", ring: 0 },
|
|
13
|
+
"verify-dispatch": { shippedAs: "dispatch-readiness", ring: 0 },
|
|
14
|
+
"verify-docs": { shippedAs: ["doc-coverage", "doc-coverage-push"], ring: 0 },
|
|
15
|
+
"verify-registry": { shippedAs: "registry-gates", ring: 0 },
|
|
16
|
+
"verify-review-gate": { shippedAs: "review-gate", ring: 1 },
|
|
17
|
+
"verify-single-plan-pr": { shippedAs: "single-plan-pr", ring: 0 },
|
|
18
|
+
"verify-test-plan": { shippedAs: "test-plan", ring: 1 },
|
|
19
19
|
"check-direct-main-push": {
|
|
20
20
|
internal: "Reaches adopters through `vinaya audit --only=direct-push`, not the check registry: it is a ring-2 sweep over merge history keyed on `GITHUB_SHA`, run by the generated archivist job on push to the default branch. It has no diff to key on, so there is nothing for `vinaya check` to run it against."
|
|
21
21
|
},
|
|
@@ -327,6 +327,13 @@ var LABELS = [
|
|
|
327
327
|
form: "literal",
|
|
328
328
|
carries: "Execution is halted pending an external unblock; wins over every other derived status."
|
|
329
329
|
},
|
|
330
|
+
{
|
|
331
|
+
key: "backlog",
|
|
332
|
+
id: "vinaya/backlog",
|
|
333
|
+
category: "state",
|
|
334
|
+
form: "literal",
|
|
335
|
+
carries: "The Issue is deliberately unplanned — belongs to no tranche and is excluded from dispatch, until a Planner promotes it."
|
|
336
|
+
},
|
|
330
337
|
{
|
|
331
338
|
key: "tier-0",
|
|
332
339
|
id: "vinaya/tier:0",
|
|
@@ -1985,7 +1992,59 @@ function overrideActive(opts) {
|
|
|
1985
1992
|
return false;
|
|
1986
1993
|
}
|
|
1987
1994
|
// ../../packages/aeg-core/src/premise-check.ts
|
|
1995
|
+
import { createHash } from "node:crypto";
|
|
1988
1996
|
var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
|
|
1997
|
+
function isPremiseHeader(line) {
|
|
1998
|
+
const stripped = line.replace(/[*#]/g, "").trim();
|
|
1999
|
+
return /^premise\s*:?$/i.test(stripped);
|
|
2000
|
+
}
|
|
2001
|
+
var PREMISE_LINE = /^[-*]\s*(\S+)\s+(contains|absent|sha256)\s*:\s*(.+)$/i;
|
|
2002
|
+
function parsePremiseBlock(prBody) {
|
|
2003
|
+
const searchIn = anchoredRegion(prBody, "PREMISE") ?? prBody;
|
|
2004
|
+
const lines = searchIn.split(/\r?\n/);
|
|
2005
|
+
const assertions = [];
|
|
2006
|
+
let inBlock = false;
|
|
2007
|
+
for (const raw of lines) {
|
|
2008
|
+
const line = raw.trim();
|
|
2009
|
+
if (!inBlock) {
|
|
2010
|
+
if (isPremiseHeader(line))
|
|
2011
|
+
inBlock = true;
|
|
2012
|
+
continue;
|
|
2013
|
+
}
|
|
2014
|
+
if (line === "")
|
|
2015
|
+
break;
|
|
2016
|
+
const m = line.match(PREMISE_LINE);
|
|
2017
|
+
if (!m)
|
|
2018
|
+
break;
|
|
2019
|
+
const [, path, kindRaw, value] = m;
|
|
2020
|
+
const kind = kindRaw.toLowerCase();
|
|
2021
|
+
if (!ASSERTION_KINDS.has(kind))
|
|
2022
|
+
continue;
|
|
2023
|
+
assertions.push({ kind, path, value: value.trim() });
|
|
2024
|
+
}
|
|
2025
|
+
return assertions;
|
|
2026
|
+
}
|
|
2027
|
+
function checkPremises(assertions, fileReader) {
|
|
2028
|
+
const failures = [];
|
|
2029
|
+
for (const a of assertions) {
|
|
2030
|
+
const content = fileReader(a.path);
|
|
2031
|
+
if (content === null) {
|
|
2032
|
+
failures.push(`premise-check: ${a.path} does not exist on disk (premise asserted \`${a.kind}: ${a.value}\`) — the surface moved since this brief was authored; re-dig before proceeding.`);
|
|
2033
|
+
continue;
|
|
2034
|
+
}
|
|
2035
|
+
if (a.kind === "contains" && !content.includes(a.value)) {
|
|
2036
|
+
failures.push(`premise-check: ${a.path} no longer contains "${a.value}" — the premise this brief pinned has moved; re-dig before proceeding.`);
|
|
2037
|
+
} else if (a.kind === "absent" && content.includes(a.value)) {
|
|
2038
|
+
failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
|
|
2039
|
+
} else if (a.kind === "sha256") {
|
|
2040
|
+
const actual = createHash("sha256").update(content).digest("hex");
|
|
2041
|
+
if (actual !== a.value.toLowerCase()) {
|
|
2042
|
+
failures.push(`premise-check: ${a.path} sha256 mismatch (brief pinned ${a.value}, file is now ${actual}) — the file changed since this brief was authored; re-dig before proceeding.`);
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
return { pass: failures.length === 0, failures };
|
|
2047
|
+
}
|
|
1989
2048
|
|
|
1990
2049
|
// ../../packages/aeg-core/src/test-plan-section.ts
|
|
1991
2050
|
var HEADING_FORM_RE = /^#{1,4}[ \t]*(?:\d+[a-z]?\.[ \t]*)?\*{0,2}Test Plan\*{0,2}[ \t]*$/im;
|
|
@@ -2789,6 +2848,7 @@ function checkG1(rows, existsFn) {
|
|
|
2789
2848
|
}
|
|
2790
2849
|
return { check: "G1", status: findings.length > 0 ? "fail" : "pass", findings };
|
|
2791
2850
|
}
|
|
2851
|
+
var SCAFFOLD_PLACEHOLDER = "[undocumented — fill in why]";
|
|
2792
2852
|
function checkG2(rows, candidateFiles) {
|
|
2793
2853
|
const implementations = new Set(rows.map((r) => r.implementation).filter((p) => p !== ""));
|
|
2794
2854
|
const findings = [];
|
|
@@ -2800,6 +2860,16 @@ function checkG2(rows, candidateFiles) {
|
|
|
2800
2860
|
});
|
|
2801
2861
|
}
|
|
2802
2862
|
}
|
|
2863
|
+
for (const row of rows) {
|
|
2864
|
+
const carriesPlaceholder = [row.summary, row.description, row.spec].some((cell) => cell === SCAFFOLD_PLACEHOLDER);
|
|
2865
|
+
if (carriesPlaceholder) {
|
|
2866
|
+
findings.push({
|
|
2867
|
+
row: row.action,
|
|
2868
|
+
path: row.implementation,
|
|
2869
|
+
reason: `${row.ring} row "${row.action}" still carries the scaffold placeholder marker — the why is owed`
|
|
2870
|
+
});
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2803
2873
|
return { check: "G2", status: findings.length > 0 ? "info" : "pass", findings };
|
|
2804
2874
|
}
|
|
2805
2875
|
function checkG3(ring0Rows, crossingFiles) {
|
|
@@ -3319,6 +3389,29 @@ function isNewDiskStateFile(path, status) {
|
|
|
3319
3389
|
return false;
|
|
3320
3390
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
3321
3391
|
}
|
|
3392
|
+
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
3393
|
+
function checkMainBranchRefusal(facts) {
|
|
3394
|
+
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
3395
|
+
if (currentSymbolicBranch === null)
|
|
3396
|
+
return null;
|
|
3397
|
+
if (defaultBranch === null) {
|
|
3398
|
+
return {
|
|
3399
|
+
reason: "default-branch-undetermined",
|
|
3400
|
+
severity: "warning",
|
|
3401
|
+
currentBranch: currentSymbolicBranch,
|
|
3402
|
+
defaultBranch: null
|
|
3403
|
+
};
|
|
3404
|
+
}
|
|
3405
|
+
if (currentSymbolicBranch === defaultBranch) {
|
|
3406
|
+
return {
|
|
3407
|
+
reason: "on-default-branch",
|
|
3408
|
+
severity: "error",
|
|
3409
|
+
currentBranch: currentSymbolicBranch,
|
|
3410
|
+
defaultBranch
|
|
3411
|
+
};
|
|
3412
|
+
}
|
|
3413
|
+
return null;
|
|
3414
|
+
}
|
|
3322
3415
|
// ../../packages/aeg-core/src/branch-topology-gate.ts
|
|
3323
3416
|
function taskBranchTopologyFields(branch) {
|
|
3324
3417
|
if (!/^task\/.*\/.*$/.test(branch))
|
|
@@ -3574,6 +3667,7 @@ function findWorkspaceEscapes(files, knownPaths, workspaceDirs = DEFAULT_WORKSPA
|
|
|
3574
3667
|
}
|
|
3575
3668
|
// src/lib/diff-evidence.ts
|
|
3576
3669
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
3670
|
+
import { join } from "node:path";
|
|
3577
3671
|
function fileDiffAgainst(ref, path) {
|
|
3578
3672
|
let out;
|
|
3579
3673
|
try {
|
|
@@ -3586,6 +3680,55 @@ function fileDiffAgainst(ref, path) {
|
|
|
3586
3680
|
}
|
|
3587
3681
|
return out === "" ? null : out;
|
|
3588
3682
|
}
|
|
3683
|
+
function revParse(ref) {
|
|
3684
|
+
try {
|
|
3685
|
+
return execFileSync2("git", ["rev-parse", "--verify", ref], {
|
|
3686
|
+
encoding: "utf8",
|
|
3687
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3688
|
+
}).trim();
|
|
3689
|
+
} catch {
|
|
3690
|
+
return null;
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3693
|
+
function repoRoot() {
|
|
3694
|
+
try {
|
|
3695
|
+
return execFileSync2("git", ["rev-parse", "--show-toplevel"], {
|
|
3696
|
+
encoding: "utf8",
|
|
3697
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3698
|
+
}).trim();
|
|
3699
|
+
} catch {
|
|
3700
|
+
return null;
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
function changedFiles(base) {
|
|
3704
|
+
let out;
|
|
3705
|
+
try {
|
|
3706
|
+
out = execFileSync2("git", ["diff", "--name-only", `${base}...HEAD`], {
|
|
3707
|
+
encoding: "utf8",
|
|
3708
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3709
|
+
}).trim();
|
|
3710
|
+
} catch {
|
|
3711
|
+
return null;
|
|
3712
|
+
}
|
|
3713
|
+
return out === "" ? [] : out.split(`
|
|
3714
|
+
`).map((s) => s.trim()).filter(Boolean);
|
|
3715
|
+
}
|
|
3716
|
+
function resolveChangedFiles(base = process.env.BASE_SHA || "origin/main") {
|
|
3717
|
+
const root = repoRoot();
|
|
3718
|
+
if (root === null)
|
|
3719
|
+
return null;
|
|
3720
|
+
const head = revParse("HEAD");
|
|
3721
|
+
for (const ref of [base, "main"]) {
|
|
3722
|
+
const resolved = revParse(ref);
|
|
3723
|
+
if (resolved === null || resolved === head)
|
|
3724
|
+
continue;
|
|
3725
|
+
const relPaths = changedFiles(ref);
|
|
3726
|
+
if (relPaths === null)
|
|
3727
|
+
continue;
|
|
3728
|
+
return relPaths.map((p) => join(root, p));
|
|
3729
|
+
}
|
|
3730
|
+
return null;
|
|
3731
|
+
}
|
|
3589
3732
|
|
|
3590
3733
|
// src/checks/contract.ts
|
|
3591
3734
|
var CHECK_SCHEMA_VERSION = 1;
|
|
@@ -3598,7 +3741,7 @@ function emitCheckError(error) {
|
|
|
3598
3741
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
3599
3742
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3600
3743
|
import { homedir } from "node:os";
|
|
3601
|
-
import { dirname, join } from "node:path";
|
|
3744
|
+
import { dirname, join as join2 } from "node:path";
|
|
3602
3745
|
import { z } from "zod";
|
|
3603
3746
|
|
|
3604
3747
|
// src/lib/agent-vendors.ts
|
|
@@ -3687,8 +3830,15 @@ function isSafeRepoRelPath(p) {
|
|
|
3687
3830
|
var SafeRepoRelPath = z.string().refine(isSafeRepoRelPath, {
|
|
3688
3831
|
message: "must be a repo-root-relative path with no `..` segment or absolute root"
|
|
3689
3832
|
});
|
|
3833
|
+
var CANONICAL_HOOK_BLOCK_PREFIXES = [".git/", ".husky/", ".vinaya/hooks/", ".claude/hooks/"];
|
|
3834
|
+
function isCanonicalHookBlockPath(p) {
|
|
3835
|
+
return CANONICAL_HOOK_BLOCK_PREFIXES.some((prefix) => p.startsWith(prefix) && p.length > prefix.length);
|
|
3836
|
+
}
|
|
3837
|
+
var ManagedHookBlockPath = SafeRepoRelPath.refine(isCanonicalHookBlockPath, {
|
|
3838
|
+
message: `must start with one of ${CANONICAL_HOOK_BLOCK_PREFIXES.join(", ")} (byte-exact, case-sensitive)`
|
|
3839
|
+
});
|
|
3690
3840
|
var ManagedBlockRecordSchema = z.object({
|
|
3691
|
-
path:
|
|
3841
|
+
path: ManagedHookBlockPath,
|
|
3692
3842
|
marker: z.string(),
|
|
3693
3843
|
comment: z.enum(["hash", "html"])
|
|
3694
3844
|
});
|
|
@@ -3719,16 +3869,16 @@ var VinayaConfigSchema = z.object({
|
|
|
3719
3869
|
legacySlugDir: z.string().min(1).optional()
|
|
3720
3870
|
}).optional()
|
|
3721
3871
|
});
|
|
3722
|
-
var GLOBAL_VINAYA_HOME =
|
|
3723
|
-
var GLOBAL_CONFIG_PATH =
|
|
3872
|
+
var GLOBAL_VINAYA_HOME = join2(homedir(), ".vinaya");
|
|
3873
|
+
var GLOBAL_CONFIG_PATH = join2(GLOBAL_VINAYA_HOME, "config.json");
|
|
3724
3874
|
var LOCAL_CONFIG_FILENAME = "vinaya.config.json";
|
|
3725
3875
|
function findLocalConfig() {
|
|
3726
3876
|
let dir = process.cwd();
|
|
3727
3877
|
while (true) {
|
|
3728
|
-
const candidate =
|
|
3878
|
+
const candidate = join2(dir, LOCAL_CONFIG_FILENAME);
|
|
3729
3879
|
if (existsSync(candidate))
|
|
3730
3880
|
return candidate;
|
|
3731
|
-
if (existsSync(
|
|
3881
|
+
if (existsSync(join2(dir, ".git")))
|
|
3732
3882
|
return null;
|
|
3733
3883
|
const parent = dirname(dir);
|
|
3734
3884
|
if (parent === dir)
|
|
@@ -3871,7 +4021,7 @@ function git(args) {
|
|
|
3871
4021
|
return "";
|
|
3872
4022
|
}
|
|
3873
4023
|
}
|
|
3874
|
-
function
|
|
4024
|
+
function changedFiles2(base) {
|
|
3875
4025
|
return git(["diff", "--name-only", `${base}...HEAD`]).split(`
|
|
3876
4026
|
`).map((s) => s.trim()).filter(Boolean);
|
|
3877
4027
|
}
|
|
@@ -3908,10 +4058,10 @@ function main() {
|
|
|
3908
4058
|
}
|
|
3909
4059
|
const base = process.env.BASE_SHA || "origin/main";
|
|
3910
4060
|
let ref = base;
|
|
3911
|
-
let changed =
|
|
4061
|
+
let changed = changedFiles2(ref);
|
|
3912
4062
|
if (changed.length === 0) {
|
|
3913
4063
|
ref = "main";
|
|
3914
|
-
changed =
|
|
4064
|
+
changed = changedFiles2(ref);
|
|
3915
4065
|
}
|
|
3916
4066
|
if (changed.length === 0)
|
|
3917
4067
|
process.exit(0);
|
|
@@ -5,17 +5,17 @@ import { execFileSync as execFileSync4 } from "node:child_process";
|
|
|
5
5
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
6
6
|
// ../../packages/aeg-core/src/gate-audience.ts
|
|
7
7
|
var GATE_AUDIENCE = {
|
|
8
|
-
"check-branch-topology": { shippedAs: "branch-topology" },
|
|
9
|
-
"check-first-push-dispatch": { shippedAs: "first-push-dispatch" },
|
|
10
|
-
"check-no-disk-state": { shippedAs: "no-disk-state" },
|
|
11
|
-
"verify-brief": { shippedAs: "brief-shape" },
|
|
12
|
-
"verify-coherence": { shippedAs: "coherence" },
|
|
13
|
-
"verify-dispatch": { shippedAs: "dispatch-readiness" },
|
|
14
|
-
"verify-docs": { shippedAs: ["doc-coverage", "doc-coverage-push"] },
|
|
15
|
-
"verify-registry": { shippedAs: "registry-gates" },
|
|
16
|
-
"verify-review-gate": { shippedAs: "review-gate" },
|
|
17
|
-
"verify-single-plan-pr": { shippedAs: "single-plan-pr" },
|
|
18
|
-
"verify-test-plan": { shippedAs: "test-plan" },
|
|
8
|
+
"check-branch-topology": { shippedAs: "branch-topology", ring: 0 },
|
|
9
|
+
"check-first-push-dispatch": { shippedAs: "first-push-dispatch", ring: 0 },
|
|
10
|
+
"check-no-disk-state": { shippedAs: "no-disk-state", ring: 0 },
|
|
11
|
+
"verify-brief": { shippedAs: "brief-shape", ring: 0 },
|
|
12
|
+
"verify-coherence": { shippedAs: "coherence", ring: 0 },
|
|
13
|
+
"verify-dispatch": { shippedAs: "dispatch-readiness", ring: 0 },
|
|
14
|
+
"verify-docs": { shippedAs: ["doc-coverage", "doc-coverage-push"], ring: 0 },
|
|
15
|
+
"verify-registry": { shippedAs: "registry-gates", ring: 0 },
|
|
16
|
+
"verify-review-gate": { shippedAs: "review-gate", ring: 1 },
|
|
17
|
+
"verify-single-plan-pr": { shippedAs: "single-plan-pr", ring: 0 },
|
|
18
|
+
"verify-test-plan": { shippedAs: "test-plan", ring: 1 },
|
|
19
19
|
"check-direct-main-push": {
|
|
20
20
|
internal: "Reaches adopters through `vinaya audit --only=direct-push`, not the check registry: it is a ring-2 sweep over merge history keyed on `GITHUB_SHA`, run by the generated archivist job on push to the default branch. It has no diff to key on, so there is nothing for `vinaya check` to run it against."
|
|
21
21
|
},
|
|
@@ -327,6 +327,13 @@ var LABELS = [
|
|
|
327
327
|
form: "literal",
|
|
328
328
|
carries: "Execution is halted pending an external unblock; wins over every other derived status."
|
|
329
329
|
},
|
|
330
|
+
{
|
|
331
|
+
key: "backlog",
|
|
332
|
+
id: "vinaya/backlog",
|
|
333
|
+
category: "state",
|
|
334
|
+
form: "literal",
|
|
335
|
+
carries: "The Issue is deliberately unplanned — belongs to no tranche and is excluded from dispatch, until a Planner promotes it."
|
|
336
|
+
},
|
|
330
337
|
{
|
|
331
338
|
key: "tier-0",
|
|
332
339
|
id: "vinaya/tier:0",
|
|
@@ -1985,7 +1992,59 @@ function overrideActive(opts) {
|
|
|
1985
1992
|
return false;
|
|
1986
1993
|
}
|
|
1987
1994
|
// ../../packages/aeg-core/src/premise-check.ts
|
|
1995
|
+
import { createHash } from "node:crypto";
|
|
1988
1996
|
var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
|
|
1997
|
+
function isPremiseHeader(line) {
|
|
1998
|
+
const stripped = line.replace(/[*#]/g, "").trim();
|
|
1999
|
+
return /^premise\s*:?$/i.test(stripped);
|
|
2000
|
+
}
|
|
2001
|
+
var PREMISE_LINE = /^[-*]\s*(\S+)\s+(contains|absent|sha256)\s*:\s*(.+)$/i;
|
|
2002
|
+
function parsePremiseBlock(prBody) {
|
|
2003
|
+
const searchIn = anchoredRegion(prBody, "PREMISE") ?? prBody;
|
|
2004
|
+
const lines = searchIn.split(/\r?\n/);
|
|
2005
|
+
const assertions = [];
|
|
2006
|
+
let inBlock = false;
|
|
2007
|
+
for (const raw of lines) {
|
|
2008
|
+
const line = raw.trim();
|
|
2009
|
+
if (!inBlock) {
|
|
2010
|
+
if (isPremiseHeader(line))
|
|
2011
|
+
inBlock = true;
|
|
2012
|
+
continue;
|
|
2013
|
+
}
|
|
2014
|
+
if (line === "")
|
|
2015
|
+
break;
|
|
2016
|
+
const m = line.match(PREMISE_LINE);
|
|
2017
|
+
if (!m)
|
|
2018
|
+
break;
|
|
2019
|
+
const [, path, kindRaw, value] = m;
|
|
2020
|
+
const kind = kindRaw.toLowerCase();
|
|
2021
|
+
if (!ASSERTION_KINDS.has(kind))
|
|
2022
|
+
continue;
|
|
2023
|
+
assertions.push({ kind, path, value: value.trim() });
|
|
2024
|
+
}
|
|
2025
|
+
return assertions;
|
|
2026
|
+
}
|
|
2027
|
+
function checkPremises(assertions, fileReader) {
|
|
2028
|
+
const failures = [];
|
|
2029
|
+
for (const a of assertions) {
|
|
2030
|
+
const content = fileReader(a.path);
|
|
2031
|
+
if (content === null) {
|
|
2032
|
+
failures.push(`premise-check: ${a.path} does not exist on disk (premise asserted \`${a.kind}: ${a.value}\`) — the surface moved since this brief was authored; re-dig before proceeding.`);
|
|
2033
|
+
continue;
|
|
2034
|
+
}
|
|
2035
|
+
if (a.kind === "contains" && !content.includes(a.value)) {
|
|
2036
|
+
failures.push(`premise-check: ${a.path} no longer contains "${a.value}" — the premise this brief pinned has moved; re-dig before proceeding.`);
|
|
2037
|
+
} else if (a.kind === "absent" && content.includes(a.value)) {
|
|
2038
|
+
failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
|
|
2039
|
+
} else if (a.kind === "sha256") {
|
|
2040
|
+
const actual = createHash("sha256").update(content).digest("hex");
|
|
2041
|
+
if (actual !== a.value.toLowerCase()) {
|
|
2042
|
+
failures.push(`premise-check: ${a.path} sha256 mismatch (brief pinned ${a.value}, file is now ${actual}) — the file changed since this brief was authored; re-dig before proceeding.`);
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
return { pass: failures.length === 0, failures };
|
|
2047
|
+
}
|
|
1989
2048
|
|
|
1990
2049
|
// ../../packages/aeg-core/src/test-plan-section.ts
|
|
1991
2050
|
var HEADING_FORM_RE = /^#{1,4}[ \t]*(?:\d+[a-z]?\.[ \t]*)?\*{0,2}Test Plan\*{0,2}[ \t]*$/im;
|
|
@@ -2789,6 +2848,7 @@ function checkG1(rows, existsFn) {
|
|
|
2789
2848
|
}
|
|
2790
2849
|
return { check: "G1", status: findings.length > 0 ? "fail" : "pass", findings };
|
|
2791
2850
|
}
|
|
2851
|
+
var SCAFFOLD_PLACEHOLDER = "[undocumented — fill in why]";
|
|
2792
2852
|
function checkG2(rows, candidateFiles) {
|
|
2793
2853
|
const implementations = new Set(rows.map((r) => r.implementation).filter((p) => p !== ""));
|
|
2794
2854
|
const findings = [];
|
|
@@ -2800,6 +2860,16 @@ function checkG2(rows, candidateFiles) {
|
|
|
2800
2860
|
});
|
|
2801
2861
|
}
|
|
2802
2862
|
}
|
|
2863
|
+
for (const row of rows) {
|
|
2864
|
+
const carriesPlaceholder = [row.summary, row.description, row.spec].some((cell) => cell === SCAFFOLD_PLACEHOLDER);
|
|
2865
|
+
if (carriesPlaceholder) {
|
|
2866
|
+
findings.push({
|
|
2867
|
+
row: row.action,
|
|
2868
|
+
path: row.implementation,
|
|
2869
|
+
reason: `${row.ring} row "${row.action}" still carries the scaffold placeholder marker — the why is owed`
|
|
2870
|
+
});
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2803
2873
|
return { check: "G2", status: findings.length > 0 ? "info" : "pass", findings };
|
|
2804
2874
|
}
|
|
2805
2875
|
function checkG3(ring0Rows, crossingFiles) {
|
|
@@ -3319,6 +3389,29 @@ function isNewDiskStateFile(path, status) {
|
|
|
3319
3389
|
return false;
|
|
3320
3390
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
3321
3391
|
}
|
|
3392
|
+
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
3393
|
+
function checkMainBranchRefusal(facts) {
|
|
3394
|
+
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
3395
|
+
if (currentSymbolicBranch === null)
|
|
3396
|
+
return null;
|
|
3397
|
+
if (defaultBranch === null) {
|
|
3398
|
+
return {
|
|
3399
|
+
reason: "default-branch-undetermined",
|
|
3400
|
+
severity: "warning",
|
|
3401
|
+
currentBranch: currentSymbolicBranch,
|
|
3402
|
+
defaultBranch: null
|
|
3403
|
+
};
|
|
3404
|
+
}
|
|
3405
|
+
if (currentSymbolicBranch === defaultBranch) {
|
|
3406
|
+
return {
|
|
3407
|
+
reason: "on-default-branch",
|
|
3408
|
+
severity: "error",
|
|
3409
|
+
currentBranch: currentSymbolicBranch,
|
|
3410
|
+
defaultBranch
|
|
3411
|
+
};
|
|
3412
|
+
}
|
|
3413
|
+
return null;
|
|
3414
|
+
}
|
|
3322
3415
|
// ../../packages/aeg-core/src/branch-topology-gate.ts
|
|
3323
3416
|
function taskBranchTopologyFields(branch) {
|
|
3324
3417
|
if (!/^task\/.*\/.*$/.test(branch))
|
|
@@ -3574,6 +3667,7 @@ function findWorkspaceEscapes(files, knownPaths, workspaceDirs = DEFAULT_WORKSPA
|
|
|
3574
3667
|
}
|
|
3575
3668
|
// src/lib/diff-evidence.ts
|
|
3576
3669
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
3670
|
+
import { join } from "node:path";
|
|
3577
3671
|
function fileDiffAgainst(ref, path) {
|
|
3578
3672
|
let out;
|
|
3579
3673
|
try {
|
|
@@ -3586,6 +3680,55 @@ function fileDiffAgainst(ref, path) {
|
|
|
3586
3680
|
}
|
|
3587
3681
|
return out === "" ? null : out;
|
|
3588
3682
|
}
|
|
3683
|
+
function revParse(ref) {
|
|
3684
|
+
try {
|
|
3685
|
+
return execFileSync2("git", ["rev-parse", "--verify", ref], {
|
|
3686
|
+
encoding: "utf8",
|
|
3687
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3688
|
+
}).trim();
|
|
3689
|
+
} catch {
|
|
3690
|
+
return null;
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3693
|
+
function repoRoot() {
|
|
3694
|
+
try {
|
|
3695
|
+
return execFileSync2("git", ["rev-parse", "--show-toplevel"], {
|
|
3696
|
+
encoding: "utf8",
|
|
3697
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3698
|
+
}).trim();
|
|
3699
|
+
} catch {
|
|
3700
|
+
return null;
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
function changedFiles(base) {
|
|
3704
|
+
let out;
|
|
3705
|
+
try {
|
|
3706
|
+
out = execFileSync2("git", ["diff", "--name-only", `${base}...HEAD`], {
|
|
3707
|
+
encoding: "utf8",
|
|
3708
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3709
|
+
}).trim();
|
|
3710
|
+
} catch {
|
|
3711
|
+
return null;
|
|
3712
|
+
}
|
|
3713
|
+
return out === "" ? [] : out.split(`
|
|
3714
|
+
`).map((s) => s.trim()).filter(Boolean);
|
|
3715
|
+
}
|
|
3716
|
+
function resolveChangedFiles(base = process.env.BASE_SHA || "origin/main") {
|
|
3717
|
+
const root = repoRoot();
|
|
3718
|
+
if (root === null)
|
|
3719
|
+
return null;
|
|
3720
|
+
const head = revParse("HEAD");
|
|
3721
|
+
for (const ref of [base, "main"]) {
|
|
3722
|
+
const resolved = revParse(ref);
|
|
3723
|
+
if (resolved === null || resolved === head)
|
|
3724
|
+
continue;
|
|
3725
|
+
const relPaths = changedFiles(ref);
|
|
3726
|
+
if (relPaths === null)
|
|
3727
|
+
continue;
|
|
3728
|
+
return relPaths.map((p) => join(root, p));
|
|
3729
|
+
}
|
|
3730
|
+
return null;
|
|
3731
|
+
}
|
|
3589
3732
|
|
|
3590
3733
|
// src/checks/contract.ts
|
|
3591
3734
|
var CHECK_SCHEMA_VERSION = 1;
|
|
@@ -3598,7 +3741,7 @@ function emitCheckError(error) {
|
|
|
3598
3741
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
3599
3742
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3600
3743
|
import { homedir } from "node:os";
|
|
3601
|
-
import { dirname, join } from "node:path";
|
|
3744
|
+
import { dirname, join as join2 } from "node:path";
|
|
3602
3745
|
import { z } from "zod";
|
|
3603
3746
|
|
|
3604
3747
|
// src/lib/agent-vendors.ts
|
|
@@ -3687,8 +3830,15 @@ function isSafeRepoRelPath(p) {
|
|
|
3687
3830
|
var SafeRepoRelPath = z.string().refine(isSafeRepoRelPath, {
|
|
3688
3831
|
message: "must be a repo-root-relative path with no `..` segment or absolute root"
|
|
3689
3832
|
});
|
|
3833
|
+
var CANONICAL_HOOK_BLOCK_PREFIXES = [".git/", ".husky/", ".vinaya/hooks/", ".claude/hooks/"];
|
|
3834
|
+
function isCanonicalHookBlockPath(p) {
|
|
3835
|
+
return CANONICAL_HOOK_BLOCK_PREFIXES.some((prefix) => p.startsWith(prefix) && p.length > prefix.length);
|
|
3836
|
+
}
|
|
3837
|
+
var ManagedHookBlockPath = SafeRepoRelPath.refine(isCanonicalHookBlockPath, {
|
|
3838
|
+
message: `must start with one of ${CANONICAL_HOOK_BLOCK_PREFIXES.join(", ")} (byte-exact, case-sensitive)`
|
|
3839
|
+
});
|
|
3690
3840
|
var ManagedBlockRecordSchema = z.object({
|
|
3691
|
-
path:
|
|
3841
|
+
path: ManagedHookBlockPath,
|
|
3692
3842
|
marker: z.string(),
|
|
3693
3843
|
comment: z.enum(["hash", "html"])
|
|
3694
3844
|
});
|
|
@@ -3719,16 +3869,16 @@ var VinayaConfigSchema = z.object({
|
|
|
3719
3869
|
legacySlugDir: z.string().min(1).optional()
|
|
3720
3870
|
}).optional()
|
|
3721
3871
|
});
|
|
3722
|
-
var GLOBAL_VINAYA_HOME =
|
|
3723
|
-
var GLOBAL_CONFIG_PATH =
|
|
3872
|
+
var GLOBAL_VINAYA_HOME = join2(homedir(), ".vinaya");
|
|
3873
|
+
var GLOBAL_CONFIG_PATH = join2(GLOBAL_VINAYA_HOME, "config.json");
|
|
3724
3874
|
var LOCAL_CONFIG_FILENAME = "vinaya.config.json";
|
|
3725
3875
|
function findLocalConfig() {
|
|
3726
3876
|
let dir = process.cwd();
|
|
3727
3877
|
while (true) {
|
|
3728
|
-
const candidate =
|
|
3878
|
+
const candidate = join2(dir, LOCAL_CONFIG_FILENAME);
|
|
3729
3879
|
if (existsSync(candidate))
|
|
3730
3880
|
return candidate;
|
|
3731
|
-
if (existsSync(
|
|
3881
|
+
if (existsSync(join2(dir, ".git")))
|
|
3732
3882
|
return null;
|
|
3733
3883
|
const parent = dirname(dir);
|
|
3734
3884
|
if (parent === dir)
|
|
@@ -3871,7 +4021,7 @@ function git(args) {
|
|
|
3871
4021
|
return "";
|
|
3872
4022
|
}
|
|
3873
4023
|
}
|
|
3874
|
-
function
|
|
4024
|
+
function changedFiles2(base) {
|
|
3875
4025
|
return git(["diff", "--name-only", `${base}...HEAD`]).split(`
|
|
3876
4026
|
`).map((s) => s.trim()).filter(Boolean);
|
|
3877
4027
|
}
|
|
@@ -3930,10 +4080,10 @@ function waiverActive() {
|
|
|
3930
4080
|
function main() {
|
|
3931
4081
|
const base = process.env.BASE_SHA || "origin/main";
|
|
3932
4082
|
let ref = base;
|
|
3933
|
-
let changed =
|
|
4083
|
+
let changed = changedFiles2(ref);
|
|
3934
4084
|
if (changed.length === 0) {
|
|
3935
4085
|
ref = "main";
|
|
3936
|
-
changed =
|
|
4086
|
+
changed = changedFiles2(ref);
|
|
3937
4087
|
}
|
|
3938
4088
|
if (changed.length === 0) {
|
|
3939
4089
|
process.exit(0);
|