fix(docs-audit): the generated-file guard sees AUTO-GENERATED after YAML frontmatter

/ship red team on #3633 (CRITICAL): every generated SKILL.md has its marker after frontmatter, so apply would edit a generated file and fail Skill Docs Freshness. Failing-first test.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-30 02:47:10 +00:00
1 parent 8b46b745ee
commit 9eeda0906c
2 files changed
+18 -1

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@ import * as path from 'node:path';
/** Files a documentation edit never touches: release metadata, manifests and lockfiles the parent owns. */
const PROTECTED = [/^CHANGELOG\.md$/, /^TODOS\.md$/, /^VERSION$/, /(^|\/)package(-lock)?\.json$/, /(^|\/)(bun\.lockb?|yarn\.lock|pnpm-lock\.yaml|Cargo\.lock|Gemfile\.lock)$/, /(^|\/)sections\/manifest\.json$/, /^agents-digest\//];
const GENERATED = /^(?:[^\n]*\n){0,2}<!-- AUTO-GENERATED/;
const GENERATED = /^(?:---\n[\s\S]*?\n---\n)?(?:[^\n]*\n){0,2}<!-- AUTO-GENERATED/;
export interface DocsAuditResult {
schema_version: 1; audit_id: string; status: 'updated' | 'current' | 'blocked';
+17
View File
@@ -172,3 +172,20 @@ describe('gstack-docs-candidate apply', () => {
expect(fs.readFileSync(path.join(outside, 'target.md'), 'utf8')).toBe('secret target\n');
});
});
describe('docs audit apply: generated files behind frontmatter', () => {
// Value: protects=a generated SKILL.md whose AUTO-GENERATED marker follows YAML frontmatter is refused like any generated file; fails_when=apply edits a generated skill file and Skill Docs Freshness fails on the next run;
// why_new=GSTA-167 /ship red team on #3633 (CRITICAL); seam=none; no_claim=which docs the candidate lists
test('an edit to a frontmatter-first generated file is a blocker, not a write', async () => {
const { applyDocsFindings } = await import('../lib/docs-audit-apply');
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'docs-gen-'));
try {
const text = '---\nname: x\ndescription: y\nallowed-tools:\n - Bash\n---\n<!-- AUTO-GENERATED from SKILL.md.tmpl -->\nold\n';
fs.mkdirSync(path.join(root, 'x')); fs.writeFileSync(path.join(root, 'x', 'SKILL.md'), text);
const out = [JSON.stringify({ path: 'x/SKILL.md', action: 'edit', kind: 'stale', summary: 's', old: 'old', new: 'new' }), JSON.stringify({ schema_version: 1, audit_id: 'a1', documentation_section: 'Docs.' })].join('\n');
const res = applyDocsFindings(root, { audit_id: 'a1', mode: 'write', docs: ['x/SKILL.md'] }, out);
expect(res.result?.blockers.join('\n')).toContain('generated file');
expect(fs.readFileSync(path.join(root, 'x', 'SKILL.md'), 'utf8')).toBe(text);
} finally { fs.rmSync(root, { recursive: true, force: true }); }
});
});