You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(review): bound STATUS loses committed-range selector after Pi restart, and baseRef input is unreachable from direct tool calls (4.3.0) #2379
I searched open and closed issues and did not find a report of this problem.
I reviewed this report and removed credentials, tokens, private paths, hostnames, and other sensitive data.
Problem
After a Pi restart, gentle_reviewstatus with the exact retained lineageId no longer resolves an open committed-range lineage. The facade keeps the lineage's committed-range selector only in memory (CandidateViewRegistry.projections), so after the restart STATUS falls back to the workspace current-changes projection: applicability: "unrelated", next_transition: collect / empty_candidate_base_ref_required, and repair counts lineages: 0. The native authority is intact (review-state.json: state: correction_required, selector base-diff with a full base_ref, 4 admitted role results).
The only workaround, passing {"baseRef":"<FULL_SHA>","committedOnly":true} to STATUS, is unreachable: the facade requires input to be a serialized string for every operation except START/ASSESS, and the tool-call layer always JSON-parses string values that look like JSON into objects. Same root class as #2375 (answer-consent) and #1573 (fixed for START/ASSESS only).
Steps to reproduce
RDD on; START a committed-range lineage (baseRef + committedOnly: true) and drive it to correction_required with a targeted-validator slot pending.
Restart Pi (e.g. to set GENTLE_PI_REVIEW_RELAY_PI_TIMEOUT_MS after a relay timeout).
gentle_reviewstatus with lineageId (with or without workspaceRoot).
gentle_reviewstatus with input{"baseRef":"<FULL_SHA>","committedOnly":true}.
Expected and actual behavior
Expected: STATUS reoffers the pending validator slot for the lineage, either because the facade restores the committed selector from native state or because STATUS accepts input as an object like START/ASSESS do.
Actual:
Step 3: applicability: "unrelated", workspace projection, empty_candidate_base_ref_required, no collect bindings.
Step 4, object form or with leading whitespace: Review controller input must be a string.
In-memory projection loss across restarts:CandidateViewRegistry.projections is purely volatile memory. When Pi restarts during an open committed-range lineage, subsequent status calls lose the remembered base selector and fall back to the workspace current-changes projection, rendering the lineage as unrelated.
Expanding serializeReviewJsonArgument in parseReviewControllerParameters to include STATUS will immediately unblock the workaround via tool calls.
A cleaner long-term recovery is having CandidateViewRegistry hydrate known lineage base selectors from the persisted native review-state.json on restart so manual re-specification is unnecessary.
Activity
carlosmoradev commentedon Oct 18, 2026
Very sharp diagnosis, @ManuelDevOps.
Two linked gaps confirmed
CandidateViewRegistry.projectionsis purely volatile memory. When Pi restarts during an open committed-range lineage, subsequentstatuscalls lose the remembered base selector and fall back to the workspace current-changes projection, rendering the lineage asunrelated.extensions/gentle-ai.ts:5567,parseReviewControllerParametersonly serialized object inputs forSTARTandASSESS(bug(review): gentle_review START fails with "input: must be string" — escaped-string contract has no object→string coercion #1573). We just opened PR fix(review): coerce answer-consent object input to serialized string (#2375) #2387 to includeanswer-consent(bug(review): gentle_review answer-consent input is unreachable from direct tool calls (object never coerced to string) (4.3.0) #2375), and your report proves thatSTATUS(REVIEW_CONTROLLER_OPERATION.STATUS) needs the exact same object coercion so passinginput: {"baseRef":"...","committedOnly":true}can reach the status probe rather than aborting withReview controller input must be a string.Path forward
serializeReviewJsonArgumentinparseReviewControllerParametersto includeSTATUSwill immediately unblock the workaround via tool calls.CandidateViewRegistryhydrate known lineage base selectors from the persisted nativereview-state.jsonon restart so manual re-specification is unnecessary.