mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-11-02 13:12:50 +00:00
fix(specs): qualify seen_jobs.json as job_scraper/seen_jobs.json in /rank, /notion-sync and /upskill (#617)
Follow-up to #608 at the maintainer's invitation. /scrape already names the full path; the three readers still used the bare filename, which an agent can resolve to the repo root (outside the **/job_scraper/seen_jobs.json ignore rule). The guard test now covers all four specs; test_notion_sync_command pins the qualified phrase. 04-job-evaluation.md is left alone on purpose: forks personalize it, and a one-word fix there would force a framework_version bump.
This commit is contained in:
1 parent
12b757189a
commit
24db6b3b59
6 files changed
+43
-25
No files matched your search
@@ -49,7 +49,7 @@ class NotionSyncCommandSpec(unittest.TestCase):
|
||||
# lookup of `role` on the entry, which never matches, so one job became
|
||||
# two Notion rows with different Keys. The join is role-vs-title.
|
||||
text = COMMAND.read_text(encoding="utf-8")
|
||||
line = next(l for l in text.splitlines() if "matched to `seen_jobs.json` entries" in l)
|
||||
line = next(l for l in text.splitlines() if "matched to `job_scraper/seen_jobs.json` entries" in l)
|
||||
self.assertIn("company + title", line)
|
||||
self.assertIn("`title`", line)
|
||||
self.assertIn("`role`", line)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Every seen_jobs.json reference in /scrape's spec names the full path.
|
||||
"""Every seen_jobs.json reference in the scrape/rank/notion-sync/upskill specs names the full path.
|
||||
|
||||
Step 0 reads `job_scraper/seen_jobs.json`, but later steps (notably Step 4,
|
||||
where the file is written) used the bare filename. An agent following Step 4
|
||||
@@ -12,18 +12,28 @@ import re
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
SKILL = Path(__file__).resolve().parent.parent / ".claude" / "skills" / "job-scraper" / "SKILL.md"
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
# /scrape writes the file; the others read it. A bare name in a reader spec is the
|
||||
# same trap: an agent asked to "read seen_jobs.json" looks in the repo root first.
|
||||
SPECS = [
|
||||
ROOT / ".claude" / "skills" / "job-scraper" / "SKILL.md",
|
||||
ROOT / ".claude" / "commands" / "rank.md",
|
||||
ROOT / ".claude" / "commands" / "notion-sync.md",
|
||||
ROOT / ".claude" / "skills" / "upskill" / "SKILL.md",
|
||||
]
|
||||
BARE = re.compile(r"(?<!job_scraper/)(?<![\w/.-])seen_jobs\.json")
|
||||
|
||||
|
||||
class ScrapeSeenJobsPathSpec(unittest.TestCase):
|
||||
def test_no_bare_seen_jobs_reference(self):
|
||||
offenders = [
|
||||
f"line {i}: {line.strip()[:90]}"
|
||||
for i, line in enumerate(SKILL.read_text(encoding="utf-8").splitlines(), 1)
|
||||
if BARE.search(line)
|
||||
]
|
||||
self.assertEqual(offenders, [], "use job_scraper/seen_jobs.json everywhere in the spec")
|
||||
for spec in SPECS:
|
||||
with self.subTest(spec=spec.relative_to(ROOT).as_posix()):
|
||||
offenders = [
|
||||
f"line {i}: {line.strip()[:90]}"
|
||||
for i, line in enumerate(spec.read_text(encoding="utf-8").splitlines(), 1)
|
||||
if BARE.search(line)
|
||||
]
|
||||
self.assertEqual(offenders, [], "use job_scraper/seen_jobs.json everywhere in the spec")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in new issue
Block a user