Conversation
select-intended-untracked decided eight conditions in one boolean and answered all of them with the same opaque `intended-untracked-selection-binding-rejected`. A caller holding provider-issued bytes could not tell a status that moved under it from a path outside the eligible list, and the only route left was to send the same call again -- which is what Gentleman-Programming#941 reports doing five times. The conditions keep their original order and their original outcome, and each now names itself: `selection-input-absent`, `binding-mismatch`, `status-field-mismatch` with the field that moved, `eligible-paths-unreadable`, `untracked-selection-invalid`, and `path-not-eligible` with the refused path. START rejections have carried `reason`/`field` since they were introduced; this is the same shape. Tests assert the reason for each existing rejection case, add a status that moves between issuing and revalidating the binding (target_identity and candidate_tree), and pin the reporter's own shape -- a candidate with no untracked files and an empty selection -- as accepted, excluding every eligible path. Refs Gentleman-Programming#941
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review. 📝 WalkthroughWalkthroughThe change centralizes intended-untracked selection validation, reports structured rejection reasons and fields, and adds tests for status drift, invalid selections, and valid empty selections. ChangesIntended-untracked selection validation
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~15 minutes Change: Bug fix Sequence Diagram(s)sequenceDiagram
participant ReviewController
participant SelectionValidator
participant ReviewStart
ReviewController->>SelectionValidator: validate intended-untracked selection
SelectionValidator-->>ReviewController: return reason and optional field
ReviewController->>ReviewStart: start when validation succeeds
Suggested reviewers: Merge Risk: ⚪ Minimal · up to The structured rejection reporting preserves rejection behavior and adds coverage for the new reason, field, status-drift, and empty-selection cases. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There is a concrete committed-range variant of this rejection that can inform the follow-up fix. This is not evidence that #941 has the same cause, and it does not require expanding this diagnostic-only PR. Observed on published gentle-pi 2.5.0 (macOS)The tracked worktree was clean, with an existing committed candidate and an unchanged unrelated untracked inventory. An ordinary START with an explicit base commit and Installed-source diagnosisIn
Suggested follow-up boundaryKeep the rejection checks. Retain the validated pre-lineage route in the host, bound to the exact provider-issued binding, session, and canonical worktree. Preserve the already-resolved base commit, committed-only semantics, and original policy/focus through both the fresh status check and the subsequent START. Do not make the caller reconstruct selectors or relax provider binding validation. Unknown/stale routes and conflicting contexts for the same binding should fail closed. The regression worth adding is the composition: clean tracked workspace + committed-range START + unrelated untracked inventory + selection Evidence boundary: the facade rejection was observed in the live Pi host; the causal path was then checked statically in the installed package. No new regression test, patched build, or end-to-end fix verification has been executed. This comment was prepared with AI assistance and is posted with the user's authorization; private repository details and candidate identifiers are omitted. |
|
Thanks — this is the kind of report that makes a diagnostic worth having, and both source claims hold on current
I agree this does not belong in this PR: it is a behaviour change, and this one only names the check that already refused. What it does do for your case is turn the aggregate into a discriminator. The order in
I cannot reproduce your exact state here (it needs the committed candidate and the untracked inventory you had), so I am not claiming which of the two fires for you. But re-running the same two calls against this branch answers it in one line, and whichever it is narrows the follow-up: On the boundary you suggest: keeping the rejection checks and retaining the validated pre-lineage route bound to the exact provider-issued binding sounds right to me, and the policy/focus loss at 7368 is worth its own line in that follow-up even though, as you say, this occurrence does not demonstrate it. |
Refs #941. This does not fix the rejection the reporter hit — it makes the rejection say which check failed, which is what the report is actually stuck on. Details and evidence below, including what I could rule out.
What #941 is stuck on
select-intended-untrackeddecides eight conditions in one boolean and answers every one of them with the same string:A caller holding provider-issued bytes cannot tell a status that moved under it (retry after a fresh inspect) from a path outside the eligible list (fix the selection) from an unreadable
eligible_paths_json(a provider problem). The report shows the consequence: five attempts of the same call with machine-verified bytes, and no forward route.After this change each condition names itself, in the same order, with the same
outcomekept for compatibility:fieldselection-input-absentbinding-mismatchstatus-field-mismatcheligible-paths-unreadableeligible_paths_jsonabsent, duplicated, or not JSONuntracked-selection-invalidvalidateNativeStartUntrackedSelectionrefused the pairpath-not-eligiblenativeStartRejectionhas carriedreason/fieldfor START since it was introduced, so this is the shape the file already uses.On the one judgement call worth a reviewer's eye:
path-not-eligibleechoes back a path the caller itself just submitted, in the response to that same call — no information the caller did not already have, and with a 400-entry inventory it is the only way to tell which entry was refused. Dropping thefieldthere is a one-line change if you would rather it never appear.What I could rule out
The empty-selection path itself is sound. I reproduced the reporter's shape in the existing harness — candidate touching only tracked files, an unrelated untracked inventory (including a path with spaces),
intendedUntracked: []— and it starts, taking theexcludescope withintended_untracked: []:That is now a test, so the case cannot regress. It also means the rejection in #941 comes from one of the identity/binding/eligible-list terms against the native provider's payload, which I cannot reproduce from here — hence the reason field rather than a guess at a fix. Once this lands, @jmasenjowork-glitch's next attempt reports which one, and that is a one-line answer instead of a five-attempt investigation.
Things I checked and found innocent:
validateNativeStartUntrackedSelectionaccepts{scope: exclude, inventory, intendedUntracked: []}(extensions/gentle-ai.ts:5009only rejects a non-empty selection underexclude);exactCollectArgumentdoes no tokenizing, so a path containing spaces is not truncated;isCanonicalProcessStringimposes no length bound, so a 426-entryeligible_paths_jsonis not rejected for size anywhere in the TypeScript layer.Verification
node --experimental-strip-types --test tests/review-controller-native-routing.test.ts→ 68 pass, 0 fail (was 65; three new cases).extensions/gentle-ai.tsand keeping the tests → 4 fail: both existingpre-lineage intended-untracked selection …cases (the per-casereasonassertions) and both moved-status cases. The empty-selection test passes in both states, which is what makes it a regression guard rather than a restatement of the change.node scripts/check-types.mjs→203 recorded diagnostic(s), no regressions. The gate also reports one pre-existing improvement intests/review-candidate-view.test.ts TS2540, which is already true on a cleanorigin/main(verified by stashing), soscripts/types-baseline.jsonis deliberately left untouched here.Summary by CodeRabbit
Bug Fixes
Improvements