Repository navigation
fix(review): allow empty input for ambient inspect (#1648) #1677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b8e29c3
02bc095
96e033c
03d0681
92e05d6
bf1beb5
75110ba
73abca9
9d9771e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8156,7 +8156,7 @@ async function executeReviewControllerOperation( | |
| parameters.operation === REVIEW_CONTROLLER_OPERATION.INSPECT && | ||
| nativeReviewCli !== null | ||
| ) { | ||
| const rawInspect = parameters.input === undefined | ||
| const rawInspect = parameters.input === undefined || parameters.input.trim() === "" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: sed -n '4840,4920p' extensions/gentle-ai.ts
sed -n '8135,8190p' extensions/gentle-ai.ts
rg -n 'REVIEW_JSON_STRING|gentle_review|syncBuiltinESMExports|whitespace-only' extensions/gentle-ai.ts tests/gentle-ai.test.ts tests/review-controller-native-routing.test.ts | head -95Repository: Gentleman-Programming/gentle-shell Length of output: 27635 🏁 Script executed: sed -n '9370,9565p' extensions/gentle-ai.ts
rg -n 'validateToolArguments|function validateToolArguments|REVIEW_CONTROLLER_PARAMETERS|parameters\\.input|operation.*inspect|inspect.*input' extensions/gentle-ai.ts tests/gentle-ai.test.ts
sed -n '880,1035p' tests/gentle-ai.test.ts
sed -n '1050,1175p' tests/review-controller-native-routing.test.tsRepository: Gentleman-Programming/gentle-shell Length of output: 38012 🏁 Script executed: sed -n '9370,9565p' extensions/gentle-ai.ts
rg -n 'validateToolArguments|REVIEW_CONTROLLER_PARAMETERS|name: "gentle_review"|parameters: REVIEW_CONTROLLER|trim\\(\\) === ""|operation: "inspect"' extensions/gentle-ai.ts tests/gentle-ai.test.ts tests/review-controller-native-routing.test.ts
sed -n '890,1020p' tests/gentle-ai.test.ts
sed -n '1045,1170p' tests/review-controller-native-routing.test.tsRepository: Gentleman-Programming/gentle-shell Length of output: 36005 Allow whitespace-only The registered 🐛 Suggested fix const REVIEW_JSON_STRING = { type: "string", pattern: "^\\s*\\{" } as const;
const REVIEW_JSON_ARGUMENT = { anyOf: [REVIEW_JSON_STRING, { type: "object" }] } as const;
+const REVIEW_INSPECT_JSON_STRING = {
+ anyOf: [REVIEW_JSON_STRING, { type: "string", pattern: "^\\s*$" }],
+} as const; input: {
- anyOf: [...REVIEW_JSON_ARGUMENT.anyOf, { type: "null" }],
+ anyOf: [...REVIEW_JSON_ARGUMENT.anyOf, { type: "string", pattern: "^\\s*$" }, { type: "null" }],
description: `${REVIEW_CONTROLLER_PARAMETER_FIELDS.properties.input.description} Null is invalid; omit input when optional.`,
},
},
anyOf: [
+ {
+ ...REVIEW_CONTROLLER_PARAMETER_FIELDS,
+ properties: {
+ ...REVIEW_CONTROLLER_PARAMETER_FIELDS.properties,
+ operation: { ...REVIEW_CONTROLLER_PARAMETER_FIELDS.properties.operation, enum: ["inspect"] },
+ input: { ...REVIEW_INSPECT_JSON_STRING, description: "Serialized JSON object string or whitespace-only string." },
+ },
+ },
{
...REVIEW_CONTROLLER_PARAMETER_FIELDS,
properties: {
...REVIEW_CONTROLLER_PARAMETER_FIELDS.properties,
- operation: { ...REVIEW_CONTROLLER_PARAMETER_FIELDS.properties.operation, enum: Object.values(REVIEW_CONTROLLER_OPERATION).filter((operation) => operation !== "start" && operation !== "assess") },
+ operation: { ...REVIEW_CONTROLLER_PARAMETER_FIELDS.properties.operation, enum: Object.values(REVIEW_CONTROLLER_OPERATION).filter((operation) => operation !== "start" && operation !== "assess" && operation !== "inspect") },
input: { ...REVIEW_JSON_STRING, description: "Serialized JSON object string only; objects are accepted only by START/ASSESS." },
},
},🤖 Prompt for AI Agents |
||
| ? undefined | ||
| : parseControllerJson(parameters.input, REVIEW_CONTROLLER_OPERATION.INSPECT); | ||
| const unknownField = rawInspect === undefined | ||
|
|
@@ -8166,7 +8166,7 @@ async function executeReviewControllerOperation( | |
| const baseRef = rawInspect?.baseRef; | ||
| if (baseRef !== undefined && !isCanonicalProcessString(baseRef)) return nativeInspectInputRejection("base-ref-invalid"); | ||
| if (baseRef !== undefined && rawInspect?.committedOnly !== true) return nativeInspectInputRejection("committed-only-required"); | ||
| if (rawInspect !== undefined && baseRef === undefined) return nativeInspectInputRejection("committed-only-invalid"); | ||
| if (rawInspect?.committedOnly !== undefined && baseRef === undefined) return nativeInspectInputRejection("committed-only-invalid"); | ||
| let canonicalBaseRef: string | undefined; | ||
| if (typeof baseRef === "string") { | ||
| try { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Fix #1648: allow empty input `{}` and empty string for ambient inspect | ||
|
|
||
| ## Objective | ||
|
|
||
| Prevent `gentle_review inspect` from rejecting ambient inspection calls when `input` is provided as an empty JSON object `"{}"` or empty string `""`. Ensure `committed-only-invalid` is only returned when `committedOnly` is actually supplied without `baseRef`. | ||
|
|
||
| ## Problem | ||
|
|
||
| When a caller (such as an LLM conforming to tool schemas) calls `gentle_review` with `{"operation": "inspect", "input": "{}"}`: | ||
| `extensions/gentle-ai.ts:7843` checks: | ||
| ```ts | ||
| if (rawInspect !== undefined && baseRef === undefined) return nativeInspectInputRejection("committed-only-invalid"); | ||
| ``` | ||
| Because `rawInspect` is `{}` (not `undefined`) and `baseRef` is `undefined`, the controller returns `committed-only-invalid` even though `committedOnly` was never passed. | ||
| Additionally, passing empty string `input: ""` throws a JSON parse error instead of treating it as omitted input. | ||
|
|
||
| ## Scope | ||
|
|
||
| - In `extensions/gentle-ai.ts`, treat empty/whitespace input string as `undefined` for `inspect`. | ||
| - In `extensions/gentle-ai.ts`, reject `committed-only-invalid` only if `rawInspect?.committedOnly !== undefined && baseRef === undefined`. | ||
| - When `rawInspect` is empty `{}` (no `baseRef` and no `committedOnly`), allow it to proceed to ambient inspect. | ||
| - In `tests/review-controller-native-routing.test.ts`, add tests proving: | ||
| - `input: "{}"` proceeds to ambient inspect. | ||
| - `input: ""` proceeds to ambient inspect. | ||
| - `input: '{"committedOnly": true}'` still rejects `committed-only-invalid`. | ||
| - `input: '{"committedOnly": false}'` still rejects `committed-only-invalid`. | ||
|
|
||
| ## Tasks | ||
|
|
||
| - [x] T1 Reproduce #1648 with failing unit tests in `tests/review-controller-native-routing.test.ts` (RED). | ||
| - [x] T2 Fix inspect input validation in `extensions/gentle-ai.ts` (GREEN). | ||
| - [x] T3 Verify full test suite, runtime module checks, and typechecks. | ||
| - [x] T4 Commit work unit and document verification evidence (commit `975e1709`). | ||
|
|
||
| ## Verification Evidence | ||
|
|
||
| - **RED observed**: | ||
| - `INSPECT accepts empty object and empty string input for ambient inspection`: failed with `AssertionError: expected ready for input "{}" ('blocked' !== 'ready')`, rejected with `native-inspect-input-invalid` and `reason: "committed-only-invalid"`. | ||
| - **GREEN observed**: | ||
| - Test passed for `"{}"`, `""`, and `" "`, successfully executing ambient `targetStatus` (3/3 calls). | ||
| - Malformed committed-range selectors (`{ committedOnly: true }`, `{ committedOnly: false }`) continue to fail closed with `committed-only-invalid`. | ||
| - `node --experimental-strip-types --test tests/review-controller-native-routing.test.ts`: 89 passed, 0 failed. | ||
| - `pnpm run typecheck`: clean (187 recorded baseline diagnostics, 0 regressions). | ||
| - `pnpm run check:runtime-modules`: clean (8 generated modules). | ||
| - `pnpm test`: 4,539 passed, 0 failed, 34 skipped (all three stages PASS: `unit-tests`, `provider-contract`, `runtime-harness`). | ||
|
|
||
|
|
||
| ## Acceptance Criteria | ||
|
|
||
| - `executeReviewControllerOperation` with `operation: "inspect"` and `input: "{}"` or `input: ""` succeeds and dispatches ambient inspection. | ||
| - Calls providing `committedOnly` without `baseRef` continue to fail closed with `committed-only-invalid`. | ||
| - All tests in `tests/review-controller-native-routing.test.ts` and full test suite pass. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: Gentleman-Programming/gentle-shell
Length of output: 7673
🏁 Script executed:
Repository: Gentleman-Programming/gentle-shell
Length of output: 15803
🏁 Script executed:
Repository: Gentleman-Programming/gentle-shell
Length of output: 12194
Use the exact workspace-root test title.
The pull-request-only focused Windows job requires one exact top-level
test(...)declaration for each$namesentry. The changed title has no match, so the inventory guard fails before Node tests and TAP parsing run.Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents