fix(F15-F16): stop losing dates, contacts and whole daily reports

F15 - dates and metadata kept their meaning
- The Taleo parser stored an application DEADLINE in `posted`, so a role closing
  on 30 September looked as though it had been published then - backwards for a
  freshness signal. It now populates `deadline`, and `posted` stays empty
  because that board genuinely publishes none.
- The Prospective adapter read unit, Lohnklasse and a named contact, folded them
  into `description` for scoring, and `_process_company` then discarded
  `description` - losing exactly the fields that decide level, pay and whether a
  cold submit is necessary. They are now carried as fields through to the report
  and the JSON dump, alongside `date_provenance`.
- Named contacts now appear in report rows. Channel is the rationed variable
  since 2026-09-05, so a published, reachable name is the difference between a
  cold submit being a choice and being the only option.

F16 - writes stopped destroying delivered work
- Every run of a day wrote `<date>.md`/`.json`, so a restricted run replaced the
  full daily report. This is not hypothetical: it happened twice in this session
  and both times the 37-company run had to be repeated by hand. Restricted runs
  now write `<date>.only-kdocy.md` and say so.
- `save_seen()` ran in a `finally:` BEFORE the report was written. A failed
  report write therefore left roles marked seen, so a `--new-only` retry would
  hide precisely the hits that were never delivered. Seen-state is now committed
  only after report and dump are on disk - and never by a restricted run, which
  did not look at the whole board.
- Atomic writes used a fixed `.tmp` name; two writers could share it and
  os.replace the wrong content into place. Unique temp names now.

34/34 tests pass; validated on a live 37-company run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
This commit is contained in:
dennisthiessenandClaude Opus 5 committed 2026-09-11 20:19:57 +02:00
1 parent ce8619b8e3
commit c7e8d4e058
2 files changed
+79 -15

No files matched your search

+12 -6
View File
@@ -6,12 +6,13 @@ Do not rewrite submitted application archives or invent missing evidence.
## Resume point
F01–F14 complete. **Next: F15** — typed dates and retained contact/compensation metadata
(`job_scout/scout.py`: the Taleo parser writes a deadline into `posted`, and the Prospective
path's unit/Lohnklasse/contact are folded into `description`, which `_process_company` discards).
F01–F16 complete. **Next: F17** — reproducible builds and safe historical-archive
classification. Start from the 13 older packages listed in the F05/F06 verification notes
below; they carry genuine findings under today's rules and must NOT be silently rewritten.
F17 also needs the 45-document LaTeX sweep, which has not been re-run this session.
Read this file and inspect `git log`/`git diff` before resuming; do not repeat completed work.
Checkpoints: `afdef7e` (F01+F02) · `fc5f3e4` (F03–F06) · `ce5b7f5` (F07) · `3519b2f` (F08–F10) · `afd8174` (F11–F13) · plus F14.
Checkpoints: `afdef7e` (F01+F02) · `fc5f3e4` (F03–F06) · `ce5b7f5` (F07) · `3519b2f` (F08–F10) · `afd8174` (F11–F13) · `ce8619b` (F14) · plus F15–F16.
## User rulings — 2026-09-11
@@ -40,8 +41,8 @@ Checkpoints: `afdef7e` (F01+F02) · `fc5f3e4` (F03–F06) · `ce5b7f5` (F07) ·
| F12 | DONE | Whole-word place matching (Bernau no longer reads as Bern); ~25 Swiss towns incl. Thun and Zimmerwald; Danish cities; pan-regional scope no longer beats an explicit onsite/one-country restriction. All 14 review cases correct |
| F13 | DONE | Identifying query params kept in the key; read and write paths share `lookup_decision`. **Live run recovered 7 reposted RUAG decisions**, labelled RELATED rather than applied as identical |
| F14 | DONE | Buckets renamed to keyword relevance with an explicit 'NOT a fit judgement'; German titles and platform/DevOps vocabulary added. Kdo Cy *ICT-System Engineer (DevSecOps/Platform Automation)* went 0→10; *Senior Dateningenieur* 1→3, level with its English twin |
| F15 | TODO | Typed dates and retained contact/compensation metadata |
| F16 | TODO | Run-scoped reports, transactional persistence and scan coverage |
| F15 | DONE | Taleo deadline moved out of `posted` (a closing date was making roles look freshly published); `unit`, `compensation`, `contact` and `date_provenance` carried as fields through to the report and JSON. Named contacts now surface — directly serving the channel rule |
| F16 | DONE | Restricted runs write `<date>.only-x.md` and leave the daily report intact; seen-state committed only after the report is on disk, and never by a restricted run; unique temp names for atomic writes |
| F17 | TODO | Reproducible new builds and safe historical archive classification |
| F18 | TODO | Evidence earlier on page one; rendered skills budget |
| F19 | TODO | Education layout, phrasing guidance, reproducible word counts |
@@ -90,6 +91,11 @@ mid-remediation — it would destroy the ability to attribute a regression to a
- F14 note: the score floor on RUAG/SBB/BKW/PostFinance/Kdo Cy was a workaround for missing German
vocabulary. The vocabulary is now the fix; the floors can probably be reduced later, but they were
left in place to keep this diff attributable.
- F15/F16 validated on a live 37-company run: named contacts with phone numbers now appear in
report rows, NATO/Taleo closing dates render as Bewerbungsfrist rather than Posted, and
`--only=kdocy` wrote `2026-09-11.only-kdocy.md` while leaving the full report untouched.
- F16 context: the daily-report clobber is not hypothetical. It happened twice in this session
(2026-09-10 and 09-11) and both times the full run had to be repeated by hand.
- Not re-run this session: the 45-document LaTeX build sweep and the visual sampling.
## Completion rules