// tools/challenge-spec/platform-challenge-scenarios.ts
// SPEC-015a: Challenge scenarios for Smart Contracts, Bots, and IoT projects
import { getAdvancedPlatformChallenges } from './platform-challenge-scenarios-b.js';
// === Smart Contract challenges (criterion 9) ===
function buildSmartContractChallenges(spec, content) {
    const lower = content.toLowerCase();
    const hasMention = (keywords) => keywords.some((kw) => lower.includes(kw));
    const scenarios = [];
    // Reentrancy
    scenarios.push({
        scenario: 'Reentrancy attack: malicious contract calls back before state update',
        probability: 'medium',
        impact: 'critical',
        currentHandling: hasMention(['nonreentrant', 'reentrancy', 'checks-effects-interactions'])
            ? 'Guard mentioned in spec'
            : 'Not addressed',
        requiredHandling: 'Apply checks-effects-interactions pattern. Use OpenZeppelin `ReentrancyGuard`. ' +
            'Update state BEFORE external calls.',
        dataConsistency: 'All funds/balances must be updated atomically before any external call.',
        userExperience: 'Transaction should revert with descriptive error on reentry attempt.',
    });
    // Integer overflow
    scenarios.push({
        scenario: 'Integer overflow/underflow causing unexpected balance or counter values',
        probability: 'low',
        impact: 'critical',
        currentHandling: hasMention(['safematch', 'overflow', 'unchecked'])
            ? 'Overflow protection noted'
            : 'Relies on Solidity 0.8+ built-in checks',
        requiredHandling: 'Solidity 0.8+ reverts on overflow by default. For gas optimization with `unchecked {}`, ' +
            'document why overflow is safe. Audit all arithmetic paths.',
        dataConsistency: 'Critical: token/ETH amounts must never overflow silently.',
        userExperience: 'Transaction reverts with "Arithmetic overflow" if built-in check triggers.',
    });
    // Gas limits
    scenarios.push({
        scenario: 'Gas limit exceeded in loops over unbounded arrays/mappings',
        probability: 'high',
        impact: 'high',
        currentHandling: hasMention(['pagination', 'batch', 'gas', 'limit'])
            ? 'Some batching mentioned'
            : 'Not addressed',
        requiredHandling: 'Limit loop iterations with a max cap. Prefer pagination over full enumeration. ' +
            'Use events for off-chain indexing instead of on-chain arrays.',
        dataConsistency: 'Partial loop execution must not leave state inconsistent.',
        userExperience: 'Implement off-chain indexing (The Graph) for queries needing iteration.',
    });
    // Access control
    scenarios.push({
        scenario: 'Unauthorized function call: missing access control on sensitive functions',
        probability: 'high',
        impact: 'critical',
        currentHandling: hasMention(['onlyowner', 'access', 'role', 'modifier'])
            ? 'Access control mentioned'
            : 'Not addressed',
        requiredHandling: 'Apply `onlyOwner`, `AccessControl`, or custom modifiers to admin functions. ' +
            'Use role-based access (ADMIN_ROLE, MINTER_ROLE). Validate every external/public function.',
        dataConsistency: 'All privileged operations require explicit authorization check.',
        userExperience: 'Unauthorized calls revert with meaningful error ("Caller is not admin").',
    });
    // Front-running
    scenarios.push({
        scenario: 'Front-running: mempool observer submits higher-gas tx to steal value',
        probability: 'medium',
        impact: 'high',
        currentHandling: hasMention(['commit-reveal', 'slippage', 'deadline', 'frontrun'])
            ? 'Mitigation strategy noted'
            : 'Not addressed',
        requiredHandling: 'For swaps: add slippage tolerance + deadline. For auctions: use commit-reveal scheme. ' +
            'For price-sensitive ops: use TWAP oracles instead of spot price.',
        dataConsistency: 'Final price/amount must match user expectation within slippage bounds.',
        userExperience: 'Transactions revert if slippage or deadline exceeded (user sees reason).',
    });
    void spec; // spec used for context
    return scenarios;
}
// === Bot challenges (criterion 10) ===
function buildBotChallenges(spec, content) {
    const lower = content.toLowerCase();
    const hasMention = (keywords) => keywords.some((kw) => lower.includes(kw));
    const scenarios = [];
    // Rate limiting
    scenarios.push({
        scenario: 'Bot exceeds platform API rate limits, causing commands to silently fail',
        probability: 'high',
        impact: 'high',
        currentHandling: hasMention(['rate limit', 'throttle', 'queue'])
            ? 'Rate limiting mentioned'
            : 'Not addressed',
        requiredHandling: 'Implement request queue with rate limiter (token bucket). Retry with exponential backoff. ' +
            'Cache frequently requested data. Respect per-route Discord/Slack limits.',
        dataConsistency: 'Queued commands must be executed in order; no silent drops.',
        userExperience: 'Inform user when request is queued: "Your request is processing, please wait."',
    });
    // Spam and abuse
    scenarios.push({
        scenario: 'User or bot sends flood of commands, causing DoS or cost spike',
        probability: 'high',
        impact: 'medium',
        currentHandling: hasMention(['cooldown', 'spam', 'abuse', 'permission'])
            ? 'Spam prevention noted'
            : 'Not addressed',
        requiredHandling: 'Per-user cooldown (e.g. 5 req/10s). Block users who exceed limits. ' +
            'Whitelist/allowlist for expensive commands.',
        dataConsistency: 'Blocked operations must not partially execute.',
        userExperience: 'Respond with cooldown remaining time: "Please wait 8s before reusing this command."',
    });
    // Command injection
    scenarios.push({
        scenario: 'Malicious user injects shell commands or SQL via bot command arguments',
        probability: 'medium',
        impact: 'critical',
        currentHandling: hasMention(['sanitize', 'escape', 'validate', 'injection'])
            ? 'Input validation noted'
            : 'Not addressed',
        requiredHandling: 'Sanitize all user inputs. Use parameterized queries. ' +
            'Never pass user input to shell. Validate argument types strictly.',
        dataConsistency: 'No user input reaches database or system calls unsanitized.',
        userExperience: 'Reject invalid input with clear error message before processing.',
    });
    // API limits
    scenarios.push({
        scenario: 'Downstream API (OpenAI, external service) is unavailable or returns error',
        probability: 'medium',
        impact: 'high',
        currentHandling: hasMention(['fallback', 'timeout', 'error handling'])
            ? 'Error handling noted'
            : 'Not addressed',
        requiredHandling: 'Implement circuit breaker pattern. Define timeout for each API call (5-10s). ' +
            'Provide fallback response when external service fails.',
        dataConsistency: 'Bot state must not be corrupted when external API fails.',
        userExperience: 'Communicate service degradation: "Feature temporarily unavailable, try again later."',
    });
    void spec;
    return scenarios;
}
// === IoT challenges (criterion 11) ===
function buildIoTChallenges(spec, content) {
    const lower = content.toLowerCase();
    const hasMention = (keywords) => keywords.some((kw) => lower.includes(kw));
    const scenarios = [];
    // Connectivity loss
    scenarios.push({
        scenario: 'Network connectivity lost while device is transmitting sensor data',
        probability: 'high',
        impact: 'high',
        currentHandling: hasMention(['offline', 'queue', 'reconnect', 'local storage'])
            ? 'Offline handling mentioned'
            : 'Not addressed',
        requiredHandling: 'Buffer readings locally (flash/EEPROM). Queue messages for later delivery. ' +
            'Implement exponential backoff reconnect. Define max local buffer size before dropping.',
        dataConsistency: 'Timestamps must be device-local (RTC) to avoid clock skew on reconnect.',
        userExperience: 'Dashboard shows "last seen X minutes ago" and data gap indicator.',
    });
    // Sensor failure
    scenarios.push({
        scenario: 'Sensor returns out-of-range values or stops responding',
        probability: 'medium',
        impact: 'high',
        currentHandling: hasMention(['sensor', 'validate', 'range', 'watchdog'])
            ? 'Sensor validation noted'
            : 'Not addressed',
        requiredHandling: 'Validate sensor readings against physical limits before processing. ' +
            'Implement watchdog timer to detect sensor hang. Alert on consecutive failures.',
        dataConsistency: 'Invalid readings must be marked (NaN/null), not silently discarded.',
        userExperience: 'Alert: "Sensor [id] is offline or returning invalid data."',
    });
    // Battery management
    scenarios.push({
        scenario: 'Battery depletes unexpectedly due to aggressive polling or wake frequency',
        probability: 'medium',
        impact: 'medium',
        currentHandling: hasMention(['sleep', 'deep sleep', 'power', 'battery'])
            ? 'Power management mentioned'
            : 'Not addressed',
        requiredHandling: 'Use deep sleep between readings. Adjust wake frequency based on battery level. ' +
            'Send battery % in every telemetry packet. Alert when <20%.',
        dataConsistency: 'Critical readings must be flushed before entering deep sleep.',
        userExperience: 'Battery level visible in dashboard. Low battery alert at threshold.',
    });
    // OTA failure
    scenarios.push({
        scenario: 'OTA firmware update fails mid-flash, leaving device in unbootable state',
        probability: 'low',
        impact: 'critical',
        currentHandling: hasMention(['ota', 'rollback', 'dual partition', 'backup'])
            ? 'OTA strategy noted'
            : 'Not addressed',
        requiredHandling: 'Use dual-partition OTA (A/B). Validate checksum before applying. ' +
            'Keep rollback partition intact. Require minimum battery level before OTA.',
        dataConsistency: 'OTA is atomic: device boots new firmware or rolls back, never partial.',
        userExperience: 'OTA progress reported to dashboard. Failure triggers automatic rollback and alert.',
    });
    void spec;
    return scenarios;
}
// === Public API ===
/**
 * Returns platform-specific challenge scenarios based on project category.
 * Covers smart contracts (criterion 9), bots (criterion 10), and IoT (criterion 11).
 */
