[PR #6495] [MERGED] fix(entropy): name offset when the byte window starts past EOF #7368

Closed
opened 2026-11-01 21:47:21 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/6495
Author: @Abelo9996
Created: 10/23/2026
Status: ✅ Merged
Merged: 10/23/2026
Merged by: @baron

Base: main ← Head: fix-6482-byte-entropy-offset-error


📝 Commits (1)

  • 60b07b2 fix(entropy): name offset when the byte window starts past EOF

📊 Changes

3 files changed (+23 additions, -2 deletions)

View changed files

📝 docs/user-visible-errors.csv (+1 -1)
📝 src/application/binaryDiagnostics/ByteEntropyService.test.ts (+16 -0)
📝 src/application/binaryDiagnostics/ByteEntropyService.ts (+6 -1)

📄 Description

Summary

Fixes #6482.

inspect-byte-entropy correctly refused a window whose offset is past the end of the file, but the correction issue named length, even when length was omitted. The remediation tells the caller to correct the listed fields, so a caller following it would change the wrong selector (setting --length 0 still fails). An offset past EOF now reports ["offset"]. An in-file offset with an overlong explicit length still reports ["length"], and the accepted window contract is unchanged.

Problem and expected behavior

In ByteEntropyService.inspect, the omitted length is computed as size - offset, and a single check covers both cases:

const length = input.length ?? size - input.offset;
if (input.offset > size || length > size - input.offset)
  throw invalid("length", "Selected byte window extends beyond the end of the file.");

So on a 1,024-byte file, --offset 2048 (with or without --length 0) is blamed on length. Expected: the same invalid_request refusal and recovery, with the issue naming offset, since that is the only selector whose change can make the request valid.

Change and scope

Split the check. offset > size is tested first and reports offset with the message "Selected byte window starts beyond the end of the file." The remaining length > size - offset check keeps its existing length issue and message. offset == size still yields an empty window, as documented in docs/binary-diagnostics.md. I added the new message to the entropy row in docs/user-visible-errors.csv.

Follow the contribution scope.
Scope decision: not applicable (ordinary fix within existing boundaries).

Contract and boundary impact

  • Semantic owner and earliest changed stage: ByteEntropyService.inspect, window validation after the file is opened and sized.
  • Contribution scope fit and linked maintainer decision: ordinary bug fix, not applicable.
  • CLI and MCP/tool-catalog contract: no schema change. For an offset past EOF, details.issues[0].path is now ["offset"] with a new message; code, category, recovery and exit status are unchanged.
  • Provider, bridge, target-format, or platform compatibility: none.
  • Evidence, artifact, provenance, or reconstruction contract: none. Accepted windows produce the same Evidence.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): unchanged. The refusal still happens before the scan, inside the same file handle scope.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact (CI generates and validates ignored catalogs and skills/; edit authored instructions in .agents/skills/reverse-engineer-anything/ and never commit build outputs): none. docs/user-visible-errors.csv gains the new message.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

(Diagnostic metadata only; the file reads the tool already does are unchanged.)

Evidence and regression coverage

  • Tests added or updated: src/application/binaryDiagnostics/ByteEntropyService.test.ts gets an it.each over a 1,024-byte file that projects the error and checks the issue path: { offset: 2048 } and { offset: 2048, length: 0 } expect offset, { offset: 512, length: 1024 } expects length. The existing test still covers the empty window at EOF.

  • Base reproduction (executed): with the test and without the fix:

    × names the selector that puts { offset: 2048 } past EOF
    × names the selector that puts { offset: 2048, length: 0 } past EOF
    ✓ names the selector that puts { offset: 512, length: 1024 } past EOF
    -           "offset",
    +           "length",
          Tests  2 failed | 16 passed | 1 skipped (19)
    

    With the fix: Tests 18 passed | 1 skipped (19).

  • User-visible CLI/MCP output (if applicable): the issue's commands against a freshly compiled runtime (scripts/rea.mjs ... --json, fixture is bytes 0..255 repeated four times), trimmed to code and details for errors and window plus block count for successes.

    Before:

    $ rea inspect-byte-entropy window.bin --offset 2048 --json
    {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["length"], "reason": "invalid_value", "message": "Selected byte window extends beyond the end of the file."}]}}
    exit=1
    $ rea inspect-byte-entropy window.bin --offset 2048 --length 0 --json
    {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["length"], "reason": "invalid_value", "message": "Selected byte window extends beyond the end of the file."}]}}
    exit=1
    $ rea inspect-byte-entropy window.bin --offset 512 --length 1024 --json
    {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["length"], "reason": "invalid_value", "message": "Selected byte window extends beyond the end of the file."}]}}
    exit=1
    $ rea inspect-byte-entropy window.bin --offset 1024 --json
    {"window": {"offset": 1024, "length": 0}, "blocks": 0}
    exit=0
    $ rea inspect-byte-entropy window.bin --offset 512 --json
    {"window": {"offset": 512, "length": 512}, "blocks": 1}
    exit=0
    

    After:

    $ rea inspect-byte-entropy window.bin --offset 2048 --json
    {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["offset"], "reason": "invalid_value", "message": "Selected byte window starts beyond the end of the file."}]}}
    exit=1
    $ rea inspect-byte-entropy window.bin --offset 2048 --length 0 --json
    {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["offset"], "reason": "invalid_value", "message": "Selected byte window starts beyond the end of the file."}]}}
    exit=1
    $ rea inspect-byte-entropy window.bin --offset 512 --length 1024 --json
    {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["length"], "reason": "invalid_value", "message": "Selected byte window extends beyond the end of the file."}]}}
    exit=1
    $ rea inspect-byte-entropy window.bin --offset 1024 --json
    {"window": {"offset": 1024, "length": 0}, "blocks": 0}
    exit=0
    $ rea inspect-byte-entropy window.bin --offset 512 --json
    {"window": {"offset": 512, "length": 512}, "blocks": 1}
    exit=0
    
  • Remaining proof gaps: MCP transport was not run by hand; it shares the same service and error projection, and tests/boundary/mcp/binaryDiagnosticsMcp.test.ts passes. macOS only.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

