Repository navigation
bug(review): required-all parameters dead-end ambient inspect before native dispatch #1648
Description
Before submitting
- 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
Native review preflight repeatedly fails in a Pi session before a review can start. The model-facing gentle_review signature presents every named argument as mandatory, while the installed registration declares only operation required. Filling unused optional fields with empty values then encounters operation-specific validation guards.
The concrete ambient inspection case is provided input: "{}" with no baseRef: it returns committed-only-invalid although no committedOnly argument was sent. The native-looking envelope is constructed locally in the extension before native dispatch. No START, lineage, consent envelope, receipt or native approval was produced by these failing calls. Review reminders can reoffer inspection while the model cannot represent the documented minimal call through the required-all interface observed here.
This report concerns the argument/interface boundary and diagnostic usability, not a request to bypass workspace, consent, snapshot or authority validation. Several individual rejections are correct for the supplied values; the integration problem is how optionality and operation-specific input requirements are exposed and diagnosed.
Steps to reproduce
- Use Pi 0.99.2 on native Windows with Node v24.21.0. The package manifest at the session-injected gentle-pi asset root reports 3.5.1. Use an existing disposable Git worktree with RDD already enabled by its human owner. Only read-only inspection is necessary; do not START or change consent.
- Compare registration and model-facing catalog. Installed registration requires only
operation. In the observed session, the exposed signature requiresoperation,lineageId,selectionBinding,intendedUntracked,untrackedScope,changeName,idempotencyKey,transition,input,outputPath,inputPath,operationId,lineageIdsandworkspaceRoot. This is an observed catalog representation, not an instrumented export of the underlying provider request. The optionality-conversion point has not been located. - Ask for ambient inspection without a committed-range selector. With a valid current Git worktree, the reduced operation shape
{"operation":"inspect","input":"{}","untrackedScope":"select","intendedUntracked":[]}yieldsblocked/native-inspect-input-invalid/committed-only-invalid/mutation_performed:false. NobaseReforcommittedOnlywas requested inside the input JSON. - Empty placeholders do not resolve the dead end:
input:""fails JSON parsing;workspaceRoot:""fails the absolute-worktree-root check. ASSESS with top-levelintendedUntrackedoruntrackedScopeis rejected by the inspect-only guard. Those ASSESS keys are supported only nested inside itsinputJSON. The guard is correct, but required-all catalog expansion makes operation-specific omission difficult to express. - Inspect installed 3.5.1 source:
extensions/gentle-ai.ts:4713-4756declaresrequired:["operation"], registered at 8945-8962. Parameter guards are at 4913-4950, workspace-root validation at 6437-6444, and JSON parsing at 5042-5056. The INSPECT branch at 7735-7747 rejects any providedrawInspectwithoutbaseRef, constructing the failure throughnativeInspectInputRejectionat 5825-5836 beforetargetStatus/native dispatch. - The documented minimal ambient shape is
{"operation":"inspect"}, with optional fields omitted. A successful live control call is not claimed: that minimal shape was not representable through the required-all interface observed here. Do not choose an arbitrary committed-only base solely to silence the error, because it changes the review candidate.
Expected and actual behavior
Expected
- Preserve registration optionality in the model-facing interface, so ambient inspect can omit irrelevant selectors and transports.
- Make operation-dependent field placement discoverable and expressible without fabricated placeholders.
- If empty JSON is intentionally invalid for inspect, explain the actual contract: omit
inputfor ambient inspection, or supply a genuine explicit paired committed-range selector. Do not appear to diagnose acommittedOnlyfield that does not exist. - Continue rejecting real invalid selectors and authority/consent inputs.
Actual and confirmed
- Installed
required:["operation"]differs from the required-all signature visible to the model. The conversion point remains uninstrumented. - All listed failures originate locally in installed extension validation. Even
native-inspect-input-invalidis a pre-dispatch return, not a Go/native CLI rejection. - No
committedOnly:falseserialization exists in shipped extensions/lib. The source emitstrueonly withbaseRef; the false-wire hypothesis is ruled out.
Possible contributors, explicitly not established causes
- Host/provider strict-schema normalization or model-facing adaptation may promote optional properties. Installed registration itself does not mark them required.
- A flat schema describes operation-specific fields while runtime guards enforce their placement and presence. Required-all expansion plus empty placeholders can create an integration dead end.
- Empty inspect JSON enters the
rawInspect-present /baseRef-absent guard and receives an imprecise reason code. - Versions are mixed: PATH launcher/native CLI report 3.7.0, while the injected package manifest reports 3.5.1. Source default native resolution uses a package-local 3.5.0 pin, not PATH. A development override was not inspected. Native version skew cannot explain these local pre-dispatch guard returns; behavior in a loaded 3.7.0 runtime was not verified.
Evidence limits
- Active tool module-path instrumentation and the raw provider request schema are unavailable. The package version comes from the session-injected asset/package root.
- An additional offline
__testinghelper probe did not run its assertions: Node v24.21.0 returnedERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPINGfor TypeScript installed undernode_modules. No dynamic zero-native-call counter is claimed. Pre-spawn origin follows installed source control flow and actual tool failures. - No package modification, installation, real native lifecycle probe, recovery, reset, review-mode change or authority mutation was used to prepare this report.
Related trackers privately examined, not equivalent to this case
- bug(review): committed-range START unreachable (3 contradictory prerequisite errors → native schema-incompatible) and inspect bases the range on the default branch #992 — explicit committed-range START prerequisites, branch-base selection and native schema compatibility.
- bug(review): blank optional tool arguments block gentle_review finalize #229 — blank optional alternative transports on retired FINALIZE.
- gentle_review: tool schema too abstract, non-discoverable params, and unhelpful error messages #103 — older nested START/lifecycle discoverability.
- bug(agents): subagent_run rejects every launch when optional root selectors are present but empty #1439 — empty optional root selectors on
subagent_run. - review: session report — 37k-line staged set split into 19 units, full remediation, and 2 committed-range CLI reviews (4+1 lenses) approved/burned #1170 — START carrying inspect-only top-level fields plus committed-range/host-dispatch reporting.
Open-and-closed search completed without saturation, followed by full private examination of these five canonical bodies before choosing a new report.
gentle-pi version
3.5.1 (manifest at the session-injected asset/package root). PATH launcher: gentle-shell 3.7.0. Default packaged native pin: 3.5.0; actual override state unverified.
Pi version
0.99.2; Node v24.21.0; native Windows x64.
Operating system
Windows
Relevant logs or error output (optional)
Installed tool registration: required:["operation"]
Model-visible session catalog: all 14 named fields presented as mandatory
{"operation":"inspect","status":"blocked",
"outcome":"native-inspect-input-invalid",
"reason":"committed-only-invalid",
"mutation_performed":false,"mutation_outcome":"none"}
Review controller assess does not accept intendedUntracked; it is accepted only by inspect with untrackedScope select
Note: top-level inspect-only fields were rejected locally, as designed.
Review controller workspaceRoot must be an absolute path to an existing Git worktree root; received ""
inspect input is not valid JSON: Unexpected end of JSON input
Historical related local error: inspect intendedUntracked requires untrackedScope select
gentle-pi manifest at injected asset/package root: 3.5.1
gentle-shell on PATH: 3.7.0
gentle-ai on PATH: 3.7.0
Pi: 0.99.2
Node: v24.21.0
Platform: win32 x64
Default package-local native pin: 3.5.0; active development override unverified
Activity
danielgap commentedon Oct 5, 2026
Taking this one, with credit to @Jublan87: the report already pins the pre-dispatch guard chain (
extensions/gentle-ai.tsINSPECT branch), rules out the false-wire hypothesis, and honestly scopes what remains uninstrumented. That is a lot of the diagnosis done.Plan, in order:
mainthe registration still declaresrequired: ["operation"](schema ~L4944, registration ~L9656), so the promotion of all 14 parameters to mandatory happens downstream. I will trace registration → model-facing catalog → actual provider request (instrumenting at the provider-request boundary), so the fix lands on the seam that actually converts, rather than on a guess. If that seam turns out to live outside this repository, the deliverable becomes the evidence plus a precise upstream report, plus whatever expressibility we can restore on our side.input: "{}"currently reaches therawInspect !== undefined && baseRef === undefinedguard and returnscommitted-only-invalid(~L8298), which diagnoses a field the caller never sent. Ambient inspection should either treat an empty input object as omitted, or say exactly what it wants: omitinputentirely, or supply a genuine{"baseRef": ..., "committedOnly": true}pair. Real selector guards stay fail-closed.Coordination note: #1710 (open) touches the same registration surface from the root-schema side for #1698. I'll sequence with it rather than race it — @carlosmoradev nothing needed from you yet, just flagging the overlap.
First deliverable is a diagnosis comment with the instrumentation evidence, not a PR. @Jublan87 if you were planning to continue this yourself, say so and I'll stand down.
enriquejmnz commentedon Oct 7, 2026
Corroborating this on Linux with gentle-pi 4.0.0, Pi 0.99.2, Node 22.23.3, and the
command-codeprovider. The same required-all catalog behavior is still observable: the model emitted this ASSESS shape instead of the documented minimal call:{"operation":"assess","lineageId":"","selectionBinding":"","intendedUntracked":[],"untrackedScope":"exclude","changeName":"","idempotencyKey":"","transition":"","input":"","outputPath":"","inputPath":"","operationId":"","lineageIds":"","workspaceRoot":""}Using an injected fake native review client, that exact object was rejected with:
The rejection occurred before any fake
reviewMode,assess, ortargetStatuscall. The minimal{ "operation": "assess" }control reached fake ASSESS normally.I also tested a narrow local compatibility shim that recognizes only the exact inert ASSESS pair
intendedUntracked: []+untrackedScope: "exclude", drops empty string placeholders for that compatibility case, and preserves fail-closed rejection of nonempty top-levelintendedUntrackedand top-leveluntrackedScope: "select". The exact expanded call then reached fake ASSESS, meaningful JSON-stringinputstill parsed normally, and the focused assessment suite passed 91/91.This is corroborating evidence rather than a proposed upstream implementation: the installed-package shim is temporary and will be overwritten by reinstall/update. It confirms that the interface defect described here remains user-visible in 4.0.0 on a second platform/provider combination.
danielgap commentedon Oct 8, 2026
Thanks @enriquejmnz, this corroboration helps a lot. The version matrix plus the emitted ASSESS shape give exactly what step 1 of the plan needs: a second platform (Linux, gentle-pi 4.0.0, Pi 0.99.2) hitting the same dead end, with the model pushed into the full-shape call because the minimal one is unreachable. Two reporters on two platforms also rules out a local config quirk. I will fold your JSON into the instrumented run when I get to it.