[GH-ISSUE #3211] [Bug] Import-reference-source schema permits negative outline depths that the command rejects #1147

Closed
opened 2026-10-15 18:31:31 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/3211

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

CLI

Observed behavior

node scripts/rea.mjs import-reference-source --schema --json exits 0 and advertises options.properties.outlineDepth as an integer with minimum -9007199254740991 and maximum 9007199254740991. Submitting -1 with --detail summary exits 1 with VALIDATION_ERROR, a field error at outlineDepth, and Too small: expected number to be >=0. The advertised range therefore includes an input the command rejects.

With the same one-file source fixture, depth 0 exits 0 with a HistoricalSourceSummary, one inventoried file, no outline entries, and an omitted-entry count of 1. Depth 1 exits 0 and includes main.js, with an omitted-entry count of 0. Supplying depth 1 without summary mode exits 1 with invalid_request and --outline-depth requires --detail summary.

Reproduction

  1. From a clean checkout at 58300885207133422af235e0f2b10658cf958b03, install the locked dependencies and build the CLI:

    npm ci
    npm run build:cached
    
  2. Create an isolated home and an inline source fixture. The helper gives each CLI invocation the same isolated HOME and XDG directories:

    repro_root="$(mktemp -d)"
    mkdir -p "$repro_root/home" "$repro_root/source"
    printf 'export const answer = 42;\n' > "$repro_root/source/main.js"
    rea_repro() {
      env HOME="$repro_root/home" \
        XDG_CONFIG_HOME="$repro_root/home/config" \
        XDG_CACHE_HOME="$repro_root/home/cache" \
        XDG_DATA_HOME="$repro_root/home/data" \
        node scripts/rea.mjs "$@"
    }
    
  3. Inspect the published option schema:

    rea_repro import-reference-source --schema --json
    

    options.properties.outlineDepth.minimum is -9007199254740991.

  4. Submit a negative integer inside that advertised range:

    rea_repro import-reference-source "$repro_root/source" --detail summary --outline-depth -1 --json
    

    The command exits 1 with the nonnegative validation error.

  5. Run the successful nonnegative controls and the existing paired-option check:

    rea_repro import-reference-source "$repro_root/source" --detail summary --outline-depth 0 --json
    rea_repro import-reference-source "$repro_root/source" --detail summary --outline-depth 1 --json
    rea_repro import-reference-source "$repro_root/source" --outline-depth 1 --json
    

    Depths 0 and 1 succeed with the outline results described above. The final command rejects the missing summary mode.

Expected behavior

docs/cli.md:240-245 documents --outline-depth as a nonnegative safe integer that requires --detail summary. It defines depth 0 as omitting all outline entries and depth 1 as showing root children. The published numeric constraints should include minimum: 0 and retain maximum: 9007199254740991. Negative depths should continue to fail runtime validation, and the successful controls and paired-option restriction should retain their behavior.

Impact and scope

This is a bounded CLI input-contract failure for consumers that use the machine-readable schema to select or validate arguments. The schema admits a negative value that the command rejects. Selecting a nonnegative safe integer with summary mode is a practical workaround; depths 0 and 1 succeeded on the same fixture. No data loss or downstream client outage was observed. The reproduced scope is the CLI; no MCP reproduction is claimed.

REA version

6.4.0 (main at 5830088520)

Runtime and platform

Node v26.10.0; macOS 27.0.1 arm64; Incur 0.6.1; Zod 4.4.3.

Target and artifact context

A local source directory containing one JavaScript file, main.js, with export const answer = 42; and a trailing newline. No native analysis provider is needed.

Interface

CLI

Earliest failure stage

Request parsing or validation

Relevant output or evidence

--schema --json: exit 0
options.properties.outlineDepth:
  type: integer
  minimum: -9007199254740991
  maximum: 9007199254740991

--detail summary --outline-depth -1 --json: exit 1
code: VALIDATION_ERROR
field: outlineDepth
message: Too small: expected number to be >=0

--detail summary --outline-depth 0 --json: exit 0
outline: {"depth":0,"entries":[],"omitted_entry_count":1}

--detail summary --outline-depth 1 --json: exit 0
outline includes main.js; omitted_entry_count: 0

--outline-depth 1 --json without --detail summary: exit 1
code: invalid_request
message: --outline-depth requires --detail summary

Typed outcome or recovery expected

The exported schema should exclude negative outline depths. Keep the existing VALIDATION_ERROR for -1 and the invalid_request response when an outline depth is supplied without summary mode. Keep successful HistoricalSourceSummary results for depths 0 and 1 with their current outline contents. These controls prevent a repair that merely weakens runtime validation.

Analysis or suspected cause

Source-derived at the verified baseline: src/cli/utilityCommands.ts:252-260 declares outlineDepth with .number().int().nonnegative().safe().optional(). src/cli/utilityCommands.ts:268-283 enforces the summary-mode requirement. The independent verifier also converted the same number constraints through the installed Incur-exported Zod and reproduced the negative schema minimum while runtime parsing rejected -1 and accepted 0. Source inspection of the installed Zod implementation supports a metadata-overwrite explanation in its number-format check and JSON Schema conversion. This causal explanation is separate from the public CLI reproduction and has not been verified by a repair.

Additional context

Related closed issue #1169 concerns defaulted inputs marked required, and closed feature #2442 introduced summaries; this report concerns the advertised numeric minimum for the existing outline-depth option. P2 is supported because a machine-readable argument contract admits a request that fails validation, with a demonstrated safe workaround and successful nonnegative controls.

Originally created by @coygeek on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3211 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area CLI ### Observed behavior `node scripts/rea.mjs import-reference-source --schema --json` exits 0 and advertises `options.properties.outlineDepth` as an integer with minimum -9007199254740991 and maximum 9007199254740991. Submitting -1 with `--detail summary` exits 1 with `VALIDATION_ERROR`, a field error at `outlineDepth`, and `Too small: expected number to be >=0`. The advertised range therefore includes an input the command rejects. With the same one-file source fixture, depth 0 exits 0 with a `HistoricalSourceSummary`, one inventoried file, no outline entries, and an omitted-entry count of 1. Depth 1 exits 0 and includes `main.js`, with an omitted-entry count of 0. Supplying depth 1 without summary mode exits 1 with `invalid_request` and `--outline-depth requires --detail summary`. ### Reproduction 1. From a clean checkout at `58300885207133422af235e0f2b10658cf958b03`, install the locked dependencies and build the CLI: ```sh npm ci npm run build:cached ``` 2. Create an isolated home and an inline source fixture. The helper gives each CLI invocation the same isolated HOME and XDG directories: ```sh repro_root="$(mktemp -d)" mkdir -p "$repro_root/home" "$repro_root/source" printf 'export const answer = 42;\n' > "$repro_root/source/main.js" rea_repro() { env HOME="$repro_root/home" \ XDG_CONFIG_HOME="$repro_root/home/config" \ XDG_CACHE_HOME="$repro_root/home/cache" \ XDG_DATA_HOME="$repro_root/home/data" \ node scripts/rea.mjs "$@" } ``` 3. Inspect the published option schema: ```sh rea_repro import-reference-source --schema --json ``` `options.properties.outlineDepth.minimum` is -9007199254740991. 4. Submit a negative integer inside that advertised range: ```sh rea_repro import-reference-source "$repro_root/source" --detail summary --outline-depth -1 --json ``` The command exits 1 with the nonnegative validation error. 5. Run the successful nonnegative controls and the existing paired-option check: ```sh rea_repro import-reference-source "$repro_root/source" --detail summary --outline-depth 0 --json rea_repro import-reference-source "$repro_root/source" --detail summary --outline-depth 1 --json rea_repro import-reference-source "$repro_root/source" --outline-depth 1 --json ``` Depths 0 and 1 succeed with the outline results described above. The final command rejects the missing summary mode. ### Expected behavior `docs/cli.md:240-245` documents `--outline-depth` as a nonnegative safe integer that requires `--detail summary`. It defines depth 0 as omitting all outline entries and depth 1 as showing root children. The published numeric constraints should include `minimum: 0` and retain `maximum: 9007199254740991`. Negative depths should continue to fail runtime validation, and the successful controls and paired-option restriction should retain their behavior. ### Impact and scope This is a bounded CLI input-contract failure for consumers that use the machine-readable schema to select or validate arguments. The schema admits a negative value that the command rejects. Selecting a nonnegative safe integer with summary mode is a practical workaround; depths 0 and 1 succeeded on the same fixture. No data loss or downstream client outage was observed. The reproduced scope is the CLI; no MCP reproduction is claimed. ### REA version 6.4.0 (main at 58300885207133422af235e0f2b10658cf958b03) ### Runtime and platform Node v26.10.0; macOS 27.0.1 arm64; Incur 0.6.1; Zod 4.4.3. ### Target and artifact context A local source directory containing one JavaScript file, `main.js`, with `export const answer = 42;` and a trailing newline. No native analysis provider is needed. ### Interface CLI ### Earliest failure stage Request parsing or validation ### Relevant output or evidence ```text --schema --json: exit 0 options.properties.outlineDepth: type: integer minimum: -9007199254740991 maximum: 9007199254740991 --detail summary --outline-depth -1 --json: exit 1 code: VALIDATION_ERROR field: outlineDepth message: Too small: expected number to be >=0 --detail summary --outline-depth 0 --json: exit 0 outline: {"depth":0,"entries":[],"omitted_entry_count":1} --detail summary --outline-depth 1 --json: exit 0 outline includes main.js; omitted_entry_count: 0 --outline-depth 1 --json without --detail summary: exit 1 code: invalid_request message: --outline-depth requires --detail summary ``` ### Typed outcome or recovery expected The exported schema should exclude negative outline depths. Keep the existing `VALIDATION_ERROR` for -1 and the `invalid_request` response when an outline depth is supplied without summary mode. Keep successful `HistoricalSourceSummary` results for depths 0 and 1 with their current outline contents. These controls prevent a repair that merely weakens runtime validation. ### Analysis or suspected cause Source-derived at the verified baseline: `src/cli/utilityCommands.ts:252-260` declares `outlineDepth` with `.number().int().nonnegative().safe().optional()`. `src/cli/utilityCommands.ts:268-283` enforces the summary-mode requirement. The independent verifier also converted the same number constraints through the installed Incur-exported Zod and reproduced the negative schema minimum while runtime parsing rejected -1 and accepted 0. Source inspection of the installed Zod implementation supports a metadata-overwrite explanation in its number-format check and JSON Schema conversion. This causal explanation is separate from the public CLI reproduction and has not been verified by a repair. ### Additional context Related closed issue [#1169](https://github.com/morluto/rea/issues/1169) concerns defaulted inputs marked required, and closed feature [#2442](https://github.com/morluto/rea/issues/2442) introduced summaries; this report concerns the advertised numeric minimum for the existing outline-depth option. P2 is supported because a machine-readable argument contract admits a request that fails validation, with a demonstrated safe workaround and successful nonnegative controls.
bsakaguchi 2026-10-15 18:31:31 +00:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@gongfpp commented on GitHub (Oct 14, 2026):

Planning to fix this.

The published schema and the parser diverge because the chain states .nonnegative() before .safe(). Zod's .safe() carries the safe-integer range and replaces the lower bound, so z.toJSONSchema emits minimum: -9007199254740991; the parser applies both checks, so it still rejects -1.

Reordering to .safe().nonnegative() publishes minimum: 0 with the unchanged maximum: 9007199254740991 and leaves parsed values identical. The same ordering in LinuxPrivateDisplayDiagnostic's xvfb_stderr_bytes carries the identical loss, so I am correcting it in the same change.

<!-- gh-comment-id:6161795825 --> @gongfpp commented on GitHub (Oct 14, 2026): Planning to fix this. The published schema and the parser diverge because the chain states `.nonnegative()` before `.safe()`. Zod's `.safe()` carries the safe-integer range and replaces the lower bound, so `z.toJSONSchema` emits `minimum: -9007199254740991`; the parser applies both checks, so it still rejects `-1`. Reordering to `.safe().nonnegative()` publishes `minimum: 0` with the unchanged `maximum: 9007199254740991` and leaves parsed values identical. The same ordering in `LinuxPrivateDisplayDiagnostic`'s `xvfb_stderr_bytes` carries the identical loss, so I am correcting it in the same change.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1147
No description provided.