feat(rank): flag stale postings from the stored posted_date (#390) (#406)

Step 3 gains rule 7: a posting whose stored posted_date is more than 30
days old at rank time carries a visible staleness marker with its age
spelled out alongside the score - FLAG treatment like location and
language, never an exclusion. No posted_date or null means no flag and no
guess (never inferred from first_seen), and rule 6's defensive-parse rule
applies wherever the stored value is compared. Age is re-derived each run
and never persisted. Four new spec pins in test_rank_command.py, each
verified to fail against the rule-less spec.
This commit is contained in:
Ayobami Adegoke
2026-09-02 20:02:38 +02:00
committed by GitHub
parent 9833a5dcb7
commit 284dc4c2d0
3 changed files with 96 additions and 0 deletions
+65
View File
@@ -419,5 +419,70 @@ class RankCommandSpec(unittest.TestCase):
self.assertEqual(result.returncode, 0, f"lint_skills.py failed:\n{result.stdout}{result.stderr}")
class PostedDateStalenessSpec(unittest.TestCase):
"""Step 3 must consume the posted_date #391 persists.
The field exists because a 27-month-old posting ranked Strong Fit at
position 1 of 133 (#390): the scoring agent noticed the age and wrote it
into prose nothing reads. Persistence alone changes nothing - these pin
that /rank actually derives a signal from the stored date, and that the
signal keeps the schema's own boundary rules (flag never veto, no
inference for absent values, rule 6's defensive parse).
"""
def setUp(self):
self.step3 = _sections(COMMAND.read_text(encoding="utf-8")).get(
"Step 3: Aggregate and Rank", ""
)
self.assertTrue(self.step3, "Step 3 section missing from rank.md")
# The spec hard-wraps its prose; assertions match against collapsed
# whitespace so a rewrap never fails a pin the text still honors.
self.flat = " ".join(self.step3.split())
def test_step3_consumes_posted_date(self):
self.assertIn(
"`posted_date`",
self.step3,
"Step 3 never reads the posted_date /scrape persists, so a posting's "
"age is stored but still invisible at rank time - the exact #390 gap",
)
self.assertIn(
"",
self.step3.split("`posted_date`", 1)[1][:600],
"the staleness rule must surface age as a visible ⚠ marker, like the "
"location and language FLAG treatments",
)
def test_staleness_is_a_flag_never_a_veto(self):
self.assertRegex(
self.flat,
r"[Aa]ge is a signal, never a veto",
"staleness must keep FLAG semantics - the #390 posting was 27 months "
"old AND still live, so excluding on age would bury real openings",
)
def test_staleness_never_inferred_for_absent_values(self):
self.assertRegex(
self.flat,
r"no `posted_date`.*no flag and no guess",
"entries predating the field must get no staleness signal - inferring "
"age from first_seen would flag jobs on a date nobody posted",
)
self.assertIn(
"`first_seen`",
self.step3,
"the rule must name first_seen as the forbidden inference source",
)
def test_staleness_parses_posted_date_defensively(self):
self.assertRegex(
self.flat,
r"defensive-parse rule applies wherever a stored `posted_date` is compared",
"posted_date comparisons must carry rule 6's defensive-parse rule - the "
"contract test pins the field's presence, not its format, and portals "
"have shipped free-text shapes into stored date fields before",
)
if __name__ == "__main__":
unittest.main()