Apply Development Effort Calculator to real pilot candidates (WP-0010-T03)
Adds since/until date-range scoping to cluster_commit_hours() and workplan_task_counts() (threaded through calculate_target_basis()), needed whenever a candidate is one bounded workplan within a repo whose overall history spans much more (net-kingdom, railiance-apps) rather than the whole repo being the candidate (vergabe-teilnahme, info-tech-canon). Fixes a real bug found along the way: workplan_task_counts() only scanned the top level of workplans/, missing net-kingdom's workplans/archived/ convention entirely - silently reported zero finished workplans for NK-WP-0002, which lives there. Fixed to scan recursively; added a regression test. Updates all three draft pilot-candidate manifests with calculator- derived target_basis/initial_target values, replacing the hand-picked placeholders: net-kingdom-local-identity: 200,000 -> 10,000 EUR (floor + sanity warnings) railiance-vergabe-teilnahme: 3,500,000 -> 648,800 EUR (no warnings) info-tech-canon-service-surface: 2,500,000 -> 141,800 EUR (sanity warning) history/260730-EffortCalculator-CandidateApplication.md records full derivation, warnings, and the judgment calls made explicit rather than silently picked (date-scoping windows; measuring vergabe-teilnahme's own repo rather than railiance-apps' deployment-only wiring, with both figures shown). Still draft/non-binding - WP-0008-T05 unaffected. 5 new tests (20 -> now covering since/until scoping and the archived-subdirectory fix). Full suite: 84 passing offline.
This commit is contained in:
parent
78a5e72bbf
commit
6eec4f6634
9 changed files with 405 additions and 25 deletions
|
|
@ -86,6 +86,27 @@ def test_cluster_commit_hours_gap_splits_into_two_sessions(git_repo):
|
|||
# --- workplan_task_counts ------------------------------------------------
|
||||
|
||||
|
||||
def test_workplan_task_counts_scans_archived_subdirectory(tmp_path):
|
||||
archived = tmp_path / "workplans" / "archived"
|
||||
archived.mkdir(parents=True)
|
||||
(archived / "old-finished.md").write_text(
|
||||
"""---
|
||||
id: OLD-0001
|
||||
status: finished
|
||||
---
|
||||
|
||||
```task
|
||||
id: OLD-0001-T01
|
||||
status: done
|
||||
```
|
||||
"""
|
||||
)
|
||||
result = ec.workplan_task_counts(tmp_path)
|
||||
assert result.finished_workplans == 1
|
||||
assert result.total_tasks == 1
|
||||
assert result.finished_tasks == 1
|
||||
|
||||
|
||||
def test_workplan_task_counts_no_workplans_dir(tmp_path):
|
||||
result = ec.workplan_task_counts(tmp_path)
|
||||
assert result == ec.WorkplanTaskCounts(0, 0, 0)
|
||||
|
|
@ -244,3 +265,78 @@ def test_calculate_target_basis_end_to_end(git_repo):
|
|||
ec.token_cost_usd(1000, 1000), abs=0.01
|
||||
)
|
||||
assert isinstance(result.estimated_effort_days, float)
|
||||
|
||||
|
||||
# --- since/until date-range scoping ---------------------------------------
|
||||
|
||||
|
||||
def test_cluster_commit_hours_since_until_excludes_outside_window(git_repo):
|
||||
_commit(git_repo, "outside-early", 1_577_836_800) # 2020-01-01
|
||||
_commit(git_repo, "inside", 1_614_556_800) # 2021-03-01
|
||||
_commit(git_repo, "outside-late", 1_672_531_200) # 2023-01-01
|
||||
result = ec.cluster_commit_hours(git_repo, since="2021-01-01", until="2021-06-01")
|
||||
assert result.commit_count == 1
|
||||
|
||||
|
||||
def test_workplan_task_counts_since_until_filters_by_updated_date(tmp_path):
|
||||
workplans = tmp_path / "workplans"
|
||||
workplans.mkdir()
|
||||
(workplans / "old.md").write_text(
|
||||
"""---
|
||||
id: OLD-0001
|
||||
status: finished
|
||||
updated: "2020-01-01"
|
||||
---
|
||||
|
||||
```task
|
||||
id: OLD-0001-T01
|
||||
status: done
|
||||
```
|
||||
"""
|
||||
)
|
||||
(workplans / "recent.md").write_text(
|
||||
"""---
|
||||
id: NEW-0001
|
||||
status: finished
|
||||
updated: "2026-03-03"
|
||||
---
|
||||
|
||||
```task
|
||||
id: NEW-0001-T01
|
||||
status: done
|
||||
```
|
||||
"""
|
||||
)
|
||||
result = ec.workplan_task_counts(tmp_path, since="2026-01-01", until="2026-06-01")
|
||||
assert result.finished_workplans == 1
|
||||
assert result.total_tasks == 1
|
||||
|
||||
|
||||
def test_workplan_task_counts_no_date_field_always_counted(tmp_path):
|
||||
workplans = tmp_path / "workplans"
|
||||
workplans.mkdir()
|
||||
(workplans / "undated.md").write_text(
|
||||
"""---
|
||||
id: UND-0001
|
||||
status: finished
|
||||
---
|
||||
|
||||
```task
|
||||
id: UND-0001-T01
|
||||
status: done
|
||||
```
|
||||
"""
|
||||
)
|
||||
result = ec.workplan_task_counts(tmp_path, since="2026-01-01", until="2026-06-01")
|
||||
assert result.finished_workplans == 1
|
||||
assert result.total_tasks == 1
|
||||
|
||||
|
||||
def test_calculate_target_basis_threads_since_until(git_repo):
|
||||
base = 1_577_836_800 # 2020-01-01
|
||||
_commit(git_repo, "outside", base)
|
||||
_commit(git_repo, "inside", base + 86400 * 400) # ~2021-02-04
|
||||
result = ec.calculate_target_basis(
|
||||
git_repo, daily_rate=1000.0, since="2021-01-01", until="2021-06-01"
|
||||
)
|
||||
assert result.derivation["commits"] == 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue