diff --git a/.changeset/silly-newts-swim.md b/.changeset/silly-newts-swim.md new file mode 100644 index 000000000..0dc68695f --- /dev/null +++ b/.changeset/silly-newts-swim.md @@ -0,0 +1,5 @@ +--- +type: Added +pr: 2982 +--- +Extended no-source-grep lint to catch var-binding readFileSync.includes() pattern. Tests now fail when source-grep is hidden behind a parser wrapper. See #2982. diff --git a/.changeset/zesty-moles-forage.md b/.changeset/zesty-moles-forage.md new file mode 100644 index 000000000..0dc68695f --- /dev/null +++ b/.changeset/zesty-moles-forage.md @@ -0,0 +1,5 @@ +--- +type: Added +pr: 2982 +--- +Extended no-source-grep lint to catch var-binding readFileSync.includes() pattern. Tests now fail when source-grep is hidden behind a parser wrapper. See #2982. diff --git a/scripts/lint-no-source-grep-extras.cjs b/scripts/lint-no-source-grep-extras.cjs new file mode 100644 index 000000000..10ff4886c --- /dev/null +++ b/scripts/lint-no-source-grep-extras.cjs @@ -0,0 +1,81 @@ +'use strict'; + +/** + * Extended detector for the no-source-grep rule (#2982). + * + * The base lint (scripts/lint-no-source-grep.cjs) only catches the + * direct-chain form: readFileSync(...).includes(...). The much more common + * var-binding form escapes it: + * + * const src = fs.readFileSync(p, 'utf8'); + * // ... 50 lines later ... + * assert.ok(src.includes('foo')); // ← still source-grep, lint missed it + * + * This module exposes pure detectors that scan source text and return + * structured violation records. The CLI wrapper (in the base lint) calls + * these for each test file. + * + * Tests assert on the typed VIOLATION enum codes, not on prose messages. + */ + +const VIOLATION = Object.freeze({ + VAR_FROM_READFILE_USED_IN_TEXT_MATCH: 'var_from_readfile_used_in_text_match', + WRAPPED_ASSERT_OK_MATCH: 'wrapped_assert_ok_match', +}); + +const TEXT_MATCH_METHODS = ['includes', 'startsWith', 'endsWith', 'match', 'search']; + +/** + * Single-pass scanner. Tracks variables bound from a readFileSync call, + * then flags any subsequent .( use where method is one of + * TEXT_MATCH_METHODS. + */ +function detectVarBindingViolations(src) { + // Pass 1: collect variables bound from readFileSync. + // Matches: const|let|var = [fs.]readFileSync( + const bindRe = /(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:[A-Za-z_$][\w$.]*\.)?readFileSync\s*\(/g; + const boundVars = new Set(); + let m; + while ((m = bindRe.exec(src)) !== null) { + boundVars.add(m[1]); + } + if (boundVars.size === 0) return []; + + // Pass 2: find .( on any bound var. + const findings = []; + // Build a regex alternation from the bound var names. + const alt = [...boundVars].map((v) => v.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|'); + const useRe = new RegExp( + `\\b(${alt})\\s*\\.\\s*(${TEXT_MATCH_METHODS.join('|')})\\s*\\(`, + 'g', + ); + while ((m = useRe.exec(src)) !== null) { + findings.push({ + kind: VIOLATION.VAR_FROM_READFILE_USED_IN_TEXT_MATCH, + variable: m[1], + method: m[2], + }); + } + return findings; +} + +/** + * Detects assert.ok(.match(/.../)) and assert.ok(.match()) + * which is the same anti-pattern as assert.match but escapes the simpler + * regex used by the base lint. + */ +function detectWrappedAssertOkMatch(src) { + const re = /assert\.ok\s*\(\s*[A-Za-z_$][\w$.]*\.match\s*\(/g; + const findings = []; + let m; + while ((m = re.exec(src)) !== null) { + findings.push({ kind: VIOLATION.WRAPPED_ASSERT_OK_MATCH }); + } + return findings; +} + +function detectAll(src) { + return [...detectVarBindingViolations(src), ...detectWrappedAssertOkMatch(src)]; +} + +module.exports = { detectVarBindingViolations, detectWrappedAssertOkMatch, detectAll, VIOLATION }; diff --git a/scripts/lint-no-source-grep.cjs b/scripts/lint-no-source-grep.cjs index 16e29b2ed..35b7e9f80 100644 --- a/scripts/lint-no-source-grep.cjs +++ b/scripts/lint-no-source-grep.cjs @@ -110,6 +110,28 @@ function check(filepath) { } } + // Patterns F..G (#2982): var-binding readFileSync().() and + // assert.ok(.match(...)). These escape the simpler patterns above + // because the bind and the use are on different lines or wrapped. + const extras = require('./lint-no-source-grep-extras.cjs'); + const varBindFindings = extras.detectVarBindingViolations(content); + if (varBindFindings.length > 0) { + const samples = varBindFindings.slice(0, 3) + .map((f) => `${f.variable}.${f.method}()`) + .join(', '); + violations.push({ + reason: `readFileSync-bound variable used in text-match method: ${samples}${varBindFindings.length > 3 ? `, …+${varBindFindings.length - 3} more` : ''}`, + fix: 'Expose typed IR; assert on structured fields. Or // allow-test-rule: ', + }); + } + const wrappedFindings = extras.detectWrappedAssertOkMatch(content); + if (wrappedFindings.length > 0) { + violations.push({ + reason: `assert.ok(.match(...)) — escapes assert.match rule (${wrappedFindings.length} occurrence${wrappedFindings.length > 1 ? 's' : ''})`, + fix: 'Use assert.equal on a typed field, not regex match on text. Or // allow-test-rule: ', + }); + } + if (violations.length === 0) return null; return { file: rel, violations }; } diff --git a/tests/agent-required-reading-consistency.test.cjs b/tests/agent-required-reading-consistency.test.cjs index b2db0fe1c..c409c1bd0 100644 --- a/tests/agent-required-reading-consistency.test.cjs +++ b/tests/agent-required-reading-consistency.test.cjs @@ -1,3 +1,7 @@ +// 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 * diff --git a/tests/agent-size-budget.test.cjs b/tests/agent-size-budget.test.cjs index 4feada42d..cfb479a01 100644 --- a/tests/agent-size-budget.test.cjs +++ b/tests/agent-size-budget.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Agent size budget. * diff --git a/tests/ai-evals.test.cjs b/tests/ai-evals.test.cjs index 840b74020..ff926afa6 100644 --- a/tests/ai-evals.test.cjs +++ b/tests/ai-evals.test.cjs @@ -1,3 +1,7 @@ +// 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 AI Evals Framework Tests * diff --git a/tests/analyze-dependencies.test.cjs b/tests/analyze-dependencies.test.cjs index 3cfe3d0d9..8cf854e6d 100644 --- a/tests/analyze-dependencies.test.cjs +++ b/tests/analyze-dependencies.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + const { test, describe, beforeEach, afterEach } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/anti-pattern-enforcement.test.cjs b/tests/anti-pattern-enforcement.test.cjs index e91d56846..2300ad310 100644 --- a/tests/anti-pattern-enforcement.test.cjs +++ b/tests/anti-pattern-enforcement.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Anti-Pattern Enforcement Tests (#1491) * diff --git a/tests/antigravity-install.test.cjs b/tests/antigravity-install.test.cjs index 10775a33e..0a8ed5fa9 100644 --- a/tests/antigravity-install.test.cjs +++ b/tests/antigravity-install.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - Antigravity Install Plumbing * diff --git a/tests/ask-user-questions-fallback.test.cjs b/tests/ask-user-questions-fallback.test.cjs index ffcfe64d2..1ca6caa81 100644 --- a/tests/ask-user-questions-fallback.test.cjs +++ b/tests/ask-user-questions-fallback.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression guard for #2012: AskUserQuestion is Claude Code-only — non-Claude * runtimes (OpenAI Codex, Gemini, etc.) render it as a markdown code block diff --git a/tests/audit-fix-command.test.cjs b/tests/audit-fix-command.test.cjs index 3e86bbce8..a57d0cb03 100644 --- a/tests/audit-fix-command.test.cjs +++ b/tests/audit-fix-command.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Audit-Fix Command Tests * diff --git a/tests/autonomous-decomposition.test.cjs b/tests/autonomous-decomposition.test.cjs index a785afa4f..7a3fb26e8 100644 --- a/tests/autonomous-decomposition.test.cjs +++ b/tests/autonomous-decomposition.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2196 * diff --git a/tests/autonomous-interactive.test.cjs b/tests/autonomous-interactive.test.cjs index 4873ecd99..c6bd1664e 100644 --- a/tests/autonomous-interactive.test.cjs +++ b/tests/autonomous-interactive.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - autonomous --interactive flag * diff --git a/tests/autonomous-to-flag.test.cjs b/tests/autonomous-to-flag.test.cjs index 0a2966539..f2b0c4435 100644 --- a/tests/autonomous-to-flag.test.cjs +++ b/tests/autonomous-to-flag.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - autonomous --to N flag * diff --git a/tests/bug-1924-preserve-user-artifacts.test.cjs b/tests/bug-1924-preserve-user-artifacts.test.cjs index b707baaa0..3ffddacfd 100644 --- a/tests/bug-1924-preserve-user-artifacts.test.cjs +++ b/tests/bug-1924-preserve-user-artifacts.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression tests for bug #1924: gsd-update silently deletes user-generated files * diff --git a/tests/bug-1967-cache-invalidation.test.cjs b/tests/bug-1967-cache-invalidation.test.cjs index 83ce83b19..f83ca3dc4 100644 --- a/tests/bug-1967-cache-invalidation.test.cjs +++ b/tests/bug-1967-cache-invalidation.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression tests for #1967 cache invalidation. * diff --git a/tests/bug-2015-worktree-base-branch.test.cjs b/tests/bug-2015-worktree-base-branch.test.cjs index c122fba12..846991066 100644 --- a/tests/bug-2015-worktree-base-branch.test.cjs +++ b/tests/bug-2015-worktree-base-branch.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2015: worktree executor creates branch from master * instead of the current feature branch HEAD. diff --git a/tests/bug-2075-worktree-deletion-safeguards.test.cjs b/tests/bug-2075-worktree-deletion-safeguards.test.cjs index e8d53104d..57c15ebfe 100644 --- a/tests/bug-2075-worktree-deletion-safeguards.test.cjs +++ b/tests/bug-2075-worktree-deletion-safeguards.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression tests for #2075: gsd-executor worktree merge systematically * deletes prior-wave committed files. diff --git a/tests/bug-2136-sh-hook-version.test.cjs b/tests/bug-2136-sh-hook-version.test.cjs index a9c6daaa8..8c8fbdfde 100644 --- a/tests/bug-2136-sh-hook-version.test.cjs +++ b/tests/bug-2136-sh-hook-version.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression tests for bug #2136 / #2206 * diff --git a/tests/bug-2388-plan-phase-no-branch-rename.test.cjs b/tests/bug-2388-plan-phase-no-branch-rename.test.cjs index 0ea90021a..02bb50deb 100644 --- a/tests/bug-2388-plan-phase-no-branch-rename.test.cjs +++ b/tests/bug-2388-plan-phase-no-branch-rename.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2388: plan-phase silently renames feature branch * when phase slug has changed since the branch was created. diff --git a/tests/bug-2396-makefile-test-priority.test.cjs b/tests/bug-2396-makefile-test-priority.test.cjs index f4755bb42..80176b501 100644 --- a/tests/bug-2396-makefile-test-priority.test.cjs +++ b/tests/bug-2396-makefile-test-priority.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2396: hardcoded host-level test commands bypass * container-only project Makefiles. diff --git a/tests/bug-2399-commit-docs-plan-phase.test.cjs b/tests/bug-2399-commit-docs-plan-phase.test.cjs index 2ef121fc8..4d7df16ba 100644 --- a/tests/bug-2399-commit-docs-plan-phase.test.cjs +++ b/tests/bug-2399-commit-docs-plan-phase.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Bug #2399: commit_docs:true is ignored in plan-phase * diff --git a/tests/bug-2410-stream-checkpoint-heartbeats.test.cjs b/tests/bug-2410-stream-checkpoint-heartbeats.test.cjs index 1107cdf79..83db74d07 100644 --- a/tests/bug-2410-stream-checkpoint-heartbeats.test.cjs +++ b/tests/bug-2410-stream-checkpoint-heartbeats.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Bug #2410 — /gsd:manager background execute-phase Task fails with * "Stream idle timeout" on multi-plan phases. diff --git a/tests/bug-2419-project-researcher-agent.test.cjs b/tests/bug-2419-project-researcher-agent.test.cjs index 0a0c0249c..516369297 100644 --- a/tests/bug-2419-project-researcher-agent.test.cjs +++ b/tests/bug-2419-project-researcher-agent.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * Bug #2419: gsd-project-researcher agent type not found * diff --git a/tests/bug-2421-planner-grep-gate-hygiene.test.cjs b/tests/bug-2421-planner-grep-gate-hygiene.test.cjs index 3de0f63ec..9a39ada08 100644 --- a/tests/bug-2421-planner-grep-gate-hygiene.test.cjs +++ b/tests/bug-2421-planner-grep-gate-hygiene.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Bug #2421: gsd-planner emits grep-count acceptance gates that count comment text * diff --git a/tests/bug-2431-worktree-locked-surfacing.test.cjs b/tests/bug-2431-worktree-locked-surfacing.test.cjs index c976c0333..88dd0345f 100644 --- a/tests/bug-2431-worktree-locked-surfacing.test.cjs +++ b/tests/bug-2431-worktree-locked-surfacing.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2431: quick.md and execute-phase.md worktree teardown * silently accumulates locked worktrees via `2>/dev/null || true`. diff --git a/tests/bug-2439-set-profile-gsd-sdk-preflight.test.cjs b/tests/bug-2439-set-profile-gsd-sdk-preflight.test.cjs index 321f96a86..e74eff350 100644 --- a/tests/bug-2439-set-profile-gsd-sdk-preflight.test.cjs +++ b/tests/bug-2439-set-profile-gsd-sdk-preflight.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for bug #2439 * diff --git a/tests/bug-2441-sdk-decouple.test.cjs b/tests/bug-2441-sdk-decouple.test.cjs index 823ae1b04..b357907f1 100644 --- a/tests/bug-2441-sdk-decouple.test.cjs +++ b/tests/bug-2441-sdk-decouple.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression tests for fix/2441-sdk-decouple * diff --git a/tests/bug-2470-update-md-claude-path.test.cjs b/tests/bug-2470-update-md-claude-path.test.cjs index 0475f6945..e562051b5 100644 --- a/tests/bug-2470-update-md-claude-path.test.cjs +++ b/tests/bug-2470-update-md-claude-path.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2470. * diff --git a/tests/bug-2492-context-coverage-gate.test.cjs b/tests/bug-2492-context-coverage-gate.test.cjs index 35a612be8..26080dc13 100644 --- a/tests/bug-2492-context-coverage-gate.test.cjs +++ b/tests/bug-2492-context-coverage-gate.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Bug #2492: Add gates to ensure discuss-phase decisions are translated to * plans (plan-phase, BLOCKING) and verified against shipped artifacts diff --git a/tests/bug-2502-insert-phase-state-update.test.cjs b/tests/bug-2502-insert-phase-state-update.test.cjs index e121b8fb0..a3b115a3f 100644 --- a/tests/bug-2502-insert-phase-state-update.test.cjs +++ b/tests/bug-2502-insert-phase-state-update.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2502: insert-phase does not update STATE.md's * next-phase recommendation after inserting a decimal phase. diff --git a/tests/bug-2516-inherit-model-execute-phase.test.cjs b/tests/bug-2516-inherit-model-execute-phase.test.cjs index 0994e573d..8f8f97b76 100644 --- a/tests/bug-2516-inherit-model-execute-phase.test.cjs +++ b/tests/bug-2516-inherit-model-execute-phase.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for bug #2516 * diff --git a/tests/bug-2524-sdk-query-ws-flag.test.cjs b/tests/bug-2524-sdk-query-ws-flag.test.cjs index 924f88e34..5ee6ff2af 100644 --- a/tests/bug-2524-sdk-query-ws-flag.test.cjs +++ b/tests/bug-2524-sdk-query-ws-flag.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Do not copy this pattern. + /** * Bug #2524: gsd-sdk query --ws silently ignores the workstream flag. * Tests that --ws is forwarded through the call chain: diff --git a/tests/bug-2549-2550-2552-discuss-phase-context.test.cjs b/tests/bug-2549-2550-2552-discuss-phase-context.test.cjs index 1bce07300..617286e96 100644 --- a/tests/bug-2549-2550-2552-discuss-phase-context.test.cjs +++ b/tests/bug-2549-2550-2552-discuss-phase-context.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Bugs #2549, #2550, #2552: discuss-phase context bloat and cache invalidation. * diff --git a/tests/bug-2559-stale-search-year.test.cjs b/tests/bug-2559-stale-search-year.test.cjs index 91271653f..3ba8d5bcd 100644 --- a/tests/bug-2559-stale-search-year.test.cjs +++ b/tests/bug-2559-stale-search-year.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Bug #2559: Stale document references in Research phase * diff --git a/tests/bug-2661-roadmap-sync-parallel.test.cjs b/tests/bug-2661-roadmap-sync-parallel.test.cjs index 0db2ea5c9..7c481dcde 100644 --- a/tests/bug-2661-roadmap-sync-parallel.test.cjs +++ b/tests/bug-2661-roadmap-sync-parallel.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * Regression tests for bug #2661: * `/gsd-execute-phase N --auto` with parallelization: true, use_worktrees: false diff --git a/tests/bug-2698-crlf-install.test.cjs b/tests/bug-2698-crlf-install.test.cjs index cc24f98f1..48e52a66d 100644 --- a/tests/bug-2698-crlf-install.test.cjs +++ b/tests/bug-2698-crlf-install.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2698: CRLF line endings break agent-block strip regexes * diff --git a/tests/bug-2770-annotate-deps-int-coerce.test.cjs b/tests/bug-2770-annotate-deps-int-coerce.test.cjs index 708d8d9ff..8142580d8 100644 --- a/tests/bug-2770-annotate-deps-int-coerce.test.cjs +++ b/tests/bug-2770-annotate-deps-int-coerce.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Regression — issue #2770 * diff --git a/tests/bug-2772-gitmodules-path-intersection.test.cjs b/tests/bug-2772-gitmodules-path-intersection.test.cjs index 3a62861b1..6c3082fef 100644 --- a/tests/bug-2772-gitmodules-path-intersection.test.cjs +++ b/tests/bug-2772-gitmodules-path-intersection.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2772: worktree isolation is unconditionally disabled * when `.gitmodules` exists in the repo, even when the plan does not touch diff --git a/tests/bug-2775-sdk-shim-path-verify.test.cjs b/tests/bug-2775-sdk-shim-path-verify.test.cjs index 57eb33bce..11bb816f6 100644 --- a/tests/bug-2775-sdk-shim-path-verify.test.cjs +++ b/tests/bug-2775-sdk-shim-path-verify.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for bug #2775 * diff --git a/tests/bug-2784-update-cache-clear-path.test.cjs b/tests/bug-2784-update-cache-clear-path.test.cjs index ded16c5f4..b80a151fc 100644 --- a/tests/bug-2784-update-cache-clear-path.test.cjs +++ b/tests/bug-2784-update-cache-clear-path.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for bug #2784 * diff --git a/tests/bug-2808-skill-hyphen-name.test.cjs b/tests/bug-2808-skill-hyphen-name.test.cjs index 1fcf25231..581885e02 100644 --- a/tests/bug-2808-skill-hyphen-name.test.cjs +++ b/tests/bug-2808-skill-hyphen-name.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * Regression test for bug #2808 * diff --git a/tests/bug-2831-opencode-home-path-prefix.test.cjs b/tests/bug-2831-opencode-home-path-prefix.test.cjs index 5c3d483c8..bed0371ac 100644 --- a/tests/bug-2831-opencode-home-path-prefix.test.cjs +++ b/tests/bug-2831-opencode-home-path-prefix.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #2831: OpenCode @file references contain literal `$HOME` * which OpenCode does not expand — `@$HOME/.config/opencode/...` is resolved diff --git a/tests/bug-2949-sketch-wrap-up-dispatch.test.cjs b/tests/bug-2949-sketch-wrap-up-dispatch.test.cjs index 2ffe47d5e..b5ac85b53 100644 --- a/tests/bug-2949-sketch-wrap-up-dispatch.test.cjs +++ b/tests/bug-2949-sketch-wrap-up-dispatch.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tests — /gsd-sketch --wrap-up silently no-ops (#2949) * diff --git a/tests/bug-2954-help-md-slash-command-stubs.test.cjs b/tests/bug-2954-help-md-slash-command-stubs.test.cjs index 0b5dceb9e..703211046 100644 --- a/tests/bug-2954-help-md-slash-command-stubs.test.cjs +++ b/tests/bug-2954-help-md-slash-command-stubs.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + process.env.GSD_TEST_MODE = '1'; /** diff --git a/tests/bug-2982-lint-var-binding.test.cjs b/tests/bug-2982-lint-var-binding.test.cjs new file mode 100644 index 000000000..cf1b72631 --- /dev/null +++ b/tests/bug-2982-lint-var-binding.test.cjs @@ -0,0 +1,100 @@ +'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Do not copy this pattern. + +process.env.GSD_TEST_MODE = '1'; + +const { test, describe } = require('node:test'); +const assert = require('node:assert/strict'); +const path = require('node:path'); + +const { detectVarBindingViolations, VIOLATION } = require(path.join(__dirname, '..', 'scripts', 'lint-no-source-grep-extras.cjs')); + +// detectVarBindingViolations is pure: takes source text, returns a list of +// violation records. Tests assert on the structured records, not on the +// detector's prose (per "Prohibited: Raw Text Matching on Test Outputs"). + +describe('Bug #2982: var-binding readFileSync.includes() detector', () => { + test('VIOLATION enum exposes the documented codes', () => { + assert.deepEqual( + Object.keys(VIOLATION).sort(), + ['VAR_FROM_READFILE_USED_IN_TEXT_MATCH', 'WRAPPED_ASSERT_OK_MATCH'].sort(), + ); + }); + + test('flags a single var bound from readFileSync then used with .includes() later', () => { + const src = [ + "const x = fs.readFileSync('foo.cjs', 'utf8');", + '// some lines later', + "if (x.includes('foo')) { /* ... */ }", + ].join('\n'); + const findings = detectVarBindingViolations(src); + assert.equal(findings.length, 1); + assert.equal(findings[0].kind, VIOLATION.VAR_FROM_READFILE_USED_IN_TEXT_MATCH); + assert.equal(findings[0].variable, 'x'); + assert.equal(findings[0].method, 'includes'); + }); +}); + +describe('Bug #2982: var-binding detector — coverage of methods (#2982)', () => { + const { detectVarBindingViolations, VIOLATION } = require(require('node:path').join(__dirname, '..', 'scripts', 'lint-no-source-grep-extras.cjs')); + + for (const method of ['includes', 'startsWith', 'endsWith', 'match', 'search']) { + test(`flags .${method}( on a readFileSync-bound variable`, () => { + const src = `const c = fs.readFileSync('x.cjs','utf8');\nc.${method}('foo');\n`; + const findings = detectVarBindingViolations(src); + assert.equal(findings.length, 1); + assert.equal(findings[0].method, method); + }); + } + + test('flags multiple violations across multiple variables', () => { + const src = [ + "const a = readFileSync('a.cjs', 'utf8');", + "const b = fs.readFileSync('b.cjs');", + "if (a.includes('x')) {}", + "if (b.startsWith('y')) {}", + "a.endsWith('z');", + ].join('\n'); + const findings = detectVarBindingViolations(src); + assert.equal(findings.length, 3); + const byVar = findings.reduce((acc, f) => { + acc[f.variable] = (acc[f.variable] || []).concat(f.method); + return acc; + }, {}); + assert.deepEqual(byVar.a.sort(), ['endsWith', 'includes']); + assert.deepEqual(byVar.b, ['startsWith']); + }); + + test('does NOT flag .includes() on a variable that was not bound from readFileSync', () => { + const src = "const arr = [1, 2, 3];\nif (arr.includes(2)) {}"; + assert.deepEqual(detectVarBindingViolations(src), []); + }); + + test('does NOT flag a fresh string literal substring check', () => { + const src = "if ('hello world'.includes('world')) {}"; + assert.deepEqual(detectVarBindingViolations(src), []); + }); +}); + +describe('Bug #2982: assert.ok(...match(...)) detector', () => { + const { detectWrappedAssertOkMatch, VIOLATION } = require(require('node:path').join(__dirname, '..', 'scripts', 'lint-no-source-grep-extras.cjs')); + + test('flags assert.ok(text.match(/.../)) which escapes assert.match', () => { + const src = "assert.ok(text.match(/Failures: \\d+/));"; + const findings = detectWrappedAssertOkMatch(src); + assert.equal(findings.length, 1); + assert.equal(findings[0].kind, VIOLATION.WRAPPED_ASSERT_OK_MATCH); + }); + + test('does NOT flag assert.match itself (covered by base lint)', () => { + const src = "assert.match(text, /foo/);"; + assert.deepEqual(detectWrappedAssertOkMatch(src), []); + }); + + test('does NOT flag .matchAll(...) — matchAll is not match, so assert.ok(.matchAll(...)) is not flagged', () => { + const src = "assert.ok([...text.matchAll(/foo/g)].length > 0);"; + assert.deepEqual(detectWrappedAssertOkMatch(src), []); + }); +}); diff --git a/tests/bug-patterns-reference.test.cjs b/tests/bug-patterns-reference.test.cjs index 2593d0c06..ab06f3cb1 100644 --- a/tests/bug-patterns-reference.test.cjs +++ b/tests/bug-patterns-reference.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Common Bug Patterns Reference Tests * diff --git a/tests/chain-flag-plan-phase.test.cjs b/tests/chain-flag-plan-phase.test.cjs index d35507be9..6bd1a2fb1 100644 --- a/tests/chain-flag-plan-phase.test.cjs +++ b/tests/chain-flag-plan-phase.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - chain flag preservation in plan-phase * diff --git a/tests/check-update-config-dir.test.cjs b/tests/check-update-config-dir.test.cjs index 93e4453be..6aae30889 100644 --- a/tests/check-update-config-dir.test.cjs +++ b/tests/check-update-config-dir.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #1860: detectConfigDir in gsd-check-update.js should * prioritize .claude over .config/opencode so that Claude Code sessions diff --git a/tests/claude-md.test.cjs b/tests/claude-md.test.cjs index c26a4560f..5de6eb1a2 100644 --- a/tests/claude-md.test.cjs +++ b/tests/claude-md.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * CLAUDE.md generation and new-project workflow tests */ diff --git a/tests/claude-skills-migration.test.cjs b/tests/claude-skills-migration.test.cjs index 508918e5d..370b16efb 100644 --- a/tests/claude-skills-migration.test.cjs +++ b/tests/claude-skills-migration.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - Claude Skills Migration (#1504) * diff --git a/tests/cline-install.test.cjs b/tests/cline-install.test.cjs index 383b89c6e..02b51bace 100644 --- a/tests/cline-install.test.cjs +++ b/tests/cline-install.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression tests for bug #1991 * diff --git a/tests/cline-support.test.cjs b/tests/cline-support.test.cjs index 9625c9c9d..459580851 100644 --- a/tests/cline-support.test.cjs +++ b/tests/cline-support.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + const { test, describe } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/code-review-command.test.cjs b/tests/code-review-command.test.cjs index 868d5cc79..467a57a77 100644 --- a/tests/code-review-command.test.cjs +++ b/tests/code-review-command.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Tests for code_review_command hook in ship workflow (#1876) * diff --git a/tests/code-review.test.cjs b/tests/code-review.test.cjs index 233435267..5359b6f52 100644 --- a/tests/code-review.test.cjs +++ b/tests/code-review.test.cjs @@ -1,3 +1,7 @@ +// 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 Code Review Tests * diff --git a/tests/codebuddy-install.test.cjs b/tests/codebuddy-install.test.cjs index 3af1e2725..f87e44a13 100644 --- a/tests/codebuddy-install.test.cjs +++ b/tests/codebuddy-install.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + process.env.GSD_TEST_MODE = '1'; const { test, describe, beforeEach, afterEach } = require('node:test'); diff --git a/tests/codex-config.test.cjs b/tests/codex-config.test.cjs index 087d3b54e..c7f662621 100644 --- a/tests/codex-config.test.cjs +++ b/tests/codex-config.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - codex-config.cjs * diff --git a/tests/commands.test.cjs b/tests/commands.test.cjs index 0c3f88dc1..31b73fdff 100644 --- a/tests/commands.test.cjs +++ b/tests/commands.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - Commands */ diff --git a/tests/concurrency-safety.test.cjs b/tests/concurrency-safety.test.cjs index 6180095ad..5d09b9486 100644 --- a/tests/concurrency-safety.test.cjs +++ b/tests/concurrency-safety.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - Concurrency Safety * diff --git a/tests/config-schema-docs-parity.test.cjs b/tests/config-schema-docs-parity.test.cjs index 7d35fa077..35f235cdf 100644 --- a/tests/config-schema-docs-parity.test.cjs +++ b/tests/config-schema-docs-parity.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Asserts every exact-match key in config-schema.cjs appears at least once * in docs/CONFIGURATION.md. A key present in the validator but absent from diff --git a/tests/context-enrichment.test.cjs b/tests/context-enrichment.test.cjs index 956dde896..92556f249 100644 --- a/tests/context-enrichment.test.cjs +++ b/tests/context-enrichment.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - Adaptive Context Enrichment for 1M Models * diff --git a/tests/core.test.cjs b/tests/core.test.cjs index 155e212ff..f5a4a48fe 100644 --- a/tests/core.test.cjs +++ b/tests/core.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - core.cjs * diff --git a/tests/cursor-reviewer.test.cjs b/tests/cursor-reviewer.test.cjs index 5fba75cae..78fde8ac2 100644 --- a/tests/cursor-reviewer.test.cjs +++ b/tests/cursor-reviewer.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Cursor CLI Reviewer Tests (#1960) * diff --git a/tests/debug-session-management.test.cjs b/tests/debug-session-management.test.cjs index f3fb0951a..83b0a3b49 100644 --- a/tests/debug-session-management.test.cjs +++ b/tests/debug-session-management.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + const { describe, test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); diff --git a/tests/discuss-all-flag.test.cjs b/tests/discuss-all-flag.test.cjs index e1f8bf1ca..7cb76fa45 100644 --- a/tests/discuss-all-flag.test.cjs +++ b/tests/discuss-all-flag.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * Tests for --all flag on /gsd-discuss-phase (#2188) * diff --git a/tests/discuss-checkpoint.test.cjs b/tests/discuss-checkpoint.test.cjs index bebd9d126..f589d2c8f 100644 --- a/tests/discuss-checkpoint.test.cjs +++ b/tests/discuss-checkpoint.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - discuss-phase incremental checkpoint saves * diff --git a/tests/discuss-phase-power.test.cjs b/tests/discuss-phase-power.test.cjs index 06d82cab6..5785542de 100644 --- a/tests/discuss-phase-power.test.cjs +++ b/tests/discuss-phase-power.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - discuss-phase power user mode * diff --git a/tests/drift-detection.test.cjs b/tests/drift-detection.test.cjs index a76a699d7..7b8e07ea4 100644 --- a/tests/drift-detection.test.cjs +++ b/tests/drift-detection.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests — Codebase Drift Detection (#2003) * diff --git a/tests/edit-phase.test.cjs b/tests/edit-phase.test.cjs index e784e23f3..16db89a9c 100644 --- a/tests/edit-phase.test.cjs +++ b/tests/edit-phase.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Tests for /gsd-edit-phase (#2617) * diff --git a/tests/enh-2310-chunked-plan-phase.test.cjs b/tests/enh-2310-chunked-plan-phase.test.cjs index d4592310d..c9c395c88 100644 --- a/tests/enh-2310-chunked-plan-phase.test.cjs +++ b/tests/enh-2310-chunked-plan-phase.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Tests for #2310: plan-phase chunked mode + filesystem fallback. * diff --git a/tests/enh-2380-sync-skills.test.cjs b/tests/enh-2380-sync-skills.test.cjs index 75d3a84a0..895b01f0a 100644 --- a/tests/enh-2380-sync-skills.test.cjs +++ b/tests/enh-2380-sync-skills.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Tests for #2380 — /gsd-sync-skills cross-runtime skill sync. * diff --git a/tests/enh-2415-claude-md-link-mode.test.cjs b/tests/enh-2415-claude-md-link-mode.test.cjs index 31afe9c7b..ae5e453de 100644 --- a/tests/enh-2415-claude-md-link-mode.test.cjs +++ b/tests/enh-2415-claude-md-link-mode.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Tests for claude_md_assembly "link" mode (#2415). * Verifies that generate-claude-md writes @-references instead of inlined diff --git a/tests/enh-2430-learnings-consumption.test.cjs b/tests/enh-2430-learnings-consumption.test.cjs index a7a7eea45..6cca4b07d 100644 --- a/tests/enh-2430-learnings-consumption.test.cjs +++ b/tests/enh-2430-learnings-consumption.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Tests for #2430 — LEARNINGS.md consumption loop. * diff --git a/tests/enh-2433-todo-phase-linking.test.cjs b/tests/enh-2433-todo-phase-linking.test.cjs index fb120f3de..bb33fce77 100644 --- a/tests/enh-2433-todo-phase-linking.test.cjs +++ b/tests/enh-2433-todo-phase-linking.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Tests for gsd-new-milestone todo-to-phase linking (#2433). * Verifies the workflow text contains the correct linking and auto-close steps. diff --git a/tests/enh-2446-milestones-drift.test.cjs b/tests/enh-2446-milestones-drift.test.cjs index cbb2646c3..fca1eb52e 100644 --- a/tests/enh-2446-milestones-drift.test.cjs +++ b/tests/enh-2446-milestones-drift.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Tests for gsd-health MILESTONES.md drift detection (#2446). */ diff --git a/tests/enh-2447-roadmap-wave-deps.test.cjs b/tests/enh-2447-roadmap-wave-deps.test.cjs index cbdd9c642..a1a9f5bc7 100644 --- a/tests/enh-2447-roadmap-wave-deps.test.cjs +++ b/tests/enh-2447-roadmap-wave-deps.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Tests for ROADMAP wave dependency surfacing (#2447). */ diff --git a/tests/enh-2448-artifact-registry.test.cjs b/tests/enh-2448-artifact-registry.test.cjs index eb26f1fb8..6c683d2bd 100644 --- a/tests/enh-2448-artifact-registry.test.cjs +++ b/tests/enh-2448-artifact-registry.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * Tests for canonical artifact registry and gsd-health W019 lint (#2448). */ diff --git a/tests/execute-phase-active-flags.test.cjs b/tests/execute-phase-active-flags.test.cjs index c7f389d57..1a0138dda 100644 --- a/tests/execute-phase-active-flags.test.cjs +++ b/tests/execute-phase-active-flags.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Execute-phase active flag prompt tests * diff --git a/tests/execute-phase-worktree-artifacts.test.cjs b/tests/execute-phase-worktree-artifacts.test.cjs index b40690a61..64551900f 100644 --- a/tests/execute-phase-worktree-artifacts.test.cjs +++ b/tests/execute-phase-worktree-artifacts.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Execute-phase worktree shared artifact ownership tests * diff --git a/tests/explore-command.test.cjs b/tests/explore-command.test.cjs index a73c1eae1..87e68953e 100644 --- a/tests/explore-command.test.cjs +++ b/tests/explore-command.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + const { describe, test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/extract-learnings.test.cjs b/tests/extract-learnings.test.cjs index dbf1db280..129263382 100644 --- a/tests/extract-learnings.test.cjs +++ b/tests/extract-learnings.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Extract-Learnings Command & Workflow Tests * diff --git a/tests/forensics.test.cjs b/tests/forensics.test.cjs index a9e14dc69..57fbedf80 100644 --- a/tests/forensics.test.cjs +++ b/tests/forensics.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Forensics Tests * diff --git a/tests/frontmatter-cli.test.cjs b/tests/frontmatter-cli.test.cjs index bc7b95201..b81565f7c 100644 --- a/tests/frontmatter-cli.test.cjs +++ b/tests/frontmatter-cli.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - frontmatter CLI integration * diff --git a/tests/gates-taxonomy.test.cjs b/tests/gates-taxonomy.test.cjs index 9ea51f191..17b0366d4 100644 --- a/tests/gates-taxonomy.test.cjs +++ b/tests/gates-taxonomy.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Validates the gates taxonomy reference document (#1715). * diff --git a/tests/gsd-settings-advanced.test.cjs b/tests/gsd-settings-advanced.test.cjs index 830dcc376..f8362fb0e 100644 --- a/tests/gsd-settings-advanced.test.cjs +++ b/tests/gsd-settings-advanced.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Tests for `/gsd-settings-advanced` — power-user configuration command (#2528). * diff --git a/tests/gsd2-import.test.cjs b/tests/gsd2-import.test.cjs index 80becb4a3..3010b9d36 100644 --- a/tests/gsd2-import.test.cjs +++ b/tests/gsd2-import.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + const { describe, it, test, beforeEach, afterEach } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); diff --git a/tests/hermes-skills-migration.test.cjs b/tests/hermes-skills-migration.test.cjs index 84c24b5da..69e2bd7b9 100644 --- a/tests/hermes-skills-migration.test.cjs +++ b/tests/hermes-skills-migration.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - Hermes Agent Skills Migration * diff --git a/tests/import-command.test.cjs b/tests/import-command.test.cjs index 739b0265c..4bcbca34f 100644 --- a/tests/import-command.test.cjs +++ b/tests/import-command.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Import Command Tests — import-command.test.cjs * diff --git a/tests/ingest-docs.test.cjs b/tests/ingest-docs.test.cjs index 851079473..f82e5a262 100644 --- a/tests/ingest-docs.test.cjs +++ b/tests/ingest-docs.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * Ingest Docs Tests — ingest-docs.test.cjs * diff --git a/tests/inline-plan-threshold.test.cjs b/tests/inline-plan-threshold.test.cjs index e8e4265ce..d9566b47e 100644 --- a/tests/inline-plan-threshold.test.cjs +++ b/tests/inline-plan-threshold.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Tests for workflow.inline_plan_threshold config key and routing logic (#1979). * diff --git a/tests/install-hooks-copy.test.cjs b/tests/install-hooks-copy.test.cjs index 2eb821a9b..741fee103 100644 --- a/tests/install-hooks-copy.test.cjs +++ b/tests/install-hooks-copy.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression tests for install process hook copying, permissions, manifest * tracking, uninstall cleanup, and settings.json registration. diff --git a/tests/install-minimal.test.cjs b/tests/install-minimal.test.cjs index ceba4c8b5..b341cb9ca 100644 --- a/tests/install-minimal.test.cjs +++ b/tests/install-minimal.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * Tests for `--minimal` install profile (#2762). * diff --git a/tests/inventory-counts.test.cjs b/tests/inventory-counts.test.cjs index a2920b4f5..0d4936cdc 100644 --- a/tests/inventory-counts.test.cjs +++ b/tests/inventory-counts.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Locks docs/INVENTORY.md's "(N shipped)" headline counts against the * filesystem for each of the six families. INVENTORY.md is the diff --git a/tests/ios-scaffold-safety.test.cjs b/tests/ios-scaffold-safety.test.cjs index 9c7e2eaae..49c10f96e 100644 --- a/tests/ios-scaffold-safety.test.cjs +++ b/tests/ios-scaffold-safety.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * iOS Scaffold Safety Tests (#2023) * diff --git a/tests/issue-2639-codex-toml-neutralization.test.cjs b/tests/issue-2639-codex-toml-neutralization.test.cjs index 0167e5c4d..dc939361d 100644 --- a/tests/issue-2639-codex-toml-neutralization.test.cjs +++ b/tests/issue-2639-codex-toml-neutralization.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression: issue #2639 — Codex install generated agent TOMLs with stale * Claude-specific references (CLAUDE.md, .claude/skills/, .claudeignore). diff --git a/tests/kilo-install.test.cjs b/tests/kilo-install.test.cjs index 77553c93d..bf4bb2537 100644 --- a/tests/kilo-install.test.cjs +++ b/tests/kilo-install.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - Kilo Install Plumbing * diff --git a/tests/mcp-tool-inheritance.test.cjs b/tests/mcp-tool-inheritance.test.cjs index 3c37548f2..39dfe51c9 100644 --- a/tests/mcp-tool-inheritance.test.cjs +++ b/tests/mcp-tool-inheritance.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + const { test, describe } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/milestone-audit.test.cjs b/tests/milestone-audit.test.cjs index 9f4678c4b..f0439bb0c 100644 --- a/tests/milestone-audit.test.cjs +++ b/tests/milestone-audit.test.cjs @@ -1,4 +1,8 @@ 'use strict'; +// 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. + const { describe, test, beforeEach, afterEach } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/milestone-summary.test.cjs b/tests/milestone-summary.test.cjs index 56373d4d1..908d9747f 100644 --- a/tests/milestone-summary.test.cjs +++ b/tests/milestone-summary.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Milestone Summary Tests * diff --git a/tests/milestone.test.cjs b/tests/milestone.test.cjs index 80f1b0e67..b3d9b9e32 100644 --- a/tests/milestone.test.cjs +++ b/tests/milestone.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - Milestone */ diff --git a/tests/next-safety-gates.test.cjs b/tests/next-safety-gates.test.cjs index 370283224..717baf1a2 100644 --- a/tests/next-safety-gates.test.cjs +++ b/tests/next-safety-gates.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - /gsd-next safety gates and prior-phase completeness scan * diff --git a/tests/next-up-clear-order.test.cjs b/tests/next-up-clear-order.test.cjs index e774e2c95..a7bb5b3ca 100644 --- a/tests/next-up-clear-order.test.cjs +++ b/tests/next-up-clear-order.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Next Up /clear Order Tests (#1623) * diff --git a/tests/opencode-permissions.test.cjs b/tests/opencode-permissions.test.cjs index 98c79ed49..db74db236 100644 --- a/tests/opencode-permissions.test.cjs +++ b/tests/opencode-permissions.test.cjs @@ -1,3 +1,7 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Do not copy this pattern. + /** * Regression tests for OpenCode permission config handling. * diff --git a/tests/orphaned-hooks.test.cjs b/tests/orphaned-hooks.test.cjs index b724b9dae..1e7bdc107 100644 --- a/tests/orphaned-hooks.test.cjs +++ b/tests/orphaned-hooks.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression test for #1750: orphaned hook files from removed features * (e.g., gsd-intel-*.js) should NOT be flagged as stale by gsd-check-update.js. diff --git a/tests/parallel-dependent-plans.test.cjs b/tests/parallel-dependent-plans.test.cjs index 443a0189c..7b142ffbb 100644 --- a/tests/parallel-dependent-plans.test.cjs +++ b/tests/parallel-dependent-plans.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Tests for bug #1587: parallel agents for dependent plans * diff --git a/tests/path-replacement.test.cjs b/tests/path-replacement.test.cjs index 739bbe99e..4c0bebc62 100644 --- a/tests/path-replacement.test.cjs +++ b/tests/path-replacement.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tests - path replacement in install.js * diff --git a/tests/phase-researcher-app-aware.test.cjs b/tests/phase-researcher-app-aware.test.cjs index 9c64cac75..39748d665 100644 --- a/tests/phase-researcher-app-aware.test.cjs +++ b/tests/phase-researcher-app-aware.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Phase Researcher Application-Aware Tests (#1988) * diff --git a/tests/phase-researcher-flow-diagram.test.cjs b/tests/phase-researcher-flow-diagram.test.cjs index 79334ce7d..b9429a762 100644 --- a/tests/phase-researcher-flow-diagram.test.cjs +++ b/tests/phase-researcher-flow-diagram.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Phase Researcher Flow Diagram Tests (#2139) * diff --git a/tests/phase.test.cjs b/tests/phase.test.cjs index 115721b1a..68779c1af 100644 --- a/tests/phase.test.cjs +++ b/tests/phase.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - Phase */ diff --git a/tests/plan-phase-ui-redirect.test.cjs b/tests/plan-phase-ui-redirect.test.cjs index 368e49d22..bcdbad946 100644 --- a/tests/plan-phase-ui-redirect.test.cjs +++ b/tests/plan-phase-ui-redirect.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + const { describe, test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/planner-decomposition.test.cjs b/tests/planner-decomposition.test.cjs index 5933436a5..bc2b3449d 100644 --- a/tests/planner-decomposition.test.cjs +++ b/tests/planner-decomposition.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Tests for modular decomposition of agents/gsd-planner.md * diff --git a/tests/planner-language-regression.test.cjs b/tests/planner-language-regression.test.cjs index b43d96da2..55cf914a1 100644 --- a/tests/planner-language-regression.test.cjs +++ b/tests/planner-language-regression.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Planner Language Regression Tests (#2091, #2092) * diff --git a/tests/playwright-ui-verify.test.cjs b/tests/playwright-ui-verify.test.cjs index dd6e9bfe3..ab5513932 100644 --- a/tests/playwright-ui-verify.test.cjs +++ b/tests/playwright-ui-verify.test.cjs @@ -1,3 +1,7 @@ +// 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. + const { test, describe } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/product-name-purity.test.cjs b/tests/product-name-purity.test.cjs index 4c995ad9c..dde7511bc 100644 --- a/tests/product-name-purity.test.cjs +++ b/tests/product-name-purity.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression guard for #1777: product names must not have parenthetical descriptions. * diff --git a/tests/profile-output.test.cjs b/tests/profile-output.test.cjs index 05364b1af..78e4f6739 100644 --- a/tests/profile-output.test.cjs +++ b/tests/profile-output.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * Profile Output Tests * diff --git a/tests/progress-forensic.test.cjs b/tests/progress-forensic.test.cjs index 994093124..723968e2a 100644 --- a/tests/progress-forensic.test.cjs +++ b/tests/progress-forensic.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * Tests for --forensic flag on /gsd-progress (#2189) * diff --git a/tests/prompt-thinning.test.cjs b/tests/prompt-thinning.test.cjs index 62a562ae3..3c404e541 100644 --- a/tests/prompt-thinning.test.cjs +++ b/tests/prompt-thinning.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Prompt Thinning Tests (#1978) * diff --git a/tests/quick-session-management.test.cjs b/tests/quick-session-management.test.cjs index 4db001090..5fddfe151 100644 --- a/tests/quick-session-management.test.cjs +++ b/tests/quick-session-management.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + const { describe, test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/qwen-skills-migration.test.cjs b/tests/qwen-skills-migration.test.cjs index 683e4aa9e..25a5c2f7c 100644 --- a/tests/qwen-skills-migration.test.cjs +++ b/tests/qwen-skills-migration.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - Qwen Code Skills Migration * diff --git a/tests/read-guard.test.cjs b/tests/read-guard.test.cjs index 69a8c094c..7a3eba2d5 100644 --- a/tests/read-guard.test.cjs +++ b/tests/read-guard.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Tests for gsd-read-guard.js PreToolUse hook. * diff --git a/tests/roadmap.test.cjs b/tests/roadmap.test.cjs index b4530b4e4..ab05926ca 100644 --- a/tests/roadmap.test.cjs +++ b/tests/roadmap.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - Roadmap */ diff --git a/tests/scan-command.test.cjs b/tests/scan-command.test.cjs index 0b4ef1fbe..290b03d6d 100644 --- a/tests/scan-command.test.cjs +++ b/tests/scan-command.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + const { describe, test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/sdk-no-sdk-guard.test.cjs b/tests/sdk-no-sdk-guard.test.cjs index 111975191..b50ee5afc 100644 --- a/tests/sdk-no-sdk-guard.test.cjs +++ b/tests/sdk-no-sdk-guard.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Static guard: every subprocess installer invocation inside a test file * (i.e. with GSD_TEST_MODE deleted so the real installer runs) MUST include diff --git a/tests/secure-phase.test.cjs b/tests/secure-phase.test.cjs index c39989363..680f8082c 100644 --- a/tests/secure-phase.test.cjs +++ b/tests/secure-phase.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Secure-Phase Tests * diff --git a/tests/seed-scan-new-milestone.test.cjs b/tests/seed-scan-new-milestone.test.cjs index e06723e04..3ee961fba 100644 --- a/tests/seed-scan-new-milestone.test.cjs +++ b/tests/seed-scan-new-milestone.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - Seed Scan in New Milestone (#2169) * diff --git a/tests/settings-integrations.test.cjs b/tests/settings-integrations.test.cjs index 49e084dc5..f189279ff 100644 --- a/tests/settings-integrations.test.cjs +++ b/tests/settings-integrations.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + /** * #2529 — /gsd-settings-integrations: configure third-party search and review integrations. * diff --git a/tests/settings-jsonc.test.cjs b/tests/settings-jsonc.test.cjs index 16e4a7612..3084e4d13 100644 --- a/tests/settings-jsonc.test.cjs +++ b/tests/settings-jsonc.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - settings.json JSONC (JSON with comments) support * diff --git a/tests/state.test.cjs b/tests/state.test.cjs index 363003d4c..39f6a8187 100644 --- a/tests/state.test.cjs +++ b/tests/state.test.cjs @@ -1,3 +1,7 @@ +// 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 Tools Tests - State */ diff --git a/tests/subagent-timeout.test.cjs b/tests/subagent-timeout.test.cjs index 71a10e6bf..1ea56211e 100644 --- a/tests/subagent-timeout.test.cjs +++ b/tests/subagent-timeout.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - subagent timeout configuration * diff --git a/tests/template.test.cjs b/tests/template.test.cjs index f27ed0822..d5672a228 100644 --- a/tests/template.test.cjs +++ b/tests/template.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Template Tests * diff --git a/tests/thinking-partner.test.cjs b/tests/thinking-partner.test.cjs index 1a12903e9..4ebf14613 100644 --- a/tests/thinking-partner.test.cjs +++ b/tests/thinking-partner.test.cjs @@ -1,3 +1,7 @@ +// 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. + const { describe, test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/thread-session-management.test.cjs b/tests/thread-session-management.test.cjs index 153262d57..a53c8c228 100644 --- a/tests/thread-session-management.test.cjs +++ b/tests/thread-session-management.test.cjs @@ -1,5 +1,9 @@ 'use strict'; +// 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. + const { describe, test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); diff --git a/tests/trae-install.test.cjs b/tests/trae-install.test.cjs index 21e347d03..ffefb8366 100644 --- a/tests/trae-install.test.cjs +++ b/tests/trae-install.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + process.env.GSD_TEST_MODE = '1'; const { test, describe, beforeEach, afterEach } = require('node:test'); diff --git a/tests/ultraplan-phase.test.cjs b/tests/ultraplan-phase.test.cjs index fb37194a8..bcb799742 100644 --- a/tests/ultraplan-phase.test.cjs +++ b/tests/ultraplan-phase.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * /gsd-ultraplan-phase [BETA] Tests * diff --git a/tests/verify-health.test.cjs b/tests/verify-health.test.cjs index ddeea35f0..c36c1e9f8 100644 --- a/tests/verify-health.test.cjs +++ b/tests/verify-health.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - Validate Health Command * diff --git a/tests/verify-test-quality.test.cjs b/tests/verify-test-quality.test.cjs index de1940873..77f440505 100644 --- a/tests/verify-test-quality.test.cjs +++ b/tests/verify-test-quality.test.cjs @@ -1,3 +1,7 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Do not copy this pattern. + /** * Tests for the audit_test_quality step in verify-phase.md * diff --git a/tests/verify-work-auto-transition.test.cjs b/tests/verify-work-auto-transition.test.cjs index 439eb5c8a..76533a5e5 100644 --- a/tests/verify-work-auto-transition.test.cjs +++ b/tests/verify-work-auto-transition.test.cjs @@ -1,5 +1,10 @@ 'use strict'; +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * verify-work auto-transition tests (#2018) * diff --git a/tests/windows-robustness.test.cjs b/tests/windows-robustness.test.cjs index 160cd1d66..ae8906711 100644 --- a/tests/windows-robustness.test.cjs +++ b/tests/windows-robustness.test.cjs @@ -1,3 +1,7 @@ +// 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. + /** * Windows Robustness Tests * diff --git a/tests/workflow-compat.test.cjs b/tests/workflow-compat.test.cjs index ae8c678e6..2c47a99e0 100644 --- a/tests/workflow-compat.test.cjs +++ b/tests/workflow-compat.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression guard for #1759: the --no-input flag was removed from Claude Code * >= v2.1.81 and causes an immediate crash ("error: unknown option '--no-input'"). diff --git a/tests/workflow-guard-registration.test.cjs b/tests/workflow-guard-registration.test.cjs index f71b5a2e9..b2b11c02c 100644 --- a/tests/workflow-guard-registration.test.cjs +++ b/tests/workflow-guard-registration.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Regression guard for #1767: gsd-workflow-guard.js must be registered in settings.json * diff --git a/tests/workflow-size-budget.test.cjs b/tests/workflow-size-budget.test.cjs index dbe994d28..01519cc30 100644 --- a/tests/workflow-size-budget.test.cjs +++ b/tests/workflow-size-budget.test.cjs @@ -1,3 +1,7 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Do not copy this pattern. + /** * Workflow size budget. * diff --git a/tests/worktree-cleanup.test.cjs b/tests/worktree-cleanup.test.cjs index 80a350fb7..72d97f448 100644 --- a/tests/worktree-cleanup.test.cjs +++ b/tests/worktree-cleanup.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * GSD Tools Tests - worktree cleanup after executor completes * diff --git a/tests/worktree-merge-protection.test.cjs b/tests/worktree-merge-protection.test.cjs index 23c56a464..cd40420fc 100644 --- a/tests/worktree-merge-protection.test.cjs +++ b/tests/worktree-merge-protection.test.cjs @@ -1,3 +1,8 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Per-file review may +// reclassify some entries as source-text-is-the-product during migration. + /** * Worktree merge orchestrator file protection tests * diff --git a/tests/worktree-safety.test.cjs b/tests/worktree-safety.test.cjs index 72bf18e8e..0e272a69c 100644 --- a/tests/worktree-safety.test.cjs +++ b/tests/worktree-safety.test.cjs @@ -1,3 +1,7 @@ +// allow-test-rule: pending-migration-to-typed-ir [#2974] +// Tracked in #2974 for migration to typed-IR assertions per CONTRIBUTING.md +// "Prohibited: Raw Text Matching on Test Outputs". Do not copy this pattern. + /** * Worktree commit safety hardening tests (#1977) *