Run with the pinned Node 24.18.0 on macOS arm64.

  • npm run test:focused -- src/application/binaryDiagnostics/ByteEntropyService.test.ts: 18 passed, 1 skipped (2 failed without the fix, shown above)
  • npm run test:focused -- src/application/binaryDiagnostics/ByteEntropyService.test.ts tests/boundary/mcp/binaryDiagnosticsMcp.test.ts src/contracts/native/binaryDiagnosticsToolContracts.test.ts src/domain/native/byteEntropy.test.ts src/main/messages.test.ts: 5 files, 29 passed, 1 skipped
  • npm run check tasks run individually: typecheck, lint:built (0 errors), knip, metadata:check and verify:architecture-guards passed. format:check was run as oxfmt --check on the changed files (clean), because the repo-wide run in my checkout also picks up unrelated untracked local notes.
  • npm run compile, then the CLI commands above.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. A client that keyed on ["length"] for an offset past EOF will now see ["offset"], which is the documented intent of the issue list.
  • Real Hopper/Ghidra, browser, or OS coverage: macOS only; no engine involved.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: no new data in the error; the offset value is not echoed.

Author readiness

Human owner: @Abelo9996

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/6495 **Author:** [@Abelo9996](https://github.com/Abelo9996) **Created:** 10/23/2026 **Status:** ✅ Merged **Merged:** 10/23/2026 **Merged by:** [@baron](https://github.com/baron) **Base:** `main` ← **Head:** `fix-6482-byte-entropy-offset-error` --- ### 📝 Commits (1) - [`60b07b2`](https://github.com/morluto/rea/commit/60b07b2db0190733a64d4ac56c628fa1d46f3191) fix(entropy): name offset when the byte window starts past EOF ### 📊 Changes **3 files changed** (+23 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `docs/user-visible-errors.csv` (+1 -1) 📝 `src/application/binaryDiagnostics/ByteEntropyService.test.ts` (+16 -0) 📝 `src/application/binaryDiagnostics/ByteEntropyService.ts` (+6 -1) </details> ### 📄 Description ## Summary Fixes #6482. `inspect-byte-entropy` correctly refused a window whose `offset` is past the end of the file, but the correction issue named `length`, even when `length` was omitted. The remediation tells the caller to correct the listed fields, so a caller following it would change the wrong selector (setting `--length 0` still fails). An offset past EOF now reports `["offset"]`. An in-file offset with an overlong explicit length still reports `["length"]`, and the accepted window contract is unchanged. ## Problem and expected behavior In `ByteEntropyService.inspect`, the omitted length is computed as `size - offset`, and a single check covers both cases: ```ts const length = input.length ?? size - input.offset; if (input.offset > size || length > size - input.offset) throw invalid("length", "Selected byte window extends beyond the end of the file."); ``` So on a 1,024-byte file, `--offset 2048` (with or without `--length 0`) is blamed on `length`. Expected: the same `invalid_request` refusal and recovery, with the issue naming `offset`, since that is the only selector whose change can make the request valid. ## Change and scope Split the check. `offset > size` is tested first and reports `offset` with the message "Selected byte window starts beyond the end of the file." The remaining `length > size - offset` check keeps its existing `length` issue and message. `offset == size` still yields an empty window, as documented in `docs/binary-diagnostics.md`. I added the new message to the entropy row in `docs/user-visible-errors.csv`. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). Scope decision: not applicable (ordinary fix within existing boundaries). ## Contract and boundary impact - Semantic owner and earliest changed stage: `ByteEntropyService.inspect`, window validation after the file is opened and sized. - Contribution scope fit and linked maintainer decision: ordinary bug fix, not applicable. - CLI and MCP/tool-catalog contract: no schema change. For an offset past EOF, `details.issues[0].path` is now `["offset"]` with a new message; code, category, recovery and exit status are unchanged. - Provider, bridge, target-format, or platform compatibility: none. - Evidence, artifact, provenance, or reconstruction contract: none. Accepted windows produce the same Evidence. - Target selection, authority, upstream behavior, and cleanup details (if applicable): unchanged. The refusal still happens before the scan, inside the same file handle scope. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `.agents/skills/reverse-engineer-anything/` and never commit build outputs): none. `docs/user-visible-errors.csv` gains the new message. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [ ] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [x] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. (Diagnostic metadata only; the file reads the tool already does are unchanged.) ## Evidence and regression coverage - Tests added or updated: `src/application/binaryDiagnostics/ByteEntropyService.test.ts` gets an `it.each` over a 1,024-byte file that projects the error and checks the issue path: `{ offset: 2048 }` and `{ offset: 2048, length: 0 }` expect `offset`, `{ offset: 512, length: 1024 }` expects `length`. The existing test still covers the empty window at EOF. - Base reproduction (executed): with the test and without the fix: ``` × names the selector that puts { offset: 2048 } past EOF × names the selector that puts { offset: 2048, length: 0 } past EOF ✓ names the selector that puts { offset: 512, length: 1024 } past EOF - "offset", + "length", Tests 2 failed | 16 passed | 1 skipped (19) ``` With the fix: `Tests 18 passed | 1 skipped (19)`. - User-visible CLI/MCP output (if applicable): the issue's commands against a freshly compiled runtime (`scripts/rea.mjs ... --json`, fixture is bytes 0..255 repeated four times), trimmed to `code` and `details` for errors and `window` plus block count for successes. Before: ``` $ rea inspect-byte-entropy window.bin --offset 2048 --json {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["length"], "reason": "invalid_value", "message": "Selected byte window extends beyond the end of the file."}]}} exit=1 $ rea inspect-byte-entropy window.bin --offset 2048 --length 0 --json {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["length"], "reason": "invalid_value", "message": "Selected byte window extends beyond the end of the file."}]}} exit=1 $ rea inspect-byte-entropy window.bin --offset 512 --length 1024 --json {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["length"], "reason": "invalid_value", "message": "Selected byte window extends beyond the end of the file."}]}} exit=1 $ rea inspect-byte-entropy window.bin --offset 1024 --json {"window": {"offset": 1024, "length": 0}, "blocks": 0} exit=0 $ rea inspect-byte-entropy window.bin --offset 512 --json {"window": {"offset": 512, "length": 512}, "blocks": 1} exit=0 ``` After: ``` $ rea inspect-byte-entropy window.bin --offset 2048 --json {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["offset"], "reason": "invalid_value", "message": "Selected byte window starts beyond the end of the file."}]}} exit=1 $ rea inspect-byte-entropy window.bin --offset 2048 --length 0 --json {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["offset"], "reason": "invalid_value", "message": "Selected byte window starts beyond the end of the file."}]}} exit=1 $ rea inspect-byte-entropy window.bin --offset 512 --length 1024 --json {"code": "invalid_request", "details": {"operation": "inspect_byte_entropy", "issues": [{"path": ["length"], "reason": "invalid_value", "message": "Selected byte window extends beyond the end of the file."}]}} exit=1 $ rea inspect-byte-entropy window.bin --offset 1024 --json {"window": {"offset": 1024, "length": 0}, "blocks": 0} exit=0 $ rea inspect-byte-entropy window.bin --offset 512 --json {"window": {"offset": 512, "length": 512}, "blocks": 1} exit=0 ``` - Remaining proof gaps: MCP transport was not run by hand; it shares the same service and error projection, and `tests/boundary/mcp/binaryDiagnosticsMcp.test.ts` passes. macOS only. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed Run with the pinned Node 24.18.0 on macOS arm64. - `npm run test:focused -- src/application/binaryDiagnostics/ByteEntropyService.test.ts`: 18 passed, 1 skipped (2 failed without the fix, shown above) - `npm run test:focused -- src/application/binaryDiagnostics/ByteEntropyService.test.ts tests/boundary/mcp/binaryDiagnosticsMcp.test.ts src/contracts/native/binaryDiagnosticsToolContracts.test.ts src/domain/native/byteEntropy.test.ts src/main/messages.test.ts`: 5 files, 29 passed, 1 skipped - `npm run check` tasks run individually: `typecheck`, `lint:built` (0 errors), `knip`, `metadata:check` and `verify:architecture-guards` passed. `format:check` was run as `oxfmt --check` on the changed files (clean), because the repo-wide run in my checkout also picks up unrelated untracked local notes. - `npm run compile`, then the CLI commands above. ## Compatibility, safety, and release - Breaking changes or migration steps: none. A client that keyed on `["length"]` for an offset past EOF will now see `["offset"]`, which is the documented intent of the issue list. - Real Hopper/Ghidra, browser, or OS coverage: macOS only; no engine involved. - Package or release metadata impact: none. - Security, privacy, process, or containment review: no new data in the error; the offset value is not echoed. ## Author readiness Human owner: @Abelo9996 - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:47:21 +00:00
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#7368
No description provided.