(changedFiles, scripts = {})
| 84 | } |
| 85 | |
| 86 | function profileForFiles(changedFiles, scripts = {}) { |
| 87 | const files = changedFiles.map(normalizePath); |
| 88 | const broad = defaultCommand(scripts); |
| 89 | const commands = [broad]; |
| 90 | const notes = []; |
| 91 | const touchesOperatorLoop = hasAny(files, (file) => file === 'scripts/dashboard.js' || file === 'scripts/next-action.js' || file === 'scripts/continue-action.js' || file === 'scripts/operator-console.js'); |
| 92 | let id = 'baseline'; |
| 93 | let label = 'Baseline regression'; |
| 94 | let reason = 'No narrower high-signal verification profile matched the changed paths.'; |
| 95 | |
| 96 | if (hasAny(files, (file) => file.startsWith('hooks_src/') || file.startsWith('hooks/'))) { |
| 97 | id = 'hook-runtime'; |
| 98 | label = 'Hook runtime verification'; |
| 99 | reason = 'Hook changes affect command safety, generated state, and lifecycle behavior.'; |
| 100 | commands.unshift( |
| 101 | 'node hooks_src/smoke-test.js', |
| 102 | 'node scripts/verify-hooks.js', |
| 103 | 'node scripts/integration-test.js' |
| 104 | ); |
| 105 | notes.push('Run hook smoke, synthetic hook verification, and integration sequences before relying on broad tests.'); |
| 106 | } else if (hasAny(files, (file) => file === 'scripts/deploy-steward.js' || file === 'scripts/test-deploy-steward.js' || file.startsWith('core/deploy-steward/') || file.startsWith('skills/deploy-steward/'))) { |
| 107 | id = 'deploy-steward'; |
| 108 | label = 'Deploy steward verification'; |
| 109 | reason = 'Deploy steward changes affect mainline serialization, CI gates, merge behavior, deploy handoff, and repair task generation.'; |
| 110 | commands.unshift( |
| 111 | 'node scripts/test-deploy-steward.js', |
| 112 | 'node scripts/test-pr-ready.js', |
| 113 | 'node scripts/test-stack-plan.js' |
| 114 | ); |
| 115 | if (hasAny(files, (file) => file.startsWith('skills/deploy-steward/'))) { |
| 116 | commands.unshift('node scripts/skill-lint.js deploy-steward'); |
| 117 | } |
| 118 | notes.push('Steward changes must prove queue/lease behavior plus the PR readiness and stack-plan inputs that feed it.'); |
| 119 | } else if (hasAny(files, (file) => file.startsWith('skills/') || file === 'scripts/skill-lint.js')) { |
| 120 | id = 'skill-surface'; |
| 121 | label = 'Skill surface verification'; |
| 122 | reason = 'Skill changes affect routing, operator instructions, and user-facing agent behavior.'; |
| 123 | commands.unshift('node scripts/skill-lint.js'); |
| 124 | notes.push('Skill lint proves structure; broad tests catch routing and packaging regressions.'); |
| 125 | } else if (hasAny(files, (file) => file === 'docs/index.html' || file === 'scripts/test-demo.js')) { |
| 126 | id = 'demo-experience'; |
| 127 | label = 'Demo experience verification'; |
| 128 | reason = 'Demo page changes affect the first-run public experience.'; |
| 129 | commands.unshift('node scripts/test-demo.js'); |
| 130 | notes.push('Demo routing checks are required because broad tests alone do not inspect the page copy and links deeply.'); |
| 131 | } else if (touchesOperatorLoop) { |
| 132 | id = 'operator-loop'; |
| 133 | label = 'Operator loop verification'; |
| 134 | reason = 'Operator changes affect the next-action, dashboard, and continuation path.'; |
| 135 | commands.unshift( |
| 136 | 'node scripts/test-dashboard.js', |
| 137 | 'node scripts/test-next-action.js', |
| 138 | 'node scripts/test-continue-action.js', |
| 139 | 'node scripts/test-operator-console.js', |
| 140 | 'node scripts/test-operator-journey.js' |
| 141 | ); |
| 142 | notes.push('Verify both focused operator behavior and the full intake-to-package journey.'); |
| 143 | } else if (hasAny(files, (file) => file === 'scripts/pr-ready.js' || file === 'scripts/verification-plan.js' || file === 'core/verification/profiles.js')) { |
no test coverage detected