export function getPlatformChallenges(spec, content, knowledge) {
    const scenarios = [];
    const category = knowledge.projectCategory;
    const framework = knowledge.framework?.toLowerCase() ?? '';
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime data may omit required fields
    const stack = (knowledge.stack ?? []).map((s) => s.toLowerCase());
    const isSmartContract = category === 'smart-contract' ||
        ['hardhat', 'foundry', 'anchor', 'move'].includes(framework) ||
        stack.some((s) => ['solidity', 'hardhat', 'foundry'].includes(s));
    const isBot = category === 'bot' ||
        stack.some((s) => ['discord.js', 'telegraf', 'grammy', '@slack/bolt'].includes(s));
    const isIoT = category === 'iot' || stack.some((s) => ['platformio', 'arduino', 'zephyr'].includes(s));
    if (isSmartContract) {
        scenarios.push(...buildSmartContractChallenges(spec, content));
    }
    if (isBot) {
        scenarios.push(...buildBotChallenges(spec, content));
    }
    if (isIoT) {
        scenarios.push(...buildIoTChallenges(spec, content));
    }
    // SPEC-015b: Advanced platform challenges (OWASP, ML distribution shift, IaC state, IoT power loss)
    scenarios.push(...getAdvancedPlatformChallenges(spec, content, knowledge));
    return scenarios;
}
//# sourceMappingURL=platform-challenge-scenarios.js.map