Problem
The Settings class in config.py defaults slack_signing_secret and slack_bot_token to empty strings (""). This means a Settings object can be fully constructed in a valid state with no Slack credentials. create_app() will build a Slack App with empty tokens, which only fails at the first API call deep inside poll_once's notification path, surfacing as a SlackApiError that looks identical to a transient Slack outage. While DATABASE_URL has an explicit empty-check with sys.exit(1) in __main__.py:92-94, no equivalent guard exists for Slack credentials.
Acceptance Criteria
Bugfix bundle — dead config / stale DB module comment (paperscout_bugfix_bundle_27f91caa.plan.md §5)
Implementation Notes
This finding overlaps with item 1 (Opaque failure path). If item 1 is implemented first, this may be partially addressed. The key decision is whether paperscout should support running without Slack (e.g., for development/testing). If yes, use a slack_enabled flag; if no, use a validator that rejects empty tokens at startup. The pydantic-settings @model_validator(mode='after') hook is the right place.
References
- Eval finding: Test 7 (Misuse Resistance) + Test 9 (Defaults Quality), cluster Correctness of Use
- Related files:
src/paperscout/config.py, src/paperscout/__main__.py, .env.example
Problem
The
Settingsclass inconfig.pydefaultsslack_signing_secretandslack_bot_tokento empty strings (""). This means aSettingsobject can be fully constructed in a valid state with no Slack credentials.create_app()will build a SlackAppwith empty tokens, which only fails at the first API call deep insidepoll_once's notification path, surfacing as aSlackApiErrorthat looks identical to a transient Slack outage. WhileDATABASE_URLhas an explicit empty-check withsys.exit(1)in__main__.py:92-94, no equivalent guard exists for Slack credentials.Acceptance Criteria
@model_validator(or@field_validator) onSettingsthat raisesValidationErrorwhenslack_signing_secretorslack_bot_tokenare empty strings, with a clear error messageslack_enabled: boolcomputed field and guard all Slack API calls behind itSettingswith empty Slack tokens either raises or correctly setsslack_enabled=False.env.examplewith commentsBugfix bundle — dead config / stale DB module comment (paperscout_bugfix_bundle_27f91caa.plan.md §5)
enable_bulk_openstdfromSettingsinconfig.py(grep confirms it is unreferenced;extra="ignore"still allows stray env vars).poolindb.py: the pool is passed explicitly through constructors;paperscout.db.poolis not assigned by__main__(prefer comment-only fix over introducing a global unless you standardize on one pattern).Implementation Notes
This finding overlaps with item 1 (Opaque failure path). If item 1 is implemented first, this may be partially addressed. The key decision is whether paperscout should support running without Slack (e.g., for development/testing). If yes, use a
slack_enabledflag; if no, use a validator that rejects empty tokens at startup. Thepydantic-settings@model_validator(mode='after')hook is the right place.References
src/paperscout/config.py,src/paperscout/__main__.py,.env.example