Strategist recent_investment counts lifetime resolutions alongside windowed score history

Open
#883 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
30/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
python
Domain
tooling

Research direction

Start with dimension_trajectories in desloppify/engine/_plan/triage/strategist_data.py, where windowed dimension_scores are returned alongside an unwindowed recent_investment count. Run the synthetic reproduction in the issue to confirm the old resolved item is counted. Done means a maintainer-chosen policy for the investment window and for untimestamped legacy resolutions, with tests in desloppify/tests/plan/test_strategist_data.py covering that boundary. The issue asks for a decision first, so do not patch the counter before the contract is settled.

Written by the indexing model from the issue text.

Description

Strategist recent_investment counts lifetime resolutions alongside windowed score history

dimension_trajectories(..., window=N) windows the dimension scores but fills recent_investment from every retained work item, without checking resolution timestamps or scan counts. A workflow receipt resolved in 2000 is therefore supplied as one recent investment alongside a one-scan score trajectory from 2026.

This is a deterministic input-label/window mismatch, before any model output. It can encourage the strategist to interpret lifetime activity as recent unsuccessful investment. I am not claiming that every resulting model recommendation is wrong, or that workflow receipts must be excluded from all investment measures.

Reproduction from a checkout, with no project scan or LLM call:

PYTHONPATH=. python - <<'PYTHON'
from desloppify.engine._plan.triage.strategist_data import dimension_trajectories
history = [{
    "timestamp": "2026-03-02T00:00:00+00:00",
    "dimension_scores": {"Test health": {"strict": 70.0}},
}]
items = {"strategy::old-evidence-audit": {
    "detector": "strategy", "status": "fixed",
    "resolved_at": "2000-01-01T00:00:00+00:00",
    "work_item_kind": "workflow_action",
    "detail": {"dimension": "Test health"},
}}
result = dimension_trajectories(
    history, {"Test health": {"strict": 70.0}}, items, window=1,
)["Test health"]
print(result.strict_scores, result.recent_investment)
PYTHON

Actual: [70.0] 1. Removing the old workflow item yields [70.0] 0. Changing the score window does not restrict the investment population. The same occurs for an old source-review fix, so this is not dependent on excluding workflow items.

Expected: either count investments within a documented window aligned with the score trajectory, or expose and describe this as an all-time count of explicitly dimension-tagged closures. If lifetime workflow effort is intentional, keep that signal but distinguish it from recent source/test interventions. Handling untimestamped legacy resolutions needs an explicit policy rather than guessing that they are recent.

Code references at upstream commit 3a7735d531a96b6a226bfbdc9fd662b14195f857 (the relevant files are byte-identical in the tested checkout):

Scope clarification: _dimension_name_for_issue explicitly supports synthetic/work-queue items, so their inclusion appears intentional. This counter uses explicit detail.dimension/dimension_name; it is not a detector-derived count of test changes or successful code interventions. This issue does not request changing score formulas, accepted-debt policy, or global workflow inclusion.

This is separate from #882: no strategy upsert or lifecycle-history loss is needed. An immutable synthetic dictionary reproduces this aggregation behavior.

Validation: existing strategist data tests pass (5 tests); the synthetic reproduction and prompt-payload probe run without state writes or model calls. No runtime patch is proposed because the intended recency/legacy-data contract needs clarification.

Dominant language
Python
Stars
3.8k
Forks
301
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from peteromallet/desloppify

All issues in peteromallet/desloppify

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.