Skip to content

chore(release): v2.22.0 - #93

Merged
jurby merged 20 commits into
mainfrom
release/v2.22.0
Jul 21, 2026
Merged

chore(release): v2.22.0#93
jurby merged 20 commits into
mainfrom
release/v2.22.0

Conversation

@jurby

@jurby jurby commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Release v2.22.0

Three credit-allocation fixes (D-80, D-81, D-82) — they change how derived hours redistribute across items and people; invariants (Σcw = 1.0 per item, Σ hours = capacity) are untouched.

Fixed

  • D-80 — net-negative contribution scores silently voided an item's entire credit → clamp at 0 + WARN
  • D-81 — QA bounce double-credited gate edges (1.64× js) → gate credit is now a per-lifecycle budget (≤ 1.0 × js per item; backward moves/re-crossings earn nothing, forward jumps sum bypassed edges, equal-split fallback removed)
  • D-82 — gate events inherited all-time contributors → attribution chain windowpassthroughauthor, recorded per event in the audit

Notes

  • Closed iteration snapshots are not rewritten retroactively; re-running an old iteration yields corrected numbers.
  • Monte Carlo validation figures (MAD 7.8 %) were measured against the old model — candidate for re-validation.
  • Docs: methodology.md + RUNBOOK.md + cw_heuristics template were already updated with the fixes; this release adds playbook CZ + web playbook CZ/EN.

Verification

  • Full suite: 1226 passed, 1 skipped
  • test_version_consistent: green
  • Web build: 30 pages OK

jurby and others added 20 commits July 21, 2026 02:02
Auto-generated by local_evidence.py post-commit hook.
Source commit: 926b409
A contributor whose signals netted negative (yaml_edit:revert from
grooming cleanup on someone else's item) deflated the per-item cw
denominator, pushing the legitimate contributors above cw 1.0 — which
engine.extract_contributors hard-drops as out of range, silently
voiding ALL credit on the item with no WARN anywhere.

aggregate_signals now clamps per-person net scores at 0 before
normalization; the raw negative score stays in contribution_score for
audit and the clamp warns on stderr. All-negative items return None
(existing warn-and-skip path). A revert from the same person still
reduces their own score — the clamp only kicks in at the net-negative
boundary, not per signal.

extract_contributors also warns when dropping out-of-range cw (covers
files written before the clamp and hand-written frontmatter).

Tests: 3 aggregate cases (clamp-to-zero, all-negative -> None,
own-revert) + 1 engine WARN case; full suite 1219 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Auto-generated by local_evidence.py post-commit hook.
Source commit: 301480a
Auto-generated by local_evidence.py post-commit hook.
Source commit: 538f7fe
Auto-generated by local_evidence.py post-commit hook.
Source commit: 52a9198
Auto-generated by local_evidence.py post-commit hook.
Source commit: 75cc42a
…cash

A QA bounce re-crossing Implementing->Validating credited 0.50 x js on
EVERY crossing (1.64x js total for one bounce); a reopen hit the
equal-split fallback (~0.143 — more than Releasing→Done); a forward
jump got an arbitrary 1/N instead of the bypassed edges it compressed.

load_gate_events now replays each item's gate-edge budget over its full
materialized transition history: each ladder edge credits at most once
(first crossing), backward moves and re-crossings earn nothing, forward
jumps sum the bypassed edges, off-ladder transitions earn nothing with
a WARN (equal-split fallback removed). Total gate credit per item is
bounded at 1.0 x js, matching the gate_weights config contract.

Tests: bounce-once, forward-jump, cross-iteration replay, unknown-gate,
revert-not-subtract (rewritten). Suite 1221 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Auto-generated by local_evidence.py post-commit hook.
Source commit: e701798
… contributors

Gate events inherited the parent's ALL-TIME contributors[] as their
first attribution step, so a contributor from an earlier iteration kept
scoring at gates in iterations they never worked the item — the
per-iteration proportional normalization then spread their capacity
over ghost shares.

Attribution is now a chain, recorded per event in the gate_events audit
(attribution field): (1) window — shares recomputed from the parent's
in-window credit-bearing evidence (same math as D-73's
_activity_contributors; agent_contribution and neutralized signals
excluded), (2) passthrough — all-time contributors[] when no in-window
signals exist, (3) author — the transition author at cw=1.0 (v1.17.1
fallback preserved).

Tests: 4 new attribution tests; docs + template updated. Suite 1226
passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Auto-generated by local_evidence.py post-commit hook.
Source commit: 5b34ea4
Auto-generated by local_evidence.py post-commit hook.
Source commit: dfb296d
Auto-generated by local_evidence.py post-commit hook.
Source commit: 14e04b6
Version stamps + CHANGELOG entry for the credit-allocation fixes
(D-80 clamp, D-81 gate budget, D-82 gate attribution). Playbook CZ +
web playbook CZ/EN now document the gate per-lifecycle budget and the
window > passthrough > author attribution chain.
Auto-generated by local_evidence.py post-commit hook.
Source commit: 4ea5b4c
@jurby
jurby merged commit 872f544 into main Jul 21, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant