diff --git a/docs/development/agent-workflow.md b/docs/development/agent-workflow.md index 0a7ef2c14..6a627b4d0 100644 --- a/docs/development/agent-workflow.md +++ b/docs/development/agent-workflow.md @@ -65,7 +65,8 @@ Inline iframe srcdoc documents are traversed too, with their own fragment anchor The first active HTML base href sets reference resolution, including nested srcdoc bases. Resolved file URLs use native filesystem conversion, including Windows drive paths. Explicit srcset attributes must contain at least one parsed candidate. -Image and media references require nonempty targets that resolve to files, not directories. +Image and media references require a nonempty path that resolves to a file, not a directory. +Direct file URLs are rejected; use portable repository-relative paths. Image references check file existence without interpreting image fragments as Markdown headings; document links keep anchor checks even when sharing a target. HTML video, audio, source and track `src` assets and video posters use the same diff --git a/tools/skills/validate-agent-guidance.mjs b/tools/skills/validate-agent-guidance.mjs index a88386d99..9f0683e47 100644 --- a/tools/skills/validate-agent-guidance.mjs +++ b/tools/skills/validate-agent-guidance.mjs @@ -41,6 +41,8 @@ async function validateReference( ) { if (unresolvedReference !== undefined) return `${source}: unresolved Markdown reference "${unresolvedReference}"`; + if (/^file:/iu.test(target)) + return `${source}: use a repository-relative path instead of a file URL: ${target}`; if (image && !target) return `${source}: empty media target`; let resolvedBasePath; if (bases?.length) { @@ -68,6 +70,8 @@ async function validateReference( } catch { return `${source}: malformed local link: ${target}`; } + if (image && !path && !resolvedBasePath) + return `${source}: media target requires a path: ${target}`; if (embeddedAnchors && !path && !image) return !anchor || embeddedAnchors.includes(anchor) ? undefined diff --git a/tools/skills/validate-agent-guidance.test.mjs b/tools/skills/validate-agent-guidance.test.mjs index 1fca537cf..ad9d0e0be 100644 --- a/tools/skills/validate-agent-guidance.test.mjs +++ b/tools/skills/validate-agent-guidance.test.mjs @@ -1586,3 +1586,14 @@ for (const extension of ['pdf', 'rst', 'adoc', 'markdown', 'docm', 'latex']) { ); }); } + +for (const markup of [ + '![logo](#missing)', + '', + '[Guide](file:///tmp/missing.md)', + 'Guide', +]) { + test(`nonportable or pathless target is rejected: ${markup}`, async (t) => { + assert.ok((await diagnostics(t, { 'AGENTS.md': markup })).length > 0); + }); +}