[PR #7124] [MERGED] fix(cli): report JSON Lines selection refusals as caller errors #7657

Closed
opened 2026-11-03 13:39:25 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/7124
Author: @kaoru0822-kitauji
Created: 10/25/2026
Status: ✅ Merged
Merged: 10/25/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/7110-jsonl-shape-refusal


📝 Commits (2)

  • e1437ec fix(cli): report JSON Lines selection refusals as caller errors
  • f8d3f1f fix(cli): carry JSON Lines refusal facts as structured observations

📊 Changes

13 files changed (+516 additions, -95 deletions)

View changed files

📝 docs/cli.md (+8 -3)
📝 src/cli/cliResultOutput.ts (+1 -0)
📝 src/cli/jsonLines.ts (+208 -60)
📝 src/cli/jsonLinesOutput.ts (+5 -0)
📝 src/domain/analysisErrorCore.ts (+9 -1)
📝 src/domain/analysisErrorPresentation.ts (+4 -1)
📝 src/domain/analysisErrorProjection.ts (+1 -0)
📝 src/domain/explicitSensitiveFailure.ts (+3 -0)
📝 tests/acceptance/jsonLinesCli.test.ts (+94 -0)
📝 tests/acceptance/managedCliOutput.test.ts (+13 -2)
📝 tests/boundary/cli/javascriptApplicationJsonOutput.test.ts (+12 -3)
📝 tests/boundary/cli/jsonLinesOutput.test.ts (+157 -24)
📝 tests/boundary/cli/jsonOutput.test.ts (+1 -1)

📄 Description

What broke: a --format jsonl refusal of a selection that is not a record collection was reported as unreadable_output / execution_failure with "Run rea doctor", although the analysis succeeded (--format json exits 0).
Fix: the JSON Lines owner (src/cli/jsonLines.ts) now refuses with AnalysisInputError → invalid_request / invalid_input, naming the selection and its observed shape, and keeps the --format json / --filter-output remediation; docs say columnar SQLite rows are not a record collection.
Risk: low. The admission rules are unchanged and exit status stays 1. Only the error code, category and message change, so callers matching unreadable_output on JSONL refusals have to switch to invalid_request.

Summary

Fixes #7110.

When --format jsonl is refused, the cause is the caller's output selection, not the analysis. The refusal is now a typed caller error, so agents that branch on code/category no longer treat a successful analysis as failed, and they are no longer pointed at rea doctor.

Problem and expected behavior

Trigger (base bc143125e, built CLI):

sqlite3 t.sqlite 'create table configInts(name text primary key, value integer); insert into configInts values ("a",1),("b",2);'
rea inspect-sqlite-database t.sqlite --table configInts --format jsonl --filter-output normalized_result.rows   # exit 1
rea inspect-sqlite-database t.sqlite --table configInts --format json > /dev/null                                # exit 0

Before:

{"$rea":"jsonl/v1","type":"error","ok":false,"result":{"code":"unreadable_output","category":"execution_failure","message":"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.","retryable":false,"remediation":{"action":"Use --format json for the complete document, or select one record collection with --filter-output."},"details":{"operation":"inspect-sqlite-database","reason":"JSON Lines requires an array or one explicit rows, items, records, or occurrences collection."}}}

After:

{"$rea":"jsonl/v1","type":"error","ok":false,"result":{"code":"invalid_request","category":"invalid_input","message":"The --filter-output selection normalized_result.rows is not a JSON Lines record collection: normalized_result.rows is an object. JSON Lines needs a top-level array, or exactly one rows, items, records, or occurrences array directly in the result, under page, or under normalized_result.","retryable":false,"remediation":{"action":"Use --format json for the complete document, or select one record collection with --filter-output."},"recovery":{"kind":"inspect_input_contract","operation":"inspect-sqlite-database"},"details":{"operation":"inspect-sqlite-database","issues":[{"path":["filter-output"],"reason":"invalid_value","message":"The --filter-output selection normalized_result.rows is not a JSON Lines record collection: normalized_result.rows is an object.","observed":[{"path":["normalized_result","rows"],"shape":"object"}]}]}}}

Change and scope

  • src/cli/jsonLines.ts (owner of JSON Lines admission): all refusals (no collection, several collections, reserved $rea collision) are now AnalysisInputError. The issue path is ["filter-output"] when a filter was given and ["format"] otherwise. A single examineBoundaries walk over the documented boundaries (result, page, normalized_result, normalized_result.page) now produces both the admitted collections and the refusal facts. It replaces collections/documentCollections, so admission behavior is identical. The messages contain only fixed field names and the caller's own filter keys, never target data.
  • Each refused value is also reported as structured data in details.issues[].observed, as [{path, shape}] with shape one of absent|null|array|object|string|number|boolean. Callers can read the location and shape without parsing the message, and the message is built from these facts. AnalysisInputIssue gains this optional observed field: the error projection outputs it, and the sensitive-value redaction copy redacts it.
  • src/domain/analysisErrorCore.ts / analysisErrorPresentation.ts: AnalysisInputError takes an optional remediationAction, the same option AnalysisOutputError, AnalysisUnsupportedTargetError and others already have. Without it, the generic input-contract advice is unchanged.
  • src/cli/cliResultOutput.ts / jsonLinesOutput.ts: pass the already parsed --filter-output paths through, so the refusal can name the selection without parsing it again.
  • docs/cli.md: documents the caller-error classification. It also states that a columnar object such as inspect-sqlite-database --table's normalized_result.rows ({columns, values}) is not a record collection, and narrows the normalized_result.rows example to analysis views.

Intentionally not included:

  • Converting columnar {columns, values} into one object per row. Nothing else in the codebase reads SQLite rows that way, and duplicate column names are allowed (columns has no uniqueness constraint), so the conversion would be ambiguous. Use --format json for these results.
  • Admitting arbitrary nested arrays such as normalized_result.schema.tables or normalized_result.imports.items. The documented boundary rule is unchanged; these are now refused with a clear caller error.
  • JSON Lines is CLI-only. MCP has no JSONL path (mcp doctor renders a single document), so MCP is unaffected.

Contribution scope: ordinary fix within existing boundaries; maintainer scope decision not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: the CLI JSON Lines projection (prepareJsonLines), plus an additive option on the AnalysisInputError domain error. The superseded collections/documentCollections helpers were removed.

  • Contribution scope fit and linked maintainer decision: not applicable (bug fix).

  • CLI and MCP/tool-catalog contract: on the CLI, JSONL refusal records change code/category/message/details to the existing invalid_request projection. Exit status stays 1. MCP: none.

  • Provider, bridge, target-format, or platform compatibility: none.

  • Evidence, artifact, provenance, or reconstruction contract: none; successful JSONL records and metadata are unchanged.

  • Target selection, authority, upstream behavior, and cleanup details: not applicable.

  • Generated metadata, package, or installation impact: none (docs:check passes; the error schema already includes invalid_request).

  • Documentation or usability only; no target interaction.

Evidence and regression coverage

  • Tests added or updated:
    • tests/boundary/cli/jsonLinesOutput.test.ts: each refusal asserts the classification (invalid_request/invalid_input), the issue path/reason, the structured observed facts, and that the remediation equals the owning constant JSON_LINES_SELECTION_REMEDIATION. No explanatory prose is asserted. A mutation check confirmed the tests are sensitive to facts, not wording: rewording the message still passed (44/44), and reporting a wrong shape failed (2 failed). Cases covered:
      • an object with no collection, a scalar, null, and a nested array elsewhere
      • collection fields that are null, a number, or a columnar object
      • several collections, including a normalized_result.page collection
      • an inherited rows, and a $rea collision in both a collection and a top-level array
      • --full-output boundary paths, and filters that match nothing, a scalar, null, a nested array, a columnar object, several collections, or several non-collection paths
      • admission still works for top-level arrays and rows of primitives and arrays, empty top-level arrays (no lines), and empty collections (metadata only)
    • tests/acceptance/jsonLinesCli.test.ts: the real built CLI against a real SQLite database runs the issue's rows (default, --table … --filter-output normalized_result.rows, --filter-output normalized_result.schema.tables), asserting structured facts, with --json exiting 0. For both the non-empty and the empty analysis-view requests, it checks that the documented --filter-output normalized_result.rows export emits exactly the same rows as the unfiltered export.
    • Updated expectations: tests/acceptance/managedCliOutput.test.ts, tests/boundary/cli/javascriptApplicationJsonOutput.test.ts, tests/boundary/cli/jsonOutput.test.ts.
  • Base reproduction: all five rows of the issue's table reproduced on bc143125e through scripts/rea.mjs (each unreadable_output, exit 1). That includes inspect-macho /System/Applications/Calculator.app --filter-output 'normalized_result.imports.items[0,2]'. After the change all five return invalid_request / invalid_input with exit 1. Two examples of the new messages:
    • normalized_result.rows is null (no --table)
    • The --filter-output selection normalized_result.imports.items is not a JSON Lines record collection: it is an array outside a record collection boundary.
  • Remaining proof gaps: Windows/Linux not run locally (no platform-specific code touched).

Validation performed

  • Issue reproduction script (5 rows plus a --format json control) on the base build and the fixed build: the base gave unreadable_output on all 5 rows. The fixed build gives invalid_request on all 5 rows, and the --format json control exits 0.
  • npm run test:focused -- tests/boundary/cli/jsonLinesOutput.test.ts tests/boundary/cli/jsonOutput.test.ts tests/boundary/cli/filteredArrayOutput.test.ts tests/boundary/cli/cliOutput.test.ts tests/boundary/cli/javascriptApplicationJsonOutput.test.ts tests/acceptance/jsonLinesCli.test.ts tests/acceptance/managedCliOutput.test.ts src/domain/analysisErrorProjection.test.ts: 8 files, 270 tests passed. After the later describe split, jsonLinesOutput.test.ts was rerun: 44 passed.
  • After the review fixes: npm run test:focused on the same 8 files plus src/domain/explicitSensitiveFailure.test.ts: 9 files, 291 tests passed. The issue repro was rerun on the rebuilt CLI: all 5 rows return invalid_request with observed facts, and the --format json control exits 0.
  • npm run check:fast: passed.
  • npm run format:check: passed.
  • npm run docs:check: passed.

Compatibility, safety, and release

  • Breaking changes or migration steps: the error code of a JSONL refusal moves from unreadable_output to invalid_request (category execution_failure → invalid_input). This corrects a misclassification; scripts matching the old code should match invalid_request. Exit status and record framing are unchanged.
  • Real Hopper/Ghidra, browser, or OS coverage: macOS arm64 only; no provider involved.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: messages echo only fixed field names and the caller's own --filter-output keys, never target values.

Author readiness

Human owner: @kaoru0822-kitauji

  • 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.

🤖 Generated with Claude Code


🔄 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/7124 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/25/2026 **Status:** ✅ Merged **Merged:** 10/25/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/7110-jsonl-shape-refusal` --- ### 📝 Commits (2) - [`e1437ec`](https://github.com/morluto/rea/commit/e1437ec5b93fb71b5ff30a766baacda1e75873cb) fix(cli): report JSON Lines selection refusals as caller errors - [`f8d3f1f`](https://github.com/morluto/rea/commit/f8d3f1f8d780e6f1c4c8c93703ba8f33ee66e99d) fix(cli): carry JSON Lines refusal facts as structured observations ### 📊 Changes **13 files changed** (+516 additions, -95 deletions) <details> <summary>View changed files</summary> 📝 `docs/cli.md` (+8 -3) 📝 `src/cli/cliResultOutput.ts` (+1 -0) 📝 `src/cli/jsonLines.ts` (+208 -60) 📝 `src/cli/jsonLinesOutput.ts` (+5 -0) 📝 `src/domain/analysisErrorCore.ts` (+9 -1) 📝 `src/domain/analysisErrorPresentation.ts` (+4 -1) 📝 `src/domain/analysisErrorProjection.ts` (+1 -0) 📝 `src/domain/explicitSensitiveFailure.ts` (+3 -0) 📝 `tests/acceptance/jsonLinesCli.test.ts` (+94 -0) 📝 `tests/acceptance/managedCliOutput.test.ts` (+13 -2) 📝 `tests/boundary/cli/javascriptApplicationJsonOutput.test.ts` (+12 -3) 📝 `tests/boundary/cli/jsonLinesOutput.test.ts` (+157 -24) 📝 `tests/boundary/cli/jsonOutput.test.ts` (+1 -1) </details> ### 📄 Description **What broke:** a `--format jsonl` refusal of a selection that is not a record collection was reported as `unreadable_output` / `execution_failure` with "Run `rea doctor`", although the analysis succeeded (`--format json` exits 0). **Fix:** the JSON Lines owner (`src/cli/jsonLines.ts`) now refuses with `AnalysisInputError` → `invalid_request` / `invalid_input`, naming the selection and its observed shape, and keeps the `--format json` / `--filter-output` remediation; docs say columnar SQLite rows are not a record collection. **Risk:** low. The admission rules are unchanged and exit status stays 1. Only the error code, category and message change, so callers matching `unreadable_output` on JSONL refusals have to switch to `invalid_request`. ## Summary Fixes #7110. When `--format jsonl` is refused, the cause is the caller's output selection, not the analysis. The refusal is now a typed caller error, so agents that branch on `code`/`category` no longer treat a successful analysis as failed, and they are no longer pointed at `rea doctor`. ## Problem and expected behavior Trigger (base `bc143125e`, built CLI): ```sh sqlite3 t.sqlite 'create table configInts(name text primary key, value integer); insert into configInts values ("a",1),("b",2);' rea inspect-sqlite-database t.sqlite --table configInts --format jsonl --filter-output normalized_result.rows # exit 1 rea inspect-sqlite-database t.sqlite --table configInts --format json > /dev/null # exit 0 ``` Before: ```json {"$rea":"jsonl/v1","type":"error","ok":false,"result":{"code":"unreadable_output","category":"execution_failure","message":"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.","retryable":false,"remediation":{"action":"Use --format json for the complete document, or select one record collection with --filter-output."},"details":{"operation":"inspect-sqlite-database","reason":"JSON Lines requires an array or one explicit rows, items, records, or occurrences collection."}}} ``` After: ```json {"$rea":"jsonl/v1","type":"error","ok":false,"result":{"code":"invalid_request","category":"invalid_input","message":"The --filter-output selection normalized_result.rows is not a JSON Lines record collection: normalized_result.rows is an object. JSON Lines needs a top-level array, or exactly one rows, items, records, or occurrences array directly in the result, under page, or under normalized_result.","retryable":false,"remediation":{"action":"Use --format json for the complete document, or select one record collection with --filter-output."},"recovery":{"kind":"inspect_input_contract","operation":"inspect-sqlite-database"},"details":{"operation":"inspect-sqlite-database","issues":[{"path":["filter-output"],"reason":"invalid_value","message":"The --filter-output selection normalized_result.rows is not a JSON Lines record collection: normalized_result.rows is an object.","observed":[{"path":["normalized_result","rows"],"shape":"object"}]}]}}} ``` ## Change and scope - `src/cli/jsonLines.ts` (owner of JSON Lines admission): all refusals (no collection, several collections, reserved `$rea` collision) are now `AnalysisInputError`. The issue path is `["filter-output"]` when a filter was given and `["format"]` otherwise. A single `examineBoundaries` walk over the documented boundaries (result, `page`, `normalized_result`, `normalized_result.page`) now produces both the admitted collections and the refusal facts. It replaces `collections`/`documentCollections`, so admission behavior is identical. The messages contain only fixed field names and the caller's own filter keys, never target data. - Each refused value is also reported as structured data in `details.issues[].observed`, as `[{path, shape}]` with shape one of `absent|null|array|object|string|number|boolean`. Callers can read the location and shape without parsing the message, and the message is built from these facts. `AnalysisInputIssue` gains this optional `observed` field: the error projection outputs it, and the sensitive-value redaction copy redacts it. - `src/domain/analysisErrorCore.ts` / `analysisErrorPresentation.ts`: `AnalysisInputError` takes an optional `remediationAction`, the same option `AnalysisOutputError`, `AnalysisUnsupportedTargetError` and others already have. Without it, the generic input-contract advice is unchanged. - `src/cli/cliResultOutput.ts` / `jsonLinesOutput.ts`: pass the already parsed `--filter-output` paths through, so the refusal can name the selection without parsing it again. - `docs/cli.md`: documents the caller-error classification. It also states that a columnar object such as `inspect-sqlite-database --table`'s `normalized_result.rows` (`{columns, values}`) is not a record collection, and narrows the `normalized_result.rows` example to analysis views. Intentionally not included: - Converting columnar `{columns, values}` into one object per row. Nothing else in the codebase reads SQLite rows that way, and duplicate column names are allowed (`columns` has no uniqueness constraint), so the conversion would be ambiguous. Use `--format json` for these results. - Admitting arbitrary nested arrays such as `normalized_result.schema.tables` or `normalized_result.imports.items`. The documented boundary rule is unchanged; these are now refused with a clear caller error. - JSON Lines is CLI-only. MCP has no JSONL path (`mcp doctor` renders a single document), so MCP is unaffected. Contribution scope: ordinary fix within existing boundaries; maintainer scope decision not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: the CLI JSON Lines projection (`prepareJsonLines`), plus an additive option on the `AnalysisInputError` domain error. The superseded `collections`/`documentCollections` helpers were removed. - Contribution scope fit and linked maintainer decision: not applicable (bug fix). - CLI and MCP/tool-catalog contract: on the CLI, JSONL refusal records change `code`/`category`/`message`/`details` to the existing `invalid_request` projection. Exit status stays 1. MCP: none. - Provider, bridge, target-format, or platform compatibility: none. - Evidence, artifact, provenance, or reconstruction contract: none; successful JSONL records and metadata are unchanged. - Target selection, authority, upstream behavior, and cleanup details: not applicable. - Generated metadata, package, or installation impact: none (`docs:check` passes; the error schema already includes `invalid_request`). - [x] Documentation or usability only; no target interaction. ## Evidence and regression coverage - Tests added or updated: - `tests/boundary/cli/jsonLinesOutput.test.ts`: each refusal asserts the classification (`invalid_request`/`invalid_input`), the issue `path`/`reason`, the structured `observed` facts, and that the remediation equals the owning constant `JSON_LINES_SELECTION_REMEDIATION`. No explanatory prose is asserted. A mutation check confirmed the tests are sensitive to facts, not wording: rewording the message still passed (44/44), and reporting a wrong shape failed (2 failed). Cases covered: - an object with no collection, a scalar, null, and a nested array elsewhere - collection fields that are null, a number, or a columnar object - several collections, including a `normalized_result.page` collection - an inherited `rows`, and a `$rea` collision in both a collection and a top-level array - `--full-output` boundary paths, and filters that match nothing, a scalar, null, a nested array, a columnar object, several collections, or several non-collection paths - admission still works for top-level arrays and `rows` of primitives and arrays, empty top-level arrays (no lines), and empty collections (metadata only) - `tests/acceptance/jsonLinesCli.test.ts`: the real built CLI against a real SQLite database runs the issue's rows (default, `--table … --filter-output normalized_result.rows`, `--filter-output normalized_result.schema.tables`), asserting structured facts, with `--json` exiting 0. For both the non-empty and the empty analysis-view requests, it checks that the documented `--filter-output normalized_result.rows` export emits exactly the same rows as the unfiltered export. - Updated expectations: `tests/acceptance/managedCliOutput.test.ts`, `tests/boundary/cli/javascriptApplicationJsonOutput.test.ts`, `tests/boundary/cli/jsonOutput.test.ts`. - Base reproduction: all five rows of the issue's table reproduced on `bc143125e` through `scripts/rea.mjs` (each `unreadable_output`, exit 1). That includes `inspect-macho /System/Applications/Calculator.app --filter-output 'normalized_result.imports.items[0,2]'`. After the change all five return `invalid_request` / `invalid_input` with exit 1. Two examples of the new messages: - `normalized_result.rows is null` (no `--table`) - `The --filter-output selection normalized_result.imports.items is not a JSON Lines record collection: it is an array outside a record collection boundary.` - Remaining proof gaps: Windows/Linux not run locally (no platform-specific code touched). ## Validation performed - Issue reproduction script (5 rows plus a `--format json` control) on the base build and the fixed build: the base gave `unreadable_output` on all 5 rows. The fixed build gives `invalid_request` on all 5 rows, and the `--format json` control exits 0. - `npm run test:focused -- tests/boundary/cli/jsonLinesOutput.test.ts tests/boundary/cli/jsonOutput.test.ts tests/boundary/cli/filteredArrayOutput.test.ts tests/boundary/cli/cliOutput.test.ts tests/boundary/cli/javascriptApplicationJsonOutput.test.ts tests/acceptance/jsonLinesCli.test.ts tests/acceptance/managedCliOutput.test.ts src/domain/analysisErrorProjection.test.ts`: 8 files, 270 tests passed. After the later describe split, `jsonLinesOutput.test.ts` was rerun: 44 passed. - After the review fixes: `npm run test:focused` on the same 8 files plus `src/domain/explicitSensitiveFailure.test.ts`: 9 files, 291 tests passed. The issue repro was rerun on the rebuilt CLI: all 5 rows return `invalid_request` with `observed` facts, and the `--format json` control exits 0. - `npm run check:fast`: passed. - `npm run format:check`: passed. - `npm run docs:check`: passed. ## Compatibility, safety, and release - Breaking changes or migration steps: the error code of a JSONL refusal moves from `unreadable_output` to `invalid_request` (category `execution_failure` → `invalid_input`). This corrects a misclassification; scripts matching the old code should match `invalid_request`. Exit status and record framing are unchanged. - Real Hopper/Ghidra, browser, or OS coverage: macOS arm64 only; no provider involved. - Package or release metadata impact: none. - Security, privacy, process, or containment review: messages echo only fixed field names and the caller's own `--filter-output` keys, never target values. ## Author readiness Human owner: @kaoru0822-kitauji - [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. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-03 13:39:25 +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#7657
No description provided.