mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-23 15:37:44 +00:00
ci(check): cap AGENTS.md at the workspace bootstrap limit
OpenClaw truncates a workspace AGENTS.md above resolveBootstrapMaxChars() (20,000 chars) to a head, a policy digest and a tail. Root AGENTS.md regrew past the cap after #163325 trimmed it. Fail the pre-commit hook, pnpm check and the CI docs check when a tracked AGENTS.md exceeds the cap, and tell the author to cut rules or move them to a scoped guide.
This commit is contained in:
parent
bab3c7d740
commit
7aae97981b
6 changed files with 50 additions and 0 deletions
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
|
|
@ -4553,6 +4553,14 @@ jobs:
|
|||
if: ${{ !cancelled() && steps.node_setup.outcome == 'success' && needs.preflight.outputs.run_format_check == 'true' }}
|
||||
run: pnpm format:check
|
||||
|
||||
- name: Check AGENTS.md bootstrap size
|
||||
if: ${{ !cancelled() && steps.node_setup.outcome == 'success' }}
|
||||
run: |
|
||||
# Historical release targets predate this guard.
|
||||
if node -e 'process.exit(require("./package.json").scripts?.["check:agents-md-size"] ? 0 : 1)'; then
|
||||
pnpm check:agents-md-size
|
||||
fi
|
||||
|
||||
- name: Check config docs baseline
|
||||
if: ${{ !cancelled() && steps.node_setup.outcome == 'success' && needs.preflight.outputs.run_docs_content == 'true' }}
|
||||
run: pnpm config:docs:check
|
||||
|
|
|
|||
|
|
@ -1764,6 +1764,7 @@
|
|||
"channels:catalog:gen": "node scripts/write-official-channel-catalog.mjs --write",
|
||||
"changed:lanes": "node scripts/changed-lanes.mjs",
|
||||
"check": "node --import ./scripts/tsx.mjs scripts/check.mts",
|
||||
"check:agents-md-size": "node --import ./scripts/tsx.mjs scripts/check-agents-md-size.mts",
|
||||
"check:architecture": "pnpm check:import-cycles && pnpm check:madge-import-cycles && pnpm check:deprecated-api-usage && pnpm check:wrapper-shadowing && pnpm check:deprecated-jsdoc && pnpm db:kysely:check && pnpm db:postgres:check && pnpm lint:kysely && pnpm check:database-first-legacy-stores",
|
||||
"check:assertion-safety": "node --import ./scripts/tsx.mjs scripts/check-assertion-safety-ratchet.mts",
|
||||
"check:base-config-schema": "node --import ./scripts/tsx.mjs scripts/generate-base-config-schema.ts --check",
|
||||
|
|
|
|||
31
scripts/check-agents-md-size.mts
Normal file
31
scripts/check-agents-md-size.mts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env node
|
||||
// Keeps tracked AGENTS.md files under the workspace bootstrap cap. Above it,
|
||||
// OpenClaw injects only a head, a policy digest and a tail, so agents miss rules.
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolveBootstrapMaxChars } from "../src/agents/embedded-agent-helpers/bootstrap.ts";
|
||||
|
||||
const maxChars = resolveBootstrapMaxChars();
|
||||
const files = execFileSync("git", ["ls-files", "-z", "--", "AGENTS.md", "*/AGENTS.md"], {
|
||||
encoding: "utf8",
|
||||
})
|
||||
.split("\0")
|
||||
.filter(Boolean);
|
||||
|
||||
let failed = false;
|
||||
for (const file of files) {
|
||||
// The bootstrap trimmer measures UTF-16 length, so match String#length.
|
||||
const chars = readFileSync(file, "utf8").length;
|
||||
if (chars > maxChars) {
|
||||
failed = true;
|
||||
console.error(
|
||||
`${file}: ${chars} chars exceeds the ${maxChars}-char workspace bootstrap cap by ${chars - maxChars}. ` +
|
||||
"Cut rules, or move subsystem rules to the owning scoped AGENTS.md.",
|
||||
);
|
||||
}
|
||||
}
|
||||
if (failed) {
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log(`AGENTS.md size check: ${files.length} files within ${maxChars} chars.`);
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ export const PREFLIGHT_CHECKS: CheckCommand[] = [
|
|||
{ name: "test timeout race ratchet", args: ["check:test-timeout-race-ratchet"], usesBase: true },
|
||||
{ name: "first-party mock export ratchet", args: ["check:test-mock-exports"], usesBase: true },
|
||||
{ name: "changelog attributions", args: ["check:changelog-attributions"] },
|
||||
{ name: "AGENTS.md bootstrap size", args: ["check:agents-md-size"] },
|
||||
{ name: "database-first legacy-store guard", args: ["check:database-first-legacy-stores"] },
|
||||
{ name: "doctor deprecation registry", args: ["check:doctor-deprecation-registry"] },
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ type FreshnessCheck = { name: string; args: string[]; fix: string };
|
|||
const DOCS_MARKDOWN_PATH_RE = /^(?:docs\/.+\.mdx?|README\.md)$/u;
|
||||
const NATIVE_I18N_INPUT_PATH_RE =
|
||||
/^(?:apps\/|scripts\/(?:native-app-i18n|native-i18n-(?:inventory|locales)|android-app-i18n|apple-app-i18n)\.ts$)/u;
|
||||
const AGENTS_MD_PATH_RE = /(?:^|\/)AGENTS\.md$/u;
|
||||
const LINE_CAP_INPUT_PATH_RE = /\.(?:ts|tsx|mts|mjs)$|^\.oxlintrc\.json$/u;
|
||||
|
||||
/** Selects freshness checks for staged paths; an empty list means the hook adds no work. */
|
||||
|
|
@ -26,6 +27,13 @@ export function selectStagedFreshnessChecks(paths: string[]): FreshnessCheck[] {
|
|||
fix: "pnpm lint:docs:fix",
|
||||
});
|
||||
}
|
||||
if (some(AGENTS_MD_PATH_RE)) {
|
||||
checks.push({
|
||||
name: "AGENTS.md bootstrap size",
|
||||
args: ["check:agents-md-size"],
|
||||
fix: "cut rules or move them to the owning scoped AGENTS.md",
|
||||
});
|
||||
}
|
||||
if (hasProtocolGenerationInput(paths)) {
|
||||
checks.push({
|
||||
name: "protocol generated models",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ describe("selectStagedFreshnessChecks", () => {
|
|||
],
|
||||
[["extensions/x/openclaw.plugin.json"], "config:docs:check"],
|
||||
[["extensions/feishu/src/bot.test.ts"], "check:line-cap-ratchet"],
|
||||
[["src/gateway/AGENTS.md"], "check:agents-md-size"],
|
||||
])("selects the CI-owned check for %j", (paths, script) => {
|
||||
expect(scripts(paths)).toContain(script);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue