Skip to content

Dead links enter pipeline without liveness verification — full eval + PDF generated for expired postings #835

Description

@PaulaBarszcz

Summary

The Level 3 scan (WebSearch) appends links to pipeline.md as - [ ] pending entries with no liveness check. Downstream modes (oferta, auto-pipeline, pdf) then process these entries in full — running all A–F evaluation blocks, writing reports, and generating tailored CVs — before anyone discovers the posting no longer exists.

Steps to Reproduce

Environment: Claude Code, career-ops v1.x, Linux/WSL2

  1. Run /career-ops scan — allow Level 3 (WebSearch) to execute and append results to data/pipeline.md.
  2. Observe that all Level 3 results are written as - [ ] (pending) entries with no liveness verification.
  3. Pick any pending entry from the Level 3 results and run /career-ops oferta (or paste the URL directly to trigger auto-pipeline).
  4. Allow the full evaluation to complete — blocks A through G, report written to reports/, TSV written to batch/tracker-additions/.
  5. If score is ≥ 4.0, run /career-ops pdf to generate a tailored CV.
  6. Only now navigate to the original URL manually.

Expected Behavior

Step 3 begins with a liveness check. If the URL returns 404 or is otherwise inactive, the system stops and marks the entry dead before spending any tokens on evaluation.

Actual Behavior

The system evaluates the offer in full and generates a PDF CV. The dead link is only discovered when the user tries to open the application form manually.

Concrete Example

  • Offer: Printify — Senior Front-end Software Engineer (Angular)
  • URL: jobs.lever.co/printify/fe0324d9-...
  • Score: 4.3/5 — highest-rated offer of the session
  • What happened: Full A–F evaluation completed, report written to reports/008-printify-2026-06-08.md, tailored PDF CV generated at output/cv-paula-barszcz-printify-2026-06-08.pdf
  • Reality: URL returns 404. Company merged with Printful → rebranded as FYUL months prior. No open Angular roles exist. Entry manually updated to Discarded after the fact.

Session total: 17 out of ~25 Level 3 results were dead links. One full evaluation + tailored PDF was generated on phantom data.

Root Cause

check-liveness.mjs exists and works correctly, but is not called at any point in the scan → pipeline → oferta flow. Level 3 entries are indistinguishable from verified entries in pipeline.md.

Suggested Fixes

Code:

  • After any Level 3 scan, auto-run check-liveness.mjs on all discovered links before writing them to pipeline.md. Dead links should be written as - [x] ~~Company | Role~~ — oferta nieaktywna immediately.
  • In pipeline mode, add a liveness pre-check loop: verify each - [ ] URL before dispatching to the evaluator.
  • In oferta / auto-pipeline, verify the URL is alive as step 0 before any LLM work begins.

Documentation:

  • Add a warning to the README under the Level 3 scan section: "Level 3 results are unverified. Run liveness verification before evaluating or generating CVs."
  • Add a rule to CLAUDE.md: "NEVER generate a report or CV for an offer whose URL has not been verified active in this session."

Pipeline format:

  • Consider a third state: - [?] or ⚠️ unverified tag for Level 3 entries, distinct from - [ ] (verified pending) and - [x] (done/dead). Makes backlog confidence visible at a glance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions