FHS bot: relative-date awareness for episode-time scoping (e.g. "last quarter", "past three months")
recycUNBRSIV9F085
- Project
- FHS Podcast Agent
- Build Model
- sonnet
- Review Model
- opus
- Runtime Model
- sonnet
- Rounds
- 2
- Work Item
- Open in Airtable
- Output
- Open PR
Time by Role
Builder705.8s(84.8%)
Reviewer126.9s(15.2%)
Total: 832.6s
Feature Waterfall (3 features)
F1 Full ticket: relative-date awareness (consolidated)
0s - APPROVE
F2 Add upload_date_range filter to hybrid_search
0s - Blocked
F3 Wire resolver and date prompt into generate_response
0s - Blocked
Builder
Reviewer
Runtime
Agent Dispatches
Orchestrator3
Builder1
Reviewer2
Runtime1
Tokens by Role
Builder129.8k(55.2%)
Reviewer105.3k(44.8%)
Total: 235.1k tokens
Token breakdown by type pending; only aggregate usage is available.
Code
+1,007
Lines Added
-3
Lines Removed
9
Files Changed
Source vs Test
Source439(43.6%)Test568(56.4%)
Coverage
Coverage: not reported
Features
Validation Contract
# Validation Contract — recg2Ubqj6K4e06bX FHS bot: relative-date awareness for episode-time scoping Generated from: https://airtable.com/appPNaMjaSYbU0qN2/tblAjO4JA5EcXkMjA/recg2Ubqj6K4e06bX Generated at: 2026-05-28T14:08:00Z ## Assertions 1. [A] src/retrieval/date_window.py exists and exports resolve_relative_date_phrase(question, now) -> tuple[date, date] | None plus the internal helpers _parse_quarter_phrase, _parse_past_n_units_phrase, _parse_this_last_unit_phrase, _parse_since_month_phrase (verifiable by file presence + grep). 2. [A] resolve_relative_date_phrase correctly resolves English relative-date phrases — this month, last month, this quarter, last quarter (including Q1→prior-year-Q4 rollover), past N days, past N weeks, past N months (calendar arithmetic), since <Month>, in <Year> — to concrete (start_date, end_date) windows, and returns None for queries with no relative-date phrase or ambiguous terms. Verified by tests/retrieval/test_date_window.py tests 1–10. 3. [A] resolve_relative_date_phrase correctly resolves Hebrew relative-date phrases — ברבעון האחרון, בשלושת החודשים האחרונים, בחודש האחרון, בחודש שעבר — to the same windows as their English equivalents. Verified by tests/retrieval/test_date_window.py tests 11–13. 4. [A] hybrid_search(...) in src/retrieval/search_engine.py accepts an optional upload_date_range parameter; when set, the OData filter string includes `upload_date ge '<start>' and upload_date le '<end>'`. 5. [A] generate_response in src/retrieval/response_generator.py calls resolve_relative_date_phrase(question, datetime.now(UTC)) once per turn, forwards a non-None resolved range as upload_date_range to hybrid_search, and prepends a RESOLVED DATE RANGE line to the user prompt only when applicable. 6. [A] The system prompt sent to Claude starts with `Today's date is <YYYY-MM-DD>.` (interpolated at call time via a _build_system_prompt(today) helper) and contains rule #10 about using RESOLVED DATE RANGE without inventing dates. 7. [A] When the date-filtered search returns zero chunks, the user-facing answer is a window-aware no-results message that mentions the filtered window (not the generic message, and not a silent re-search without the filter). 8. [A] The existing _is_latest_episode_content_question fast-path keeps firing first; the new date-range resolution does not override it. 9. [A] Full `uv run pytest tests/ -q` suite is green: all 18 new unit + integration tests pass and no existing test regresses. 10. [A] PR opened against master with conventional commit prefix `feat(retrieval):` referencing the ticket title. ## Coverage Rules - [A] assertions MUST have a corresponding failing test (or grep/file check for markdown-only repos) in the dev's first commit. - [R] assertions MUST be verified by the runtime validator against a running instance of the app. - The reviewer MUST reject any first commit that has no [A] verification for each [A] assertion. - Tag [A] when: verifiable by reading files, running unit/integration tests, or static analysis. - Tag [R] when: requires spawning a server, opening a browser, or running a CLI against a live process.
Event Timeline (7 events)
| # | Role | Event Type | Summary | Verdict | Time |
|---|---|---|---|---|---|
| 1 | Orchestrator | contract_generated | Validation contract approved (10 [A] / 0 [R] assertions) | 5/28/2026, 2:36:30 PM | |
| 2 | Builder | dispatch_started | Dev subagent completed F1 (consolidated full ticket) on branch mission/run_recg2Ubqj6K4e06bX_2026-05-28. 3 commits, 22 new tests, 138 passed / 1 pre-existing fail. | 5/28/2026, 2:55:00 PM | |
| 3 | Reviewer | validator_verdict | REQUEST_CHANGES — 2 mechanical fixes: (1) declare python-dateutil in pyproject.toml dependencies (currently transitive via mistralai), (2) delete dead _PinnedDatetime class in test_generate_response_date_scoping.py:22-31. | Request Changes | 5/28/2026, 3:00:00 PM |
| 4 | Reviewer | validator_verdict | APPROVE (round 2) — both REQUEST_CHANGES items fixed, no scope creep, round-1 work intact, suite green modulo pre-existing master failure. | Approve | 5/28/2026, 3:10:00 PM |
| 5 | Runtime | validator_verdict | APPROVE (skipped) — 0 [R] assertions in validation contract; Project row has no spawn_hint / ready_url / smoke_routes; ticket explicitly tags manual smoke as post-deploy via fhs-deploy + fhs-ui-qa. | Approve | 5/28/2026, 3:11:00 PM |
| 6 | Orchestrator | pr_opened | PR opened: https://github.com/Adva-Solutions/Hartman-FHS-Agent/pull/5 | 5/28/2026, 3:15:30 PM | |
| 7 | Orchestrator | completed | Run complete — PR https://github.com/Adva-Solutions/Hartman-FHS-Agent/pull/5 open against master, ticket ready for human review/merge. | 5/28/2026, 3:15:45 PM |