diff --git a/docs/development/agent-workflow.md b/docs/development/agent-workflow.md index 77dcf800a..1e1e413ba 100644 --- a/docs/development/agent-workflow.md +++ b/docs/development/agent-workflow.md @@ -72,7 +72,8 @@ are recognized as package/alias mentions. Traversal and document-file imports ar rejected before those exemptions, including document paths with fragments or queries. All recognized Markdown extensions share the document-import guard; reStructuredText and AsciiDoc, PDF, Word, OpenDocument, RTF, Org and TeX documents are also excluded -from package exemptions. URL-encoded +from package exemptions. Recognized extensionless guidance names (including AGENTS, +CLAUDE, INSTRUCTIONS and README) are excluded in package subpaths too. URL-encoded paths do not receive package exemptions. TypeScript configuration is parsed as JSONC. Declared packages also permit safe subpaths; exact aliases stay exact. Declared package mentions may include a version (including semver comparators and wildcard ranges) or dist-tag qualifier. diff --git a/tools/skills/validate-agent-guidance.mjs b/tools/skills/validate-agent-guidance.mjs index 92eb20abe..1ba82093a 100644 --- a/tools/skills/validate-agent-guidance.mjs +++ b/tools/skills/validate-agent-guidance.mjs @@ -130,7 +130,10 @@ async function packageMentions(rootDir) { if ( /%[\da-f]{2}/iu.test(token) || MARKDOWN_EXTENSION.test(path) || - /\.(?:txt|json|ya?ml|html?|rst|rest|adoc|asciidoc|pdf|docx?|odt|rtf|org|tex)$/iu.test( + /(?:^|\/)(?:AGENTS|CLAUDE|INSTRUCTIONS|README|LICENSE|LICENCE|NOTICE|COPYING|AUTHORS|CONTRIBUTORS|CHANGELOG)$/u.test( + path + ) || + /\.(?:txt|json|ya?ml|html?|rst|rest|adoc|asciidoc|pdf|doc[xm]?|dot[xm]?|od[tspgfbm]|ot[tspg]|fod[tspg]|rtf|org|tex|latex)$/iu.test( path ) ) diff --git a/tools/skills/validate-agent-guidance.test.mjs b/tools/skills/validate-agent-guidance.test.mjs index ddce49e73..941b6df24 100644 --- a/tools/skills/validate-agent-guidance.test.mjs +++ b/tools/skills/validate-agent-guidance.test.mjs @@ -1292,3 +1292,30 @@ for (const html of [ assert.deepEqual(await diagnostics(t, { 'AGENTS.md': html }), []); }); } + +for (const name of [ + 'guide.ods', + 'guide.odp', + 'guide.docm', + 'guide.dotx', + 'guide.latex', + 'AGENTS', + 'CLAUDE', + 'README', + 'INSTRUCTIONS', + 'LICENSE', +]) { + test(`package subpath cannot import guidance document ${name}`, async (t) => { + assert.ok( + ( + await diagnostics(t, { + 'package.json': JSON.stringify({ + dependencies: { '@angular/core': '*' }, + }), + 'CLAUDE.md': + '@AGENTS.md\n\nRead @angular/core/docs/' + name, + }) + ).some((message) => message.includes('additional or inline')) + ); + }); +}