Repository navigation
Repo hygiene: license, CI, pinned deps, complete env example, no personal data in source - #12
Merged
Merged
Conversation
…onal data in source The code was fine; the packaging around it read as a prototype. This is the first of four cleanup stages (hygiene, package layout, test consolidation, docs split) ahead of scaling Palmer. - LICENSE (all rights reserved, source available for reading) and a README License section. The repo is public and Palmer is a product. - .github/workflows/ci.yml runs ruff and the full suite on every push and PR. The suite is offline; a few modules read their API key at import time, so the workflow sets placeholder values rather than secrets. - requirements.txt pinned to the versions the venv actually runs, and `requests` added — it is imported directly by three modules and only resolved through a transitive dependency. requirements-dev.txt adds pytest and ruff. - .env.example lists all 14 variables the code reads. It listed five, and TAVILY_API_KEY was not one of them, so a fresh clone failed on import. Verified: the suite passes in a clean environment holding only these placeholders. - README: price watches run twice daily on a cron and alert on any move over a flat $2 in either direction, not "every 6h" on a "15% drop" — the code changed twice and the prose did not. Same stale claim fixed in shopping.py's docstrings. Added a Development section and the CI badge. - Personal data out of the source tree: the NWS User-Agent contact is now PALMER_CONTACT_EMAIL; guards.py and two test files no longer carry real users' names, neighbourhoods or verbatim texts; the one non-555 phone number in the suite is now a reserved one. The repetition fixture keeps a two-word city because opening_shape compares three meaningful words. - Dead code removed, each verified to have no caller: artifacts.publish, db.get_all_phones, home.home_url, cards.AMBER, shows.resolve_show (the follow_show dispatch uses find_shows) and its two tests. wxaudit gets a __main__ so `python wxaudit.py` prints the scoreboard. send_morning.py gets a __main__ guard — importing it sent real SMS. - Five comments still pointed at the deleted alerts.py; reworded. - ruff.toml selects E/F/W and deliberately ignores line length, imports below load_dotenv()/init_db(), and the `conn = _conn(); cur = ...` house style, so the linter enforces mistakes rather than taste. Kept on purpose: shopping._daily_ok mirrors watches._daily_ok, but shopping sits below agent in the import graph and watches above it, so sharing one definition would invert the dependency direction. Flagged, not fixed: db.get_user_flight_watches has no caller because list_watches never lists flight watches — a user can add one and never see it again. That is a product gap for its own PR. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018QpUhnYC3U7KxF8QCeenfQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First of four cleanup stages ahead of scaling Palmer (hygiene → package layout → test consolidation → docs split). No behaviour changes.
.github/workflows/ci.ymlrunsruff check .andpytest -qon every push and PR. No secrets needed: the suite is offline and the workflow sets placeholder values for the keys a few modules read at import time.requirements.txtto the versions the venv actually runs, plusrequests, which three modules import directly and which only resolved transitively. Newrequirements-dev.txt..env.exampleis complete — all 14 variables the code reads, with comments. It listed 5, missingTAVILY_API_KEY, so a fresh clone failed on import. Verified the suite passes in a clean env holding only these placeholders.shopping.pydocstrings. Added Development section, License section, CI badge.PALMER_CONTACT_EMAIL;guards.py,test_repetition.py,test_profile_freshness.pyno longer carry real users' names, neighbourhoods or verbatim texts; the one non-555 phone in the suite is now reserved.artifacts.publish,db.get_all_phones,home.home_url,cards.AMBER,shows.resolve_show+ its two tests.wxauditgets a__main__;send_morning.pygets a__main__guard (importing it sent real SMS).alerts.py; reworded.ruff.tomlselects E/F/W, ignoring line length, imports-after-load_dotenv(), and theconn = _conn(); cur = ...house style.Kept on purpose:
shopping._daily_okmirrorswatches._daily_ok, butshoppingsits belowagentin the import graph andwatchesabove it; sharing one definition would invert the dependency direction.Flagged, not fixed:
db.get_user_flight_watcheshas no caller becauselist_watchesnever lists flight watches. A user can add one and never see it again. Product gap for its own PR.Test plan
ruff check .cleanpytest -q— 1,403 passed (1,405 on main minus the tworesolve_showtests).env.exampleplaceholdersgrepfor the removed names, email and phone number: no hitsPALMER_NO_SCHEDULER=1 python -c "import main; import send_morning"imports without sending🤖 Generated with Claude Code
https://claude.ai/code/session_018QpUhnYC3U7KxF8QCeenfQ