Skip to content

[finding] plugins/uberdev/lib/premerge-findings.py — 6 findings #770

Open

Description

@TheFJK

@TheFJK — /premerge flagged a blocker finding on PR #768.

Origin: 2c6db44177351a84156c12e838aceecd76f8713b
Agent: premerge.review.code_review
File: plugins/uberdev/lib/premerge-findings.py:425
Severity: blocker (Phase premerge)
Disposition: DEFERRED (premerge-repair-budget-exhausted)
Tier: BLOCKER
Blocks: #768

Findings (6)

1. plugins/uberdev/lib/premerge-findings.py:425 — blocker / BLOCKER / DEFERRED (premerge-repair-budget-exhausted) — _repo_path's .git guard inspects only the FIRST path segment, so sub/.git and a/.git/config pass - and this PR makes tha

Lenses: premerge.review.code_review

first = value.split('/',1)[0]; if first in ('..','.git') rejects .git/config but admits sub/.git. Before this PR the only paths reaching _repo_path came from the built-in reviewer; --carry-blocked now routes agent-chosen blocked_on_file values through it. A submodule's .git is a regular file, so it survives _beneath_repo_root and os.path.isfile, becomes a first-class wave member with severity blocker, and lands in fix-waves-<NN>.json - from which the fix-commit fence derives its entire committable set. No submodules exist in this repo today, which is exactly the reasoning _beneath_repo_root's own docstring rejects for the symlink case.

2. plugins/uberdev/lib/premerge-findings.py:1373 — blocker / BLOCKER / DEFERRED (premerge-repair-budget-exhausted) — _read_blocked_on validates only schema_version and the blocked_on array; the attempt, pr_number and run_id fields the ar

Lenses: premerge.review.code_review

SKILL.md 2a makes the controller hand-write blocked-on-<NN>.json with an attempt field, but nothing reads it - a dead contract field. _read_attempt, the module's designated fail-closed reader, checks schema_version, both arrays, pr_number AND run_id precisely because a field it waves through is a field that crashes somewhere downstream instead of refusing here. A controller that writes blocked-on-02.json when it meant 03, or a run dir reused across two /premerge runs, silently widens the wrong attempt's wave plan with paths from a different stack - up to MAX_BLOCKED_ON agent-chosen files added to the committable set, with BLOCKED=n reporting it as legitimate.

3. plugins/uberdev/lib/premerge-findings.py:1444 — suggestion / SUGGESTION / DEFERRED (premerge-repair-budget-exhausted) — The fingerprint computed for every synthesised blocked_on_carry row is now dead state - no consumer reads it after the c

Lenses: premerge.review.code_review

_read_blocked_on sets fingerprint on each carried row, and _BLOCKED_ON_SUMMARY's 25-line comment block exists solely to keep that fingerprint stable across attempts. But _blocker_fingerprints now continues on _is_carried, _growth_ratio skips carried rows on both sides, cmd_assert_green filters them out and cmd_defer excludes them from _object_rows - so nothing reads the field. Either drop it, or drop the comment's claim that it drives STOP_NO_PROGRESS.

4. plugins/uberdev/lib/premerge-findings.py:1777 — suggestion / SUGGESTION / DEFERRED (premerge-repair-budget-exhausted) — _growth_round_counts adds a third, load-bearing condition to STOP_SELF_REFERENTIAL (blockers >= previous_blockers) that

Lenses: premerge.review.code_review

grep over SKILL.md, commands/premerge.md, docs/rfc/0021 and references/common-mistakes.md returns zero hits for the new term. All four say the stop fires on 'two consecutive measured rounds at or above the ceiling'; the shipped predicate additionally refuses any round that reduced the reviewer-raised blocker count. RFC 0021 states GROWTH(N) = |{...}| / |blockers(N)| but _growth_ratio now excludes blocked_on_carry rows from BOTH sides. A maintainer reading SKILL.md's emphatic 'Do not reduce the requirement to a single round' has no record that the non-reduction term exists and can delete it as unexplained.

5. plugins/uberdev/lib/premerge-findings.py:1792 — suggestion / SUGGESTION / DEFERRED (premerge-repair-budget-exhausted) — _growth_ratio's fail('finding_schema_invalid', 'a blocker is not an object') is unreachable dead code, and it is the one

Lenses: premerge.review.code_review

cmd_converge calls _blocker_fingerprints(current) before _growth_ratio. That function already raises on any blocker whose fingerprint is not 16 hex chars, and a non-dict row yields value None, so it refuses first - the branch can never be taken. It also contradicts _scope_key's own docstring, which explains that _repo_path was replaced there because cmd_converge is the one place where failing closed is WRONG. If the ordering ever changes, this line becomes exit 74 out of the loop's decision step.

6. plugins/uberdev/lib/premerge-findings.py:2462 — suggestion / SUGGESTION / DEFERRED (premerge-repair-budget-exhausted) — GROWTH= is inserted into the middle of the PREMERGE_CONVERGE line (between NEW= and WAIT=) rather than appended, against

Lenses: premerge.review.code_review

The PREMERGE_TRIAGE print at 1863 carries an explicit comment that the first five fields are a pinned prefix and to append, never reorder or insert; #755 correctly appended BLOCKED= at the end. The converge line got the opposite treatment: WAIT=, MAXREPAIRS= and REASONS= all shift one field right. Nothing parses this line positionally today, so the break is latent rather than live, but the run summary transcribes it by hand and any future awk '{print $8}' reader silently reads the wrong field.

To resolve: address the findings above in code and close this issue. Closing resolves exactly the findings listed in this body and the findings added by a later comment on it — one index records both, and closing resolves that recorded set and nothing else. A finding in this file that this issue never recorded is filed as a NEW issue rather than suppressed, so closing never mutes the file. Before closing, apply finding:true-positive if it was a real defect or finding:false-positive if it was not — that label is the eval ground truth (RFC 0018).

Activity

  1. self-assigned this
    on Aug 24, 2026
  2. added
    premerge-findingAuto-filed by /uberdev:premerge from deferred findings (RFC 0002)
    on Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

premerge-findingAuto-filed by /uberdev:premerge from deferred findings (RFC 0002)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions