Skip to content

feat: scheduled deadline watcher for existing listings (#54)#65

Merged
Jose-Gael-Cruz-Lopez merged 3 commits into
mainfrom
feat/deadline-watcher
Jul 7, 2026
Merged

feat: scheduled deadline watcher for existing listings (#54)#65
Jose-Gael-Cruz-Lopez merged 3 commits into
mainfrom
feat/deadline-watcher

Conversation

@Jose-Gael-Cruz-Lopez

Copy link
Copy Markdown
Collaborator

Closes #54. Top of the stack (base chore/tech-debt-cleanup). Merge #60#61#62#63#64 → this.

A weekly job (also workflow_dispatch) that backfills missing deadlines as reviewable proposals — it never edits listings.json and never pushes.

How it works

  1. Load active + visible listings with no deadline.
  2. Re-fetch each listing's already-stored URL via auto_extract's SSRF/TLS-hardened fetch.
  3. Ask the model for a hacker-facing application/registration deadline with a quoted evidence snippet.
  4. _accept() enforces the safety rules; write a markdown report + has_content output.
  5. Workflow opens an issue from the report for maintainer review.

Safety rules (from the issue) — all enforced

  • ✅ Only participant application/registration deadlines — not event dates, judge/mentor/sponsor deadlines, or prior-cycle dates (prompt + deadline_type filter)
  • ✅ Only high-confidence results with a quoted evidence snippet and a valid date
  • Never overwrites deadlines / never pushes / never auto-merges — permissions: contents:read, issues:write only
  • ✅ Reviewable issue output, not a direct change

Verification

  • ✅ scripts compile; 19 Python unittests pass (incl. 5 for the _accept safety rules)
  • ✅ a no-key run finds 11 candidates, warns, and exits has_content=false with no network calls
  • ✅ workflow YAML valid; actions SHA-pinned; deadline_proposals.md gitignored

🤖 Generated with Claude Code

Jose-Gael-Cruz-Lopez and others added 3 commits July 7, 2026 09:39
Closes #54.

Adds a weekly (workflow_dispatch too) job that backfills MISSING deadlines as
reviewable proposals — it never edits listings.json or pushes.

- deadline_watcher.py: loads active + visible listings with no `deadline`,
  re-fetches each listing's stored URL via auto_extract's SSRF/TLS-hardened
  fetch, and asks the model for a hacker-facing application/registration
  deadline. Safety rules enforced in _accept(): only application/registration
  types, only high confidence, requires a quoted evidence snippet and a valid
  date; event dates, judge/mentor/sponsor deadlines, and prior-cycle dates are
  excluded by the prompt + filters. Writes a markdown report and a has_content
  output; degrades gracefully (no candidates / no OpenAI key -> nothing).
- deadline_watch.yml: schedule + manual, permissions contents:read + issues:
  write (no push), SHA-pinned actions, opens an issue from the report for
  maintainer review. Never auto-merges.
- Unit tests for the _accept safety rules; deadline_proposals.md gitignored.

Verified: scripts compile; 19 Python unittests pass; a no-key run finds
candidates, warns, and exits with has_content=false (no network); workflow
YAML valid.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…vidence

Review fixes for the scheduled deadline watcher:

- Idempotent issue creation: the workflow opened a brand-new issue every
  weekly run, so unaddressed proposals piled up as duplicates. Now it reuses
  the existing open `deadline-proposal` issue (edit + comment) and only
  creates one when none is open. Added a `concurrency` group so an overlapping
  scheduled + manual run can't double-open.
- Enforce the "no prior-cycle dates" rule in code, not just the prompt:
  _accept() now rejects any parsed deadline before today (PST). `today` is an
  injectable param so the check is deterministic in tests; main() computes it
  once per run.
- Sanitize the model/page-derived evidence (and company/title) through
  util.sanitize_field before embedding in the issue markdown, so a multi-line
  or markup-bearing quote can't break the report or smuggle mentions/links.
- Correct the cron comment (15:00 UTC is 07:00 PST / 08:00 PDT, not "~7am PT").

Tests: pinned the acceptance test's reference date (was a latent time-bomb
once 2026-08-01 passed) and added a past-date rejection test. 20/20 pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Carry the lockfile fix onto this branch so its Web CI passes at `npm ci`
instead of failing on the inherited out-of-sync lockfile. Regenerated with
npm@11.16.0 (the CI runner version); verified `npm ci` and build pass and the
scripts unittest suite is 20/20.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Jose-Gael-Cruz-Lopez Jose-Gael-Cruz-Lopez changed the base branch from chore/tech-debt-cleanup to main July 7, 2026 15:36
@Jose-Gael-Cruz-Lopez Jose-Gael-Cruz-Lopez merged commit d691f3f into main Jul 7, 2026
2 checks passed
@Jose-Gael-Cruz-Lopez Jose-Gael-Cruz-Lopez deleted the feat/deadline-watcher branch July 7, 2026 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement] Scheduled deadline watcher for existing listings

1 participant