[GH-ISSUE #8587] [Design] Page retained native procedure-reference observations #6660

Open
opened 2026-11-01 21:13:00 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @morluto on GitHub (Nov 1, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/8587

Before submitting

  • I searched the open and closed issues and pull requests for a related discussion.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This discussion does not include credentials, private samples, or sensitive target data.

Decision needed

How should an analyst inspect a bounded portion of a completed native procedure_references result without transferring every row, while preserving reference identity, procedure-body coverage, provider provenance and complete Evidence?

Context and evidence

On REA #8585 head 2a0415cd5, real Ghidra 12.1.4/JDK 21 and stdio MCP on macOS arm64, I analyzed two source-built, unexecuted arm64 Mach-O executables. Each has one audit_target and an array of pointers statically initialized to it; the array sizes below deliberately stress output volume.

  • In the compact profile at 3,000 slots, procedure_references with direction: incoming returned 3,001 references in a 5,434,853-byte SDK-serialized response. Each row included the target procedure identity. inspect_native_instruction at the entry returned 3,001 typed incoming references in 1,737,893 bytes; xrefs returned 3,001 addresses in 97,431 bytes.
  • In both compact and full profiles at 8,000 slots, procedure_references completed but exceeded the default 10 MiB MCP response budget, returning the retained Evidence ID. An exact one-record get_evidence_bundle request also exceeded the budget; inspect_analysis_view rejected that record as an unsupported parent. Exporting the retained bundle succeeded and its 9,061,620-byte JSON contained the procedure-reference record with 8,001 rows. inspect_native_instruction at the entry succeeded with 8,001 incoming rows (4,617,885 serialized SDK bytes), and xrefs returned 8,001 addresses (247,423 bytes).

The instruction alternative is narrower: it reports references to one exact address, while procedure_references covers the complete Ghidra function-body AddressSet and entry. It therefore cannot generally replace the procedure query. An exported file is a working complete-data fallback. SDK-serialized sizes include text and structured representations and are not model-token or latency measurements. These fixtures establish neither typical volume nor general provider completeness. The 8,000-slot target SHA-256 206c08b323fb2a97004e13b40121560360b0ea426719a6c41f507142304e4ee1 was unchanged; no target was executed.

Expected interaction with targets

Read the caller-selected binary, launch the existing Ghidra analysis provider, and optionally write an explicitly selected local Evidence export. A retained view can operate without reopening the target.

Boundary details

Keep the exact parent Evidence ID, direction, source and target addresses, source procedure/unknown state, provider-specific reference kinds, body coverage, source ordering and duplicates. A page does not establish discovery completeness or runtime execution. Preserve full raw Evidence and caller-selected detail.

Options and tradeoffs

Compare a summary and paged inspect_analysis_view for existing retained procedure_references with a task-oriented query that can select source/target or kind. Avoid repeating unchanged procedure identity per row in the compact view if it can be represented once without losing identity. Distinguish separately scoped xrefs (#8549) and native feature-trace pages (#8585); neither currently pages this retained procedure result. Account for per-record and allocation bounds, output schemas and offline import/export.

Verification available so far

I have a prototype or observed results.

Success criteria and open questions

Exercise empty, multi-range function bodies, interior targets, duplicates, data/instruction/indirect references, exact filters, page boundaries, full and compact MCP profiles, CLI and target-free export/import. Check both existing provider semantics and coverage limitations. The observed large control used one host and both schema profiles; no autonomous agent or latency study was performed.

References

Related #8549 (xrefs view recovery), #8348 and #8510 (Kuna reference provenance), #8373 and #8585 (bounded feature-trace delivery).

cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0

Reversible compact-row experiment

A standalone projection of the real 8,001-row incoming Evidence replaces a row's endpoint procedure with an explicit selected-procedure reference only when its complete procedure object equals the query's procedure; null and other procedure objects have distinct representations. All 8,001 rows reconstructed exactly with their original indices, endpoints, kinds and optional fields. All 8,001 target procedures matched the selected procedure; all source procedures were null. For the first 64 rows, minified JSON holding the selected procedure and rows was 54,779 bytes / approximately 17,115 tokenx-estimated tokens with complete endpoint objects versus 28,977 bytes / approximately 8,923 estimated tokens with the explicit references. These are one offline shape comparison, not an MCP task, actual model billing or an elapsed-time/CPU/memory measurement.

As an outgoing control, a real Ghidra full-profile MCP query of a separate unexecuted fixture returned five references: every source procedure matched the selected procedure, one target was a different resolved procedure, and the others had no target procedure. The same encode/decode rule reconstructed all five rows, including stack address spaces and static read/write/call kinds. Neither fixture changed. This is not an implemented contract: define explicit null/unknown semantics, multiple collections including unresolved_calls, filters and page coverage before adoption; compare decoding complexity, full task costs, oversized single rows and source Evidence retention. More providers, complex bodies, duplicate/mixed kinds, and autonomous-agent use remain unverified.

Unmerged retained-view prototype

An isolated prototype based on main 6d60db195 adds opt-in detail: summary to procedure_references and retained pages for references and unresolved calls. Endpoint procedures are explicitly selected-procedure, null, or inline; a row retains its original source index and complete remaining edge fields. In real Ghidra 12.1.4 stdio MCP on the 8,000-slot fixture, both full and compact profiles returned 8,001 as the summary count. The SDK-serialized summary was 10,579 bytes; separate one-row first/last pages were 11,919 and 11,941 bytes, and decoding them matched the respective complete parent rows. Summary and page replies validated against each profile's advertised output schemas (Ajv 2020, strict and formats disabled). The target hash stayed unchanged and the target was not executed.

Separately, after importing the previously exported complete Ghidra bundle into fresh target-free servers, both profiles paged and exactly reconstructed all 8,001 original reference rows and reported the empty unresolved-call collection. These observations are from an unmerged local prototype, not shipped support. It currently lacks kind filters, public CLI summary delivery, oversized-row boundary tests, documentation and general provider verification. SDK serialized bytes are not model-token or full-task performance measurements; no latency, CPU or memory comparison is claimed.

The prototype now also accepts exact source and target address filters. In both MCP profiles, an offline page filtered by a real Ghidra source/target pair returned the original source index 4,321. A live Ghidra outgoing control reconstructed all five edges, including one different resolved target. A synthetic public MCP boundary control preserved duplicate indices 0 and 2, paged a nonempty unresolved-call collection, and rejected endpoint filters on that collection. The canonical result schema and full advertised output schema reject a page whose collection and rows disagree; the deliberately reduced compact output advertisement accepts that malformed shape, while server-side canonical validation remains in force. A focused two-profile MCP test covering offline handoff and these distinctions passed. These controls are still from an unmerged prototype; real unresolved computed calls, CLI, large single rows and other providers remain unverified.

One-shot CLI and source closure experiment

A separate unmerged prototype stacked on #8585 adds rea procedure-references <path> <procedure> --direction incoming|outgoing --detail summary --evidence_output <path>. On a real Ghidra 12.1.4 existing-project fixture, the summary and saved bundle contained five outgoing rows and retained the linked historical-project health Evidence; a later target-free CLI inspect-analysis-view returned the first two rows from that bundle. A second invocation using the same snapshot returned the same trace and linked history, but this project produced no snapshot replay entries: it re-observed the provider and is not a replay control. Kuna 1.988 returned capability_unavailable for the same command and did not create an output bundle. The target was not executed.

Focused CLI/MCP boundary tests passed for source closure, missing-source refusal without publication, and offline page handoff. The new command reuses #8585's source-closure delivery boundary; it is exploratory and not an independent shipped implementation. CLI command naming/discoverability, large or oversized individual rows, additional provider coverage, complete/summary parity, cancellation/finalization and documentation remain open.

Real noncontiguous body and interior-target control

On the unmerged prototype stacked on #8585, I built an arm64 Mach-O with three pointer slots targeting a function's entry, entry+4 and entry+8. I imported it into a separate test-owned Ghidra 12.1.4 project and used a headless Java script to set that function's body to two disjoint ranges, 0x100000370..373 and 0x100000378..383. The script modified the test project's analysis database; it did not modify or execute the target binary. In both full and compact real stdio MCP profiles, procedure_references(direction: incoming) returned the entry reference and the entry+8 interior reference, and excluded the entry+4 gap reference. Exact xrefs(0x100000374) independently returned the gap's slot. The filtered native-procedure-references page for target_address: 0x100000378 returned the interior slot with its original source index, and its summary retained both noncontiguous body ranges. The original executable SHA-256 8d5c1b54cb27c8ed68ac16feb6ee635244c520ee22433c92f31236dcd91c7ad4 was unchanged. This exercises one deliberately edited Ghidra database on one host, not naturally recovered body correctness, all address spaces, or general provider coverage.

Real unresolved-call paging control

On the unmerged stacked prototype, real Ghidra 12.1.4 analyzed a source-built arm64 Mach-O whose audit_indirect calls two function-pointer arguments. Independent otool disassembly identifies blr at 0x100000348 and 0x100000358. In both full and compact stdio MCP profiles, the complete outgoing procedure-reference result reported those two sites as unresolved because its instruction decoder found calls without ReferenceManager call destinations. Opt-in summary preserved the same parent ID and count; one-row unresolved-call pages reconstructed both original addresses and reasons, and the replies validated against the respective advertised output schemas (Ajv 2020, strict and formats disabled). The target was unchanged (SHA-256 a34f95f4fdea0952ee60436e7399eb92af79c1a50fdd8552e9dcdab87b3e919d) and not executed.

The CLI prototype also saved that result, then inspect-analysis-view selected the second unresolved row from its Evidence bundle in a separate process without reopening Ghidra. This is one unexecuted binary on one host; no conclusion about runtime call targets, other indirect-call shapes, or exhaustive unresolved coverage follows.

Representative complete task measurement

On the source-built 3,000-slot fixture, real Ghidra 12.1.4 and compact stdio MCP on macOS arm64, I compared selecting the first and last incoming procedure-reference rows from the complete response on #8585 2a0415cd5 against one summary plus two one-row pages on the unmerged stacked prototype. The selected original rows reconstructed identically. One cold and one warm measurement were taken per mode in separate sessions, with analysis-server startup and catalog transfer time excluded; the target was unchanged and not executed.

Measurement Complete, 1 call Summary + pages, 3 calls
Tokenx estimate for serialized SDK requests and replies 1,902,437 9,874
Cold / warm elapsed seconds 3.999 / 0.316 4.031 / 0.268
Cold / warm sampled process-family CPU seconds 7.52 / 0.42 7.66 / 0.59
Cold / warm sampled peak process-family RSS MiB 989.6 / 982.2 966.8 / 1006.4
Additional full compact-catalog tokenx estimate 161,639 161,760

The SDK serialization includes both text and structured representations and may double-count content; tokenx is an estimate, not actual model usage or billing. Process-family ps samples were taken every 100 ms; short-lived peaks can be missed. The one-run samples do not establish general timing, CPU or memory improvement. Both modes still construct and retain the complete source result, and a task that needs every row would incur more calls. The measurement excludes connection startup, catalog transfer time, and unmeasured client costs.

Bounded page construction and oversized-row recovery

A synthetic bundle repeated the real 8,001-row Ghidra result three times (24,003 rows). The initial prototype constructed the entire requested page and then received the 10 MiB MCP response error; a one-row retry still worked. A subsequent unmerged revision uses the existing 1,048,576-byte analysis-view projection allowance before adding each row. In full and compact MCP profiles, a request for all rows returned a byte-limited page with next_offset: 2344 and total: 24003; eleven pages reconstructed all original rows and indices, with ten byte-limited pages. The first replies validated against each advertised output schema. The fixed projection allowance is separate from the 10 MiB transport limit and has no runtime override; its byte count is for the projection, not the entire SDK response.

A second synthetic source used one 1.1-million-character endpoint procedure name. In both profiles, that one-row view returned resource_constraint with its parent Evidence ID and the projection allowance, while an unresolved-call page from the same retained parent still succeeded. Focused MCP tests cover continuation and this recovery. These are explicit synthetic resource controls, not claims that Ghidra generated such names or that total process memory is bounded by the page allowance. The parent result and parsing/retention costs remain separate; no performance benchmark was performed for this revision.

Originally created by @morluto on GitHub (Nov 1, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8587 ### Before submitting - [x] I searched the open and closed issues and pull requests for a related discussion. - [x] I understand the contribution scope must be reviewed before integration; open questions are welcome here. - [x] This discussion does not include credentials, private samples, or sensitive target data. ### Decision needed How should an analyst inspect a bounded portion of a completed native `procedure_references` result without transferring every row, while preserving reference identity, procedure-body coverage, provider provenance and complete Evidence? ### Context and evidence On REA #8585 head `2a0415cd5`, real Ghidra 12.1.4/JDK 21 and stdio MCP on macOS arm64, I analyzed two source-built, unexecuted arm64 Mach-O executables. Each has one `audit_target` and an array of pointers statically initialized to it; the array sizes below deliberately stress output volume. - In the compact profile at 3,000 slots, `procedure_references` with `direction: incoming` returned 3,001 references in a 5,434,853-byte SDK-serialized response. Each row included the target procedure identity. `inspect_native_instruction` at the entry returned 3,001 typed incoming references in 1,737,893 bytes; `xrefs` returned 3,001 addresses in 97,431 bytes. - In both compact and full profiles at 8,000 slots, `procedure_references` completed but exceeded the default 10 MiB MCP response budget, returning the retained Evidence ID. An exact one-record `get_evidence_bundle` request also exceeded the budget; `inspect_analysis_view` rejected that record as an unsupported parent. Exporting the retained bundle succeeded and its 9,061,620-byte JSON contained the procedure-reference record with 8,001 rows. `inspect_native_instruction` at the entry succeeded with 8,001 incoming rows (4,617,885 serialized SDK bytes), and `xrefs` returned 8,001 addresses (247,423 bytes). The instruction alternative is narrower: it reports references to one exact address, while `procedure_references` covers the complete Ghidra function-body AddressSet and entry. It therefore cannot generally replace the procedure query. An exported file is a working complete-data fallback. SDK-serialized sizes include text and structured representations and are not model-token or latency measurements. These fixtures establish neither typical volume nor general provider completeness. The 8,000-slot target SHA-256 `206c08b323fb2a97004e13b40121560360b0ea426719a6c41f507142304e4ee1` was unchanged; no target was executed. ### Expected interaction with targets Read the caller-selected binary, launch the existing Ghidra analysis provider, and optionally write an explicitly selected local Evidence export. A retained view can operate without reopening the target. ### Boundary details Keep the exact parent Evidence ID, direction, source and target addresses, source procedure/unknown state, provider-specific reference kinds, body coverage, source ordering and duplicates. A page does not establish discovery completeness or runtime execution. Preserve full raw Evidence and caller-selected detail. ### Options and tradeoffs Compare a summary and paged `inspect_analysis_view` for existing retained `procedure_references` with a task-oriented query that can select source/target or kind. Avoid repeating unchanged procedure identity per row in the compact view if it can be represented once without losing identity. Distinguish separately scoped `xrefs` (#8549) and native feature-trace pages (#8585); neither currently pages this retained procedure result. Account for per-record and allocation bounds, output schemas and offline import/export. ### Verification available so far I have a prototype or observed results. ### Success criteria and open questions Exercise empty, multi-range function bodies, interior targets, duplicates, data/instruction/indirect references, exact filters, page boundaries, full and compact MCP profiles, CLI and target-free export/import. Check both existing provider semantics and coverage limitations. The observed large control used one host and both schema profiles; no autonomous agent or latency study was performed. ### References Related #8549 (xrefs view recovery), #8348 and #8510 (Kuna reference provenance), #8373 and #8585 (bounded feature-trace delivery). cc @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 ### Reversible compact-row experiment A standalone projection of the real 8,001-row incoming Evidence replaces a row's endpoint procedure with an explicit `selected-procedure` reference only when its complete procedure object equals the query's procedure; `null` and other procedure objects have distinct representations. All 8,001 rows reconstructed exactly with their original indices, endpoints, kinds and optional fields. All 8,001 target procedures matched the selected procedure; all source procedures were null. For the first 64 rows, minified JSON holding the selected procedure and rows was 54,779 bytes / approximately 17,115 tokenx-estimated tokens with complete endpoint objects versus 28,977 bytes / approximately 8,923 estimated tokens with the explicit references. These are one offline shape comparison, not an MCP task, actual model billing or an elapsed-time/CPU/memory measurement. As an outgoing control, a real Ghidra full-profile MCP query of a separate unexecuted fixture returned five references: every source procedure matched the selected procedure, one target was a different resolved procedure, and the others had no target procedure. The same encode/decode rule reconstructed all five rows, including stack address spaces and static read/write/call kinds. Neither fixture changed. This is not an implemented contract: define explicit null/unknown semantics, multiple collections including `unresolved_calls`, filters and page coverage before adoption; compare decoding complexity, full task costs, oversized single rows and source Evidence retention. More providers, complex bodies, duplicate/mixed kinds, and autonomous-agent use remain unverified. ### Unmerged retained-view prototype An isolated prototype based on main `6d60db195` adds opt-in `detail: summary` to `procedure_references` and retained pages for references and unresolved calls. Endpoint procedures are explicitly `selected-procedure`, `null`, or `inline`; a row retains its original source index and complete remaining edge fields. In real Ghidra 12.1.4 stdio MCP on the 8,000-slot fixture, both full and compact profiles returned 8,001 as the summary count. The SDK-serialized summary was 10,579 bytes; separate one-row first/last pages were 11,919 and 11,941 bytes, and decoding them matched the respective complete parent rows. Summary and page replies validated against each profile's advertised output schemas (Ajv 2020, strict and formats disabled). The target hash stayed unchanged and the target was not executed. Separately, after importing the previously exported complete Ghidra bundle into fresh target-free servers, both profiles paged and exactly reconstructed all 8,001 original reference rows and reported the empty unresolved-call collection. These observations are from an unmerged local prototype, not shipped support. It currently lacks kind filters, public CLI summary delivery, oversized-row boundary tests, documentation and general provider verification. SDK serialized bytes are not model-token or full-task performance measurements; no latency, CPU or memory comparison is claimed. The prototype now also accepts exact source and target address filters. In both MCP profiles, an offline page filtered by a real Ghidra source/target pair returned the original source index 4,321. A live Ghidra outgoing control reconstructed all five edges, including one different resolved target. A synthetic public MCP boundary control preserved duplicate indices 0 and 2, paged a nonempty unresolved-call collection, and rejected endpoint filters on that collection. The canonical result schema and full advertised output schema reject a page whose collection and rows disagree; the deliberately reduced compact output advertisement accepts that malformed shape, while server-side canonical validation remains in force. A focused two-profile MCP test covering offline handoff and these distinctions passed. These controls are still from an unmerged prototype; real unresolved computed calls, CLI, large single rows and other providers remain unverified. ### One-shot CLI and source closure experiment A separate unmerged prototype stacked on #8585 adds `rea procedure-references <path> <procedure> --direction incoming|outgoing --detail summary --evidence_output <path>`. On a real Ghidra 12.1.4 existing-project fixture, the summary and saved bundle contained five outgoing rows and retained the linked historical-project `health` Evidence; a later target-free CLI `inspect-analysis-view` returned the first two rows from that bundle. A second invocation using the same snapshot returned the same trace and linked history, but this project produced no snapshot replay entries: it re-observed the provider and is not a replay control. Kuna 1.988 returned `capability_unavailable` for the same command and did not create an output bundle. The target was not executed. Focused CLI/MCP boundary tests passed for source closure, missing-source refusal without publication, and offline page handoff. The new command reuses #8585's source-closure delivery boundary; it is exploratory and not an independent shipped implementation. CLI command naming/discoverability, large or oversized individual rows, additional provider coverage, complete/summary parity, cancellation/finalization and documentation remain open. ### Real noncontiguous body and interior-target control On the unmerged prototype stacked on #8585, I built an arm64 Mach-O with three pointer slots targeting a function's entry, entry+4 and entry+8. I imported it into a separate test-owned Ghidra 12.1.4 project and used a headless Java script to set that function's body to two disjoint ranges, `0x100000370..373` and `0x100000378..383`. The script modified the test project's analysis database; it did not modify or execute the target binary. In both full and compact real stdio MCP profiles, `procedure_references(direction: incoming)` returned the entry reference and the entry+8 interior reference, and excluded the entry+4 gap reference. Exact `xrefs(0x100000374)` independently returned the gap's slot. The filtered `native-procedure-references` page for `target_address: 0x100000378` returned the interior slot with its original source index, and its summary retained both noncontiguous body ranges. The original executable SHA-256 `8d5c1b54cb27c8ed68ac16feb6ee635244c520ee22433c92f31236dcd91c7ad4` was unchanged. This exercises one deliberately edited Ghidra database on one host, not naturally recovered body correctness, all address spaces, or general provider coverage. ### Real unresolved-call paging control On the unmerged stacked prototype, real Ghidra 12.1.4 analyzed a source-built arm64 Mach-O whose `audit_indirect` calls two function-pointer arguments. Independent `otool` disassembly identifies `blr` at `0x100000348` and `0x100000358`. In both full and compact stdio MCP profiles, the complete outgoing procedure-reference result reported those two sites as unresolved because its instruction decoder found calls without ReferenceManager call destinations. Opt-in summary preserved the same parent ID and count; one-row unresolved-call pages reconstructed both original addresses and reasons, and the replies validated against the respective advertised output schemas (Ajv 2020, strict and formats disabled). The target was unchanged (SHA-256 `a34f95f4fdea0952ee60436e7399eb92af79c1a50fdd8552e9dcdab87b3e919d`) and not executed. The CLI prototype also saved that result, then `inspect-analysis-view` selected the second unresolved row from its Evidence bundle in a separate process without reopening Ghidra. This is one unexecuted binary on one host; no conclusion about runtime call targets, other indirect-call shapes, or exhaustive unresolved coverage follows. ### Representative complete task measurement On the source-built 3,000-slot fixture, real Ghidra 12.1.4 and compact stdio MCP on macOS arm64, I compared selecting the first and last incoming procedure-reference rows from the complete response on #8585 `2a0415cd5` against one summary plus two one-row pages on the unmerged stacked prototype. The selected original rows reconstructed identically. One cold and one warm measurement were taken per mode in separate sessions, with analysis-server startup and catalog transfer time excluded; the target was unchanged and not executed. | Measurement | Complete, 1 call | Summary + pages, 3 calls | |---|---:|---:| | Tokenx estimate for serialized SDK requests and replies | 1,902,437 | 9,874 | | Cold / warm elapsed seconds | 3.999 / 0.316 | 4.031 / 0.268 | | Cold / warm sampled process-family CPU seconds | 7.52 / 0.42 | 7.66 / 0.59 | | Cold / warm sampled peak process-family RSS MiB | 989.6 / 982.2 | 966.8 / 1006.4 | | Additional full compact-catalog tokenx estimate | 161,639 | 161,760 | The SDK serialization includes both text and structured representations and may double-count content; tokenx is an estimate, not actual model usage or billing. Process-family `ps` samples were taken every 100 ms; short-lived peaks can be missed. The one-run samples do not establish general timing, CPU or memory improvement. Both modes still construct and retain the complete source result, and a task that needs every row would incur more calls. The measurement excludes connection startup, catalog transfer time, and unmeasured client costs. ### Bounded page construction and oversized-row recovery A synthetic bundle repeated the real 8,001-row Ghidra result three times (24,003 rows). The initial prototype constructed the entire requested page and then received the 10 MiB MCP response error; a one-row retry still worked. A subsequent unmerged revision uses the existing 1,048,576-byte analysis-view projection allowance before adding each row. In full and compact MCP profiles, a request for all rows returned a byte-limited page with `next_offset: 2344` and `total: 24003`; eleven pages reconstructed all original rows and indices, with ten byte-limited pages. The first replies validated against each advertised output schema. The fixed projection allowance is separate from the 10 MiB transport limit and has no runtime override; its byte count is for the projection, not the entire SDK response. A second synthetic source used one 1.1-million-character endpoint procedure name. In both profiles, that one-row view returned `resource_constraint` with its parent Evidence ID and the projection allowance, while an unresolved-call page from the same retained parent still succeeded. Focused MCP tests cover continuation and this recovery. These are explicit synthetic resource controls, not claims that Ghidra generated such names or that total process memory is bounded by the page allowance. The parent result and parsing/retention costs remain separate; no performance benchmark was performed for this revision.
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#6660
No description provided.