Skip to content

bug(review): required-all parameters dead-end ambient inspect before native dispatch #1648

Open

Description

@Jublan87

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

  1. 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.
  2. Compare registration and model-facing catalog. Installed registration requires only operation. In the observed session, the exposed signature requires operation, lineageId, selectionBinding, intendedUntracked, untrackedScope, changeName, idempotencyKey, transition, input, outputPath, inputPath, operationId, lineageIds and workspaceRoot. This is an observed catalog representation, not an instrumented export of the underlying provider request. The optionality-conversion point has not been located.
  3. 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":[]} yields blocked / native-inspect-input-invalid / committed-only-invalid / mutation_performed:false. No baseRef or committedOnly was requested inside the input JSON.
  4. Empty placeholders do not resolve the dead end: input:"" fails JSON parsing; workspaceRoot:"" fails the absolute-worktree-root check. ASSESS with top-level intendedUntracked or untrackedScope is rejected by the inspect-only guard. Those ASSESS keys are supported only nested inside its input JSON. The guard is correct, but required-all catalog expansion makes operation-specific omission difficult to express.
  5. Inspect installed 3.5.1 source: extensions/gentle-ai.ts:4713-4756 declares required:["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 provided rawInspect without baseRef, constructing the failure through nativeInspectInputRejection at 5825-5836 before targetStatus/native dispatch.
  6. 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 input for ambient inspection, or supply a genuine explicit paired committed-range selector. Do not appear to diagnose a committedOnly field 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-invalid is a pre-dispatch return, not a Go/native CLI rejection.
  • No committedOnly:false serialization exists in shipped extensions/lib. The source emits true only with baseRef; 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 __testing helper probe did not run its assertions: Node v24.21.0 returned ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING for TypeScript installed under node_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

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

  1. danielgap commented on Oct 5, 2026

    @danielgap
    Contributor

    Taking this one, with credit to @Jublan87: the report already pins the pre-dispatch guard chain (extensions/gentle-ai.ts INSPECT branch), rules out the false-wire hypothesis, and honestly scopes what remains uninstrumented. That is a lot of the diagnosis done.

    Plan, in order:

    1. Locate the optionality-conversion point with instrumented evidence. On current main the registration still declares required: ["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.
    2. Fix the pre-dispatch inspect diagnostic contract. input: "{}" currently reaches the rawInspect !== undefined && baseRef === undefined guard and returns committed-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: omit input entirely, or supply a genuine {"baseRef": ..., "committedOnly": true} pair. Real selector guards stay fail-closed.
    3. Scope stays on the interface/diagnostic boundary, as the report frames it: no relaxation of workspace, consent, snapshot, or authority validation.

    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.

  2. enriquejmnz commented on Oct 7, 2026

    @enriquejmnz

    Corroborating this on Linux with gentle-pi 4.0.0, Pi 0.99.2, Node 22.23.3, and the command-code provider. 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:

    Review controller assess does not accept intendedUntracked; it is accepted only by inspect with untrackedScope select
    

    The rejection occurred before any fake reviewMode, assess, or targetStatus call. 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-level intendedUntracked and top-level untrackedScope: "select". The exact expanded call then reached fake ASSESS, meaningful JSON-string input still 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.

  3. danielgap commented on Oct 8, 2026

    @danielgap
    Contributor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    status:approvedIssue approved by maintainer; PR may be opened

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions