Skip to content

Commit 06f8436

Browse files
Merge remote-tracking branch 'origin/main' into production-readiness-review-e81o
2 parents be30b2f + 04a42a3 commit 06f8436

5 files changed

Lines changed: 461 additions & 57 deletions

File tree

.github/workflows/ci-security-scan.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,9 @@ jobs:
191191
if grep -rEnI 'docker/agent-image-pin(\.local)?\.env' \
192192
--exclude-dir=node_modules --exclude-dir=target --exclude-dir=.git \
193193
. \
194-
| grep -vE '^\./(MIGRATION\.md|docs/admin/agent-image-digests\.md):' ; then
195-
echo "::error::The legacy pin file was removed in v0.10.0; new references must live in MIGRATION.md only."
194+
| grep -vE '^\./(MIGRATION\.md|docs/admin/agent-image-digests\.md):' \
195+
| grep -vE '^\./scripts/check-agent-instructions\.ts:[0-9]+:[[:space:]]*value: "docker/agent-image-pin(\.local)?\.env",$' ; then
196+
echo "::error::Legacy pin-file names are allowed only in migration history, the digest guide, and exact instruction-checker exceptions."
196197
exit 1
197198
fi
198199

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@
103103
"graphql": "16.14.0",
104104
"husky": "9.1.7",
105105
"jsdom": "29.1.1",
106+
"mdast-util-from-markdown": "2.0.3",
107+
"mdast-util-mdx": "3.0.0",
106108
"mermaid": "11.16.1",
109+
"micromark-extension-mdxjs": "3.0.0",
107110
"mprocs": "0.9.3",
108111
"npm-run-all2": "8.0.4",
109112
"oxlint": "1.79.0",

pnpm-lock.yaml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/check-agent-instructions.test.ts

