Files
msd-core/tests/agent-required-reading-consistency.test.cjs
Tom Boucher 2a915c1b82 chore: migrate references from gsd-build to open-gsd/get-shit-done-redux (#120) (#121)
Security-motivated migration of all stale repository and npm-scope references.

Three categories of changes (58 files, 174 substitutions):

1. gsd-build → open-gsd (security-critical):
   - .github/workflows/release-sdk.yml — npm token comment, tarball filename pattern
   - .github/workflows/hotfix.yml — same
   - .changeset/fix-3406-detect-stale-sdk-shadow.md — @gsd-build/sdk → @open-gsd/sdk
   - .changeset/sharp-quails-leap.md — same
   - get-shit-done/workflows/update.md — CHANGELOG raw GitHub URL

2. GSD-redux org slug → open-gsd (canonical rename):
   - package.json + sdk/package.json — repository/homepage/bugs metadata
   - All README.*.md — live badge and link sections
   - CONTRIBUTING.md, CONTEXT.md, QUICK-WINS-CONFIRMED-BUGS.md
   - .coderabbit.yaml, .release-monitor.sh, scripts/sync-rulesets.sh
   - docs/** — all live agent/ADR/user-facing documentation
   - tests/** — repo slug assertions and test fixtures
   - scripts/changeset/cli.cjs + github-release-notes.cjs
   - .github/ISSUE_TEMPLATE/*, .github/pull_request_template.md
   - bin/install.js, get-shit-done/bin/lib/model-catalog.cjs
   - sdk/HANDOVER-*.md, sdk/src/*.test.ts

3. CLAUDE.md (gitignored local file — not in this commit):
   Updated separately outside git: --repo gsd-build/get-shit-done →
   --repo open-gsd/get-shit-done-redux with security warning.

Intentionally unchanged: CHANGELOG.md, docs/RELEASE-*.md,
.changeset/README.md, .changeset/build-hooks-atomic-write.md,
README.md migration table (historical fork record),
tests/changeset-serialize.test.cjs line 78 (serialization fixture).

The gsd-build/get-shit-done repo is compromised (rug-pull documented in
README.md). Do not push to or interact with that repo.

Closes #120
2026-05-22 12:28:16 -04:00

83 lines
3.2 KiB
JavaScript

// allow-test-rule: source-text-is-the-product
// Reads .md/.json/.yml product files whose deployed text IS what the
// runtime loads — testing text content tests the deployed contract.
/**
* GSD Agent Required Reading Consistency Tests
*
* Validates that all agent .md files use the standardized <required_reading>
* pattern and that no legacy <files_to_read> blocks remain.
*
* See: https://github.com/open-gsd/get-shit-done-redux/issues/2168
*/
const { test, describe } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('fs');
const path = require('path');
const AGENTS_DIR = path.join(__dirname, '..', 'agents');
const ALL_AGENTS = fs.readdirSync(AGENTS_DIR)
.filter(f => f.startsWith('gsd-') && f.endsWith('.md'))
.map(f => f.replace('.md', ''));
// ─── No Legacy files_to_read Blocks ────────────────────────────────────────
describe('READING: no legacy <files_to_read> blocks remain', () => {
for (const agent of ALL_AGENTS) {
test(`${agent} does not contain <files_to_read>`, () => {
const content = fs.readFileSync(path.join(AGENTS_DIR, agent + '.md'), 'utf-8');
assert.ok(
!content.includes('<files_to_read>'),
`${agent} still has <files_to_read> opening tag — migrate to <required_reading>`
);
assert.ok(
!content.includes('</files_to_read>'),
`${agent} still has </files_to_read> closing tag — migrate to </required_reading>`
);
});
}
test('no backtick references to files_to_read in any agent', () => {
for (const agent of ALL_AGENTS) {
const content = fs.readFileSync(path.join(AGENTS_DIR, agent + '.md'), 'utf-8');
assert.ok(
!content.includes('`<files_to_read>`'),
`${agent} still references \`<files_to_read>\` in prose — update to \`<required_reading>\``
);
}
});
});
// ─── Standardized required_reading Pattern ─────────────────────────────────
describe('READING: agents with reading blocks use <required_reading>', () => {
// Agents that have any kind of reading instruction should use required_reading
const AGENTS_WITH_READING = ALL_AGENTS.filter(name => {
const content = fs.readFileSync(path.join(AGENTS_DIR, name + '.md'), 'utf-8');
return content.includes('required_reading') || content.includes('files_to_read');
});
test('at least 20 agents have reading instructions', () => {
assert.ok(
AGENTS_WITH_READING.length >= 20,
`Expected at least 20 agents with reading instructions, found ${AGENTS_WITH_READING.length}`
);
});
for (const agent of AGENTS_WITH_READING) {
test(`${agent} uses required_reading (not files_to_read)`, () => {
const content = fs.readFileSync(path.join(AGENTS_DIR, agent + '.md'), 'utf-8');
assert.ok(
content.includes('required_reading'),
`${agent} has reading instructions but does not use required_reading`
);
assert.ok(
!content.includes('files_to_read'),
`${agent} still uses files_to_read — must be migrated to required_reading`
);
});
}
});