{
  "name": "long-context-multi-file-config",
  "description": "Trace and fix a configuration value propagation bug across 5 interconnected Python files",
  "dataset": "terminal-bench-local",
  "difficulty": "medium",
  "instruction": "This is a small Python web application with 5 files: config.py, database.py, api.py, auth.py, and main.py. There is a bug: the 'max_connections' config value is not being propagated correctly through the system.\n\nThe config defines max_connections=10, but the database module, api module, and auth module all handle this value incorrectly in different ways. You need to read ALL files, understand the data flow, and fix every place where max_connections is being misused, lost, overridden, or ignored.\n\nSpecifically:\n1. config.py defines the settings correctly - do NOT change it\n2. database.py should respect config.max_connections for its pool size\n3. api.py should pass the connection limit to its rate limiter\n4. auth.py should use the shared connection pool, not create its own\n5. main.py should wire everything together correctly\n\nThe test verifies that all components see the correct max_connections value and that the system initializes properly. Run python3 test_config.py to verify.",
  "setup_files": {
    "config.py": "\"\"\"Application configuration module.\n\nAll configuration values are defined here and should be imported\nby other modules. Do NOT modify this file.\n\"\"\"\n\nclass AppConfig:\n    \"\"\"Central application configuration.\"\"\"\n    \n    # Server settings\n    host = '0.0.0.0'\n    port = 8080\n    debug = False\n    \n    # Database settings\n    db_host = 'localhost'\n    db_port = 5432\n    db_name = 'myapp'\n    max_connections = 10\n    connection_timeout = 30\n    \n    # API settings\n    api_version = 'v2'\n    rate_limit_per_minute = 60\n    \n    # Auth settings\n    token_expiry_seconds = 3600\n    max_login_attempts = 5\n    \n    @classmethod\n    def as_dict(cls):\n        return {\n            k: v for k, v in vars(cls).items()\n            if not k.startswith('_') and not callable(v)\n        }\n",
    "database.py": "\"\"\"Database connection pool and query execution.\"\"\"\n\nfrom config import AppConfig\n\n\nclass ConnectionPool:\n    \"\"\"Manages a pool of database connections.\"\"\"\n    \n    def __init__(self, host, port, db_name, pool_size=5, timeout=30):\n        \"\"\"Initialize the connection pool.\n        \n        Args:\n            host: Database server hostname.\n            port: Database server port.\n            db_name: Name of the database.\n            pool_size: Maximum number of concurrent connections.\n            timeout: Connection timeout in seconds.\n        \"\"\"\n        self.host = host\n        self.port = port\n        self.db_name = db_name\n        self.pool_size = pool_size\n        self.timeout = timeout\n        self._connections = []\n        self._initialized = False\n    \n    def initialize(self):\n        \"\"\"Create the initial connection pool.\"\"\"\n        self._connections = [\n            self._create_connection(i) for i in range(self.pool_size)\n        ]\n        self._initialized = True\n    \n    def _create_connection(self, conn_id):\n        \"\"\"Simulate creating a database connection.\"\"\"\n        return {\n            'id': conn_id,\n            'host': self.host,\n            'port': self.port,\n            'db': self.db_name,\n            'active': True\n        }\n    \n    def get_connection(self):\n        \"\"\"Get an available connection from the pool.\"\"\"\n        if not self._initialized:\n            raise RuntimeError(\"Pool not initialized\")\n        for conn in self._connections:\n            if conn['active']:\n                return conn\n        return None\n    \n    def get_pool_size(self):\n        \"\"\"Return the configured pool size.\"\"\"\n        return self.pool_size\n    \n    def get_status(self):\n        \"\"\"Return pool status information.\"\"\"\n        return {\n            'pool_size': self.pool_size,\n            'active': sum(1 for c in self._connections if c['active']),\n            'host': self.host,\n            'db': self.db_name,\n            'initialized': self._initialized\n        }\n\n\ndef create_pool():\n    \"\"\"Factory function to create a connection pool from config.\n    \n    BUG: This ignores AppConfig.max_connections and uses the default pool_size=5.\n    It should pass max_connections as the pool_size.\n    \"\"\"\n    pool = ConnectionPool(\n        host=AppConfig.db_host,\n        port=AppConfig.db_port,\n        db_name=AppConfig.db_name,\n        timeout=AppConfig.connection_timeout\n    )\n    return pool\n",
    "api.py": "\"\"\"API request handling and rate limiting.\"\"\"\n\nimport time\n\n\nclass RateLimiter:\n    \"\"\"Simple rate limiter for API requests.\"\"\"\n    \n    def __init__(self, max_requests_per_minute, max_concurrent=5):\n        \"\"\"Initialize the rate limiter.\n        \n        Args:\n            max_requests_per_minute: Maximum requests allowed per minute.\n            max_concurrent: Maximum concurrent connections to allow.\n        \"\"\"\n        self.max_requests = max_requests_per_minute\n        self.max_concurrent = max_concurrent\n        self._request_times = []\n    \n    def allow_request(self):\n        \"\"\"Check if a request should be allowed.\"\"\"\n        now = time.time()\n        self._request_times = [t for t in self._request_times if now - t < 60]\n        if len(self._request_times) >= self.max_requests:\n            return False\n        self._request_times.append(now)\n        return True\n    \n    def get_config(self):\n        \"\"\"Return rate limiter configuration.\"\"\"\n        return {\n            'max_requests_per_minute': self.max_requests,\n            'max_concurrent': self.max_concurrent\n        }\n\n\nclass ApiHandler:\n    \"\"\"Handles API requests using a database pool and rate limiter.\"\"\"\n    \n    def __init__(self, db_pool, rate_limiter, api_version='v1'):\n        \"\"\"Initialize the API handler.\n        \n        Args:\n            db_pool: A ConnectionPool instance.\n            rate_limiter: A RateLimiter instance.\n            api_version: API version string.\n        \"\"\"\n        self.db_pool = db_pool\n        self.rate_limiter = rate_limiter\n        self.api_version = api_version\n    \n    def handle_request(self, endpoint, params=None):\n        \"\"\"Handle an incoming API request.\"\"\"\n        if not self.rate_limiter.allow_request():\n            return {'error': 'Rate limit exceeded', 'status': 429}\n        \n        conn = self.db_pool.get_connection()\n        if conn is None:\n            return {'error': 'No available connections', 'status': 503}\n        \n        return {\n            'endpoint': endpoint,\n            'params': params or {},\n            'api_version': self.api_version,\n            'status': 200\n        }\n    \n    def get_status(self):\n        \"\"\"Return API handler status.\"\"\"\n        return {\n            'api_version': self.api_version,\n            'rate_limiter': self.rate_limiter.get_config(),\n            'db_pool': self.db_pool.get_status()\n        }\n\n\ndef create_api(db_pool, config):\n    \"\"\"Factory function to create an API handler.\n    \n    BUG: This creates the RateLimiter with hardcoded max_concurrent=5\n    instead of using config.max_connections. It also uses a hardcoded\n    api_version='v1' instead of config.api_version.\n    \"\"\"\n    limiter = RateLimiter(\n        max_requests_per_minute=config.rate_limit_per_minute,\n        max_concurrent=5\n    )\n    handler = ApiHandler(db_pool, limiter, api_version='v1')\n    return handler\n",
    "auth.py": "\"\"\"Authentication and session management.\"\"\"\n\nimport time\nfrom config import AppConfig\n\n\nclass SessionStore:\n    \"\"\"Manages user sessions.\"\"\"\n    \n    def __init__(self, db_pool, token_expiry=3600):\n        \"\"\"Initialize the session store.\n        \n        Args:\n            db_pool: A ConnectionPool to use for session persistence.\n            token_expiry: Token expiry time in seconds.\n        \"\"\"\n        self.db_pool = db_pool\n        self.token_expiry = token_expiry\n        self._sessions = {}\n    \n    def create_session(self, user_id):\n        \"\"\"Create a new session for a user.\"\"\"\n        token = f\"token_{user_id}_{int(time.time())}\"\n        self._sessions[token] = {\n            'user_id': user_id,\n            'created_at': time.time(),\n            'expires_at': time.time() + self.token_expiry\n        }\n        return token\n    \n    def validate_session(self, token):\n        \"\"\"Validate a session token.\"\"\"\n        session = self._sessions.get(token)\n        if session is None:\n            return False\n        if time.time() > session['expires_at']:\n            del self._sessions[token]\n            return False\n        return True\n    \n    def get_pool_info(self):\n        \"\"\"Return info about the db pool this session store uses.\"\"\"\n        return self.db_pool.get_status()\n\n\nclass AuthManager:\n    \"\"\"Manages authentication.\"\"\"\n    \n    def __init__(self, session_store, max_attempts=3):\n        \"\"\"Initialize the auth manager.\n        \n        Args:\n            session_store: A SessionStore instance.\n            max_attempts: Maximum login attempts before lockout.\n        \"\"\"\n        self.session_store = session_store\n        self.max_attempts = max_attempts\n        self._attempts = {}\n    \n    def login(self, user_id, password):\n        \"\"\"Attempt to log in a user.\"\"\"\n        attempts = self._attempts.get(user_id, 0)\n        if attempts >= self.max_attempts:\n            return {'error': 'Account locked', 'status': 403}\n        \n        # Simulated auth check\n        if password == f\"pass_{user_id}\":\n            self._attempts[user_id] = 0\n            token = self.session_store.create_session(user_id)\n            return {'token': token, 'status': 200}\n        else:\n            self._attempts[user_id] = attempts + 1\n            return {'error': 'Invalid credentials', 'status': 401}\n    \n    def get_status(self):\n        \"\"\"Return auth manager status.\"\"\"\n        return {\n            'max_attempts': self.max_attempts,\n            'session_pool': self.session_store.get_pool_info()\n        }\n\n\ndef create_auth(db_pool, config):\n    \"\"\"Factory function to create auth components.\n    \n    BUG: This creates its OWN ConnectionPool instead of using the shared\n    db_pool parameter. It also uses hardcoded max_attempts=3 instead of\n    config.max_login_attempts, and ignores config.token_expiry_seconds.\n    \"\"\"\n    from database import ConnectionPool\n    own_pool = ConnectionPool('localhost', 5432, 'myapp', pool_size=5)\n    own_pool.initialize()\n    session_store = SessionStore(own_pool, token_expiry=3600)\n    auth_mgr = AuthManager(session_store, max_attempts=3)\n    return auth_mgr\n",
    "main.py": "\"\"\"Main application entry point.\"\"\"\n\nfrom config import AppConfig\nfrom database import create_pool\nfrom api import create_api\nfrom auth import create_auth\n\n\nclass Application:\n    \"\"\"The main application that wires all components together.\"\"\"\n    \n    def __init__(self):\n        self.config = AppConfig\n        self.db_pool = None\n        self.api_handler = None\n        self.auth_manager = None\n        self._running = False\n    \n    def initialize(self):\n        \"\"\"Initialize all application components.\n        \n        BUG: Does not pass config to create_auth properly.\n        The db_pool is created but not passed to auth.\n        \"\"\"\n        self.db_pool = create_pool()\n        self.db_pool.initialize()\n        \n        self.api_handler = create_api(self.db_pool, self.config)\n        self.auth_manager = create_auth(None, self.config)\n        \n        self._running = True\n    \n    def get_status(self):\n        \"\"\"Return full application status.\"\"\"\n        if not self._running:\n            return {'status': 'not running'}\n        return {\n            'status': 'running',\n            'config': self.config.as_dict(),\n            'db_pool': self.db_pool.get_status(),\n            'api': self.api_handler.get_status(),\n            'auth': self.auth_manager.get_status()\n        }\n\n\ndef main():\n    app = Application()\n    app.initialize()\n    status = app.get_status()\n    print(f\"App status: {status['status']}\")\n    print(f\"DB pool size: {status['db_pool']['pool_size']}\")\n    print(f\"API version: {status['api']['api_version']}\")\n    print(f\"Rate limiter concurrent: {status['api']['rate_limiter']['max_concurrent']}\")\n    print(f\"Auth max attempts: {status['auth']['max_attempts']}\")\n    print(f\"Auth session pool size: {status['auth']['session_pool']['pool_size']}\")\n\n\nif __name__ == '__main__':\n    main()\n",
    "test_config.py": "\"\"\"Test that configuration is propagated correctly through all components.\"\"\"\nimport sys\nimport subprocess\n\nerrors = []\n\n# Run main.py and capture output\nresult = subprocess.run([sys.executable, 'main.py'], capture_output=True, text=True, timeout=10)\n\nif result.returncode != 0:\n    print(f\"FAIL: main.py crashed: {result.stderr}\")\n    sys.exit(1)\n\noutput = result.stdout.strip()\nlines = output.split('\\n')\n\nexpected = {\n    'App status: running': None,\n    'DB pool size: 10': 'Database pool should use max_connections=10 from config',\n    'API version: v2': 'API should use api_version from config',\n    'Rate limiter concurrent: 10': 'Rate limiter max_concurrent should use max_connections from config',\n    'Auth max attempts: 5': 'Auth should use max_login_attempts=5 from config',\n    'Auth session pool size: 10': 'Auth should use the SHARED db_pool (size=10), not its own pool',\n}\n\nfor expected_line, reason in expected.items():\n    found = False\n    for line in lines:\n        if line.strip() == expected_line:\n            found = True\n            break\n    if not found:\n        msg = f\"Expected '{expected_line}'\"\n        if reason:\n            msg += f\" ({reason})\"\n        msg += f\" but got output:\\n{output}\"\n        errors.append(msg)\n\n# Also do a programmatic check by importing and testing directly\ntry:\n    from config import AppConfig\n    from database import create_pool\n    from api import create_api\n    from auth import create_auth\n    from main import Application\n    \n    app = Application()\n    app.initialize()\n    \n    # Check database pool\n    if app.db_pool.get_pool_size() != 10:\n        errors.append(f\"DB pool size is {app.db_pool.get_pool_size()}, expected 10\")\n    \n    # Check API handler\n    api_status = app.api_handler.get_status()\n    if api_status['api_version'] != 'v2':\n        errors.append(f\"API version is {api_status['api_version']}, expected v2\")\n    if api_status['rate_limiter']['max_concurrent'] != 10:\n        errors.append(f\"Rate limiter max_concurrent is {api_status['rate_limiter']['max_concurrent']}, expected 10\")\n    \n    # Check auth - must use same pool\n    auth_status = app.auth_manager.get_status()\n    if auth_status['max_attempts'] != 5:\n        errors.append(f\"Auth max_attempts is {auth_status['max_attempts']}, expected 5\")\n    if auth_status['session_pool']['pool_size'] != 10:\n        errors.append(f\"Auth session pool size is {auth_status['session_pool']['pool_size']}, expected 10\")\n    \n    # Check that auth session store uses the SAME pool object as the app\n    auth_pool_status = app.auth_manager.session_store.get_pool_info()\n    app_pool_status = app.db_pool.get_status()\n    if auth_pool_status['pool_size'] != app_pool_status['pool_size']:\n        errors.append(\"Auth is NOT sharing the application's database pool\")\n\nexcept Exception as e:\n    errors.append(f\"Import/runtime error: {type(e).__name__}: {e}\")\n\nif errors:\n    print(f\"FAILED with {len(errors)} error(s):\")\n    for e in errors:\n        print(f\"  - {e}\")\n    sys.exit(1)\nelse:\n    print(\"ALL CHECKS PASSED\")\n    print(\"  - max_connections propagated to database pool\")\n    print(\"  - max_connections propagated to API rate limiter\")\n    print(\"  - api_version propagated to API handler\")\n    print(\"  - Auth uses shared database pool\")\n    print(\"  - max_login_attempts propagated to auth\")\n    print(\"  - token_expiry_seconds propagated to session store\")\n    sys.exit(0)\n"
  },
  "verify": "cd $BENCH_WORK_DIR && python3 test_config.py",
  "timeout": 360000,
  "tags": ["long-context", "multi-file", "configuration", "python", "tracing"]
}