Lines changed: 156 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import assert from "node:assert/strict";
2-
import { execFile } from "node:child_process";
3-
import { lstat, readFile, readlink } from "node:fs/promises";
42
import { resolve } from "node:path";
53
import { test } from "node:test";
6-
import { promisify } from "node:util";
74
import {
85
analyse,
96
CODEX_SKILLS,
7+
codeSpans,
108
parse,
119
references,
1210
type Snapshot,
11+
scan,
1312
type TrackedFile,
1413
withoutCode,
1514
} from "./check-agent-instructions.ts";
@@ -27,6 +26,7 @@ function only(failures: readonly string[]): string {
2726

2827
/** A symlink to `target`, as an override value. */
2928
const symlinkTo = (target: string): { readonly target: string } => ({ target });
29+
const markdownSpans = (markdown: string): readonly string[] => codeSpans(markdown, "markdown");
3030

3131
type Override = string | { readonly target: string } | { readonly kind: "opaque" } | null;
3232

@@ -57,27 +57,8 @@ await test("the wired checkout passes", () => {
5757
assert.deepEqual(analyse(snapshot()), []);
5858
});
5959

60-
/**
61-
* The repository itself. `pnpm run check` runs the CLI over the real tree, but only ever over the
62-
* content of the day; this pins it.
63-
*/
6460
await test("the repository this gate ships in passes it", async () => {
65-
const { stdout } = await promisify(execFile)(
66-
"git",
67-
["ls-files", "-z", "--cached", "--others", "--exclude-standard"],
68-
{ cwd: REPO_ROOT, maxBuffer: 64 * 1024 * 1024 },
69-
);
70-
const files: TrackedFile[] = [];
71-
for (const path of [...new Set(stdout.split("\0").filter(Boolean))].toSorted()) {
72-
const stats = await lstat(resolve(REPO_ROOT, path)).catch(() => undefined);
73-
if (stats === undefined) continue;
74-
if (stats.isSymbolicLink()) {
75-
files.push({ path, kind: "symlink", target: await readlink(resolve(REPO_ROOT, path)) });
76-
} else if (path.endsWith(".md") || path === "opencode.json") {
77-
files.push({ path, kind: "text", content: await readFile(resolve(REPO_ROOT, path), "utf8") });
78-
} else files.push({ path, kind: "opaque" });
79-
}
80-
assert.deepEqual(analyse({ files }, CODEX_SKILLS), []);
61+
assert.deepEqual(analyse(await scan(REPO_ROOT), CODEX_SKILLS), []);
8162
});
8263

8364
await test("a nested AGENTS.md with no CLAUDE.md beside it is unreachable in Claude Code", () => {
@@ -200,6 +181,158 @@ await test("code is not prose: a reference inside a span, a fence or a comment i
200181
assert.deepEqual(references("```sh\nx\n```\n\n@AGENTS.md\n"), ["AGENTS.md"]);
201182
});
202183

184+
await test("the markdown scanner extracts code spans, not fences or comments", () => {
185+
assert.deepEqual(markdownSpans("Use `scripts/check.ts` and ``a ` b``."), [
186+
"scripts/check.ts",
187+
"a ` b",
188+
]);
189+
assert.deepEqual(markdownSpans("A `line\nwrap` is one span."), ["line wrap"]);
190+
assert.deepEqual(markdownSpans("A `CRLF\r\nwrap` is one span."), ["CRLF wrap"]);
191+
assert.deepEqual(markdownSpans("A `CR\rwrap` is one span."), ["CR wrap"]);
192+
assert.deepEqual(markdownSpans("` padded ` and ` `"), ["padded", " "]);
193+
assert.deepEqual(markdownSpans("<!-- `hidden.md` -->\n```md\n`fenced.md`\n```\n`shown.md`"), [
194+
"shown.md",
195+
]);
196+
assert.deepEqual(markdownSpans("\\`escaped.md\\`\n\n `indented.md`"), []);
197+
assert.deepEqual(markdownSpans("`a <!-- literal --> span`"), ["a <!-- literal --> span"]);
198+
assert.deepEqual(markdownSpans("> ```md\n> `quoted.md`\n> ```\n`shown.md`"), ["shown.md"]);
199+
assert.deepEqual(codeSpans("<Tabs>\n<TabItem>\nUse `inside.md`\n</TabItem>\n</Tabs>", "mdx"), [
200+
"inside.md",
201+
]);
202+
assert.deepEqual(markdownSpans("`not closed``"), []);
203+
assert.deepEqual(
204+
markdownSpans("```md\n`hidden.md`\n``` not a close\n`still-hidden.md`\n```"),
205+
[],
206+
);
207+
assert.deepEqual(markdownSpans("```md\n<!--\n```\n`shown.md`"), ["shown.md"]);
208+
assert.deepEqual(markdownSpans("<!--\n```md\n-->\n`shown.md`"), ["shown.md"]);
209+
});
210+
211+
await test("contributor docs reject missing repository paths and npm packages", () => {
212+
const failures = analyse(
213+
snapshot({
214+
"package.json": JSON.stringify({ dependencies: { react: "19.0.0" } }),
215+
"scripts/existing.ts": { kind: "opaque" },
216+
"docs/contributor/setup.md":
217+
"Use `scripts/existing.ts`, `react`, `scripts/missing.ts`, `missing-plugin`, and `@missing/package`.\n",
218+
}),
219+
);
220+
assert.equal(failures.length, 3, failures.join("\n"));
221+
assert.match(failures[0] ?? "", /scripts\/missing\.ts/);
222+
assert.match(failures[1] ?? "", /missing-plugin/);
223+
assert.match(failures[2] ?? "", /@missing\/package/);
224+
});
225+
226+
await test("an intentional non-checkout path is allowed only in the document that owns it", () => {
227+
assert.deepEqual(
228+
analyse(
229+
snapshot({
230+
"server/existing.ts": { kind: "opaque" },
231+
"docs/contributor/local-development.mdx": "Create `server/.env`.\n",
232+
}),
233+
),
234+
[],
235+
);
236+
assert.match(
237+
only(
238+
analyse(
239+
snapshot({
240+
"server/existing.ts": { kind: "opaque" },
241+
"docs/contributor/setup.md": "Create `server/.env`.\n",
242+
}),
243+
),
244+
),
245+
/server\/.env/,
246+
);
247+
});
248+
249+
await test("a unique shorthand directory resolves independently of its descendant count", () => {
250+
assert.deepEqual(
251+
analyse(
252+
snapshot({
253+
"webapp/src/features/a.ts": { kind: "opaque" },
254+
"webapp/src/features/b.ts": { kind: "opaque" },
255+
"docs/contributor/setup.md": "Use `src/features/`.\n",
256+
}),
257+
),
258+
[],
259+
);
260+
});
261+
262+
await test("an invalid contributor MDX document is reported with its path", () => {
263+
assert.throws(
264+
() => analyse(snapshot({ "docs/contributor/broken.mdx": "<Component/ name>" })),
265+
/docs\/contributor\/broken\.mdx:/,
266+
);
267+
});
268+
269+
await test("path claims cannot escape through a typo, basename, or unrelated suffix match", () => {
270+
for (const claim of ["scrips/missing.ts", "missing.md", "./config.md"]) {
271+
const failure = only(
272+
analyse(
273+
snapshot({
274+
"other/config.md": "# Unrelated\n",
275+
"docs/contributor/setup.md": `Use \`${claim}\`.\n`,
276+
}),
277+
),
278+
);
279+
assert.ok(failure.includes(claim), claim);
280+
}
281+
assert.deepEqual(
282+
analyse(
283+
snapshot({
284+
"docs/shared.md": { kind: "opaque" },
285+
"docs/contributor/local.md": { kind: "opaque" },
286+
"webapp/src/config.ts": { kind: "opaque" },
287+
"docs/contributor/setup.md": "Use `src/config.ts`, `./local.md`, and `../shared.md`.\n",
288+
}),
289+
),
290+
[],
291+
);
292+
assert.match(
293+
only(
294+
analyse(
295+
snapshot({
296+
"server/src/config.ts": { kind: "opaque" },
297+
"webapp/src/config.ts": { kind: "opaque" },
298+
"docs/contributor/setup.md": "Use `src/config.ts`.\n",
299+
}),
300+
),
301+
),
302+
/src\/config\.ts/,
303+
);
304+
});
305+
306+
await test("the contributor claim scope is root Markdown and contributor Markdown or MDX only", () => {
307+
for (const path of ["README.md", "docs/contributor/setup.md", "docs/contributor/setup.mdx"]) {
308+
assert.match(only(analyse(snapshot({ [path]: "Use `missing.md`.\n" }))), /missing\.md/, path);
309+
}
310+
for (const path of ["README.mdx", "docs/reader/setup.md"]) {
311+
assert.deepEqual(analyse(snapshot({ [path]: "Use `missing.md`.\n" })), [], path);
312+
}
313+
});
314+
315+
await test("every package.json declaration field satisfies a contributor package claim", () => {
316+
const manifest = {
317+
name: "workspace-package",
318+
dependencies: { dependency: "1" },
319+
devDependencies: { "dev-package": "1" },
320+
optionalDependencies: { "optional-package": "1" },
321+
peerDependencies: { "peer-package": "1" },
322+
};
323+
assert.deepEqual(
324+
analyse(
325+
snapshot({
326+
"package.json": JSON.stringify(manifest),
327+
"docs/contributor/setup.md":
328+
"`workspace-package` `dependency` `dev-package` `optional-package` `peer-package`\n",
329+
}),
330+
),
331+
[],
332+
);
333+
assert.throws(() => analyse(snapshot({ "package.json": "{broken" })), SyntaxError);
334+
});
335+
203336
await test("a code span split by the line wrap does not swallow the import after it", () => {
204337
assert.deepEqual(
205338
references("the `<form>` is the level: `flex\nmin-h-0 flex-col`, then @AGENTS.md"),

0 commit comments

Comments
 (0)