[PR #7024] feat(pe): share one image-layout owner and read the exception directory #7583

Open
opened 2026-11-03 13:38:53 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/7024
Author: @NgLanNg
Created: 10/24/2026
Status: 🔄 Open

Base: main ← Head: feat/pe-image-layout-and-exception-directory


📝 Commits (6)

  • 475da95 feat(pe): share one image-layout owner and read the exception directory
  • a7c2931 chore(vault): stop tracking the harness-managed FM26 session transcript
  • 102b05e chore(vault): keep reverse-engineering evidence out of the repository
  • f266c63 chore: ignore local pi session exports
  • d284d32 chore(release): 6.8.0
  • 9fa9aa1 fix(pe): route the certificate parser through the shared image-layout owner

📊 Changes

13 files changed (+1358 additions, -151 deletions)

View changed files

📝 .gitignore (+8 -0)
📝 .release-please-manifest.json (+1 -1)
📝 CHANGELOG.md (+12 -0)
📝 docs/installation.md (+3 -3)
📝 package-lock.json (+2 -2)
📝 package.json (+1 -1)
📝 server.json (+2 -2)
📝 src/generatedPackageMetadata.ts (+1 -1)
➕ src/native/PeExceptionDirectory.test.ts (+446 -0)
➕ src/native/PeExceptionDirectory.ts (+438 -0)
📝 src/native/pe/PeCertificateParser.ts (+10 -6)
➕ src/native/pe/PeImageLayout.ts (+394 -0)
📝 src/native/pe/PeResourceLayout.ts (+40 -135)

📄 Description

Summary

PE header, section-table and data-directory facts now have one shared owner, and a new
reader exposes the image's exception directory as measured function extents.

PeImageLayout owns header admission, the section table, data directories, virtual
extent and file-backed RVA mapping, with tagged failure reasons. PeResourceLayout
delegates its header and section facts to that owner and keeps only the
resource-specific mapping rules and their messages.

PeExceptionDirectory decodes the exception directory as RUNTIME_FUNCTION records
and reports partial coverage and tagged failures instead of silently dropping extents
that no section maps.

Problem and expected behavior

PE header and section-table facts were parsed in more than one place, so two readers
could disagree about the same image. A reader that wanted a function boundary had no
supported way to obtain one: the exception directory is the authoritative source for
x64 function extents, and nothing read it.

Expected: one owner for PE image facts, and a way to ask an image for its measured
function extents with explicit failure reasons and coverage.

Change and scope

PeImageLayout becomes the single owner for MZ/PE header admission, the section
table, data directories, virtual extent and file-backed RVA mapping. PeResourceLayout
keeps its own resource mapping semantics — an empty interval still resolves at a
section's virtual end, a zero-extent section owns no byte, and an ambiguous interval
still fails — and only its messages.

PeExceptionDirectory reads the exception directory and reports each measured extent,
the coverage it achieved, and a tagged reason when the directory is absent,
inconsistent, unmapped, not file-backed, empty or malformed.

No target execution, no injection, no memory mutation, no protection recovery. This is
static format inspection of an artifact the caller already possesses.

Contract and boundary impact

  • Semantic owner and earliest changed stage: src/native/pe/PeImageLayout.ts owns PE
    image facts; PeResourceLayout consumes it. Native artifact inspection stage.
  • Contribution scope fit and linked maintainer decision: supported — "format
    inspection", "ordinary archive and standard-compression extraction, disassembly,
    decompilation, cross-references". No new provider, no target execution, no
    protection recovery. Not applicable.
  • CLI and MCP/tool-catalog contract: no CLI command, MCP tool, input schema or tool
    catalog entry changes. This adds library capability only.
  • Provider, bridge, target-format, or platform compatibility: PE only. Reads the
    EXCEPTION data directory of an existing PE image; no new dependency, no bridge
    change, no platform-specific code.
  • Evidence, artifact, provenance, or reconstruction contract: no Evidence record,
    artifact inventory or provenance field changes. The new reader reports partial
    coverage and tagged failures rather than defaulting to "absent".
  • Target selection, authority, upstream behavior, and cleanup details (if applicable):
    not applicable; the reader takes bytes already in memory and reads no target.
  • Generated metadata (docs/public/product-catalog.json), package, or installation
    impact: the package version moves to 6.8.0 with matching package-lock.json,
    server.json, src/generatedPackageMetadata.ts, docs/installation.md and
    .release-please-manifest.json. CI regenerates and validates the ignored catalog
    and skills/; no authored skill instruction changed.

Expected effects:

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

Evidence and regression coverage

  • Tests added or updated: src/native/PeExceptionDirectory.test.ts (new, 446 lines)
    covers record decoding, partial coverage, and each tagged failure reason.
    tests/boundary/filesystem/peResources.test.ts continues to cover resource
    mapping through the new shared owner.
  • Base reproduction or other evidence: the exception directory has no prior reader
    in this repository, so there is no base behaviour to regress. The resource reader's
    behaviour is covered by the existing boundary test, which passes unchanged.
  • User-visible CLI/MCP output (if applicable): none; this is library capability.
  • Remaining proof gaps: the exception-directory reader is not yet surfaced through a
    CLI command or MCP tool, so it is not reachable by users in this release. PE
    (32-bit and 64-bit) is covered; ELF, Mach-O and other formats are out of scope for
    this reader.

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

All commands below were executed on this branch.

  • npm run check:fast — passed (typecheck and lint clean, 0 errors).
  • npx vitest run tests/boundary/native tests/boundary/filesystem/peResources.test.ts src/native — 15 passed.
  • npx vitest run tests/conformance/releaseConfiguration.test.ts — 5 passed.
  • npx vitest run tests/boundary/filesystem/releaseCheckpoint.test.ts — 39 passed.
  • npx vitest run tests/boundary/filesystem/releaseNotes.test.ts — 5 passed.
  • npm run metadata:check — passed.
  • npm run docs:check — passed.
  • npm run test:python — 91 passed.
  • npm run jscpd — 3.40% duplicated lines, no threshold failure.
  • npm run scan:todos — no tech-debt markers.
  • npm run knip — clean.
  • npm pack --dry-run — rea-agents-6.8.0.tgz, 2110 files, 8.1 MB; contains no vault/ path.
  • npm ci --ignore-scripts — succeeded and left package-lock.json unchanged.

Pre-existing failures, not caused by this change

Each was reproduced identically on clean origin/main in a separate worktree.

  • npm run check:pr — test:run was force-killed at the 50-minute task limit; the
    remaining suite steps (test:python, docs:check, jscpd, scan:todos) pass
    individually.
  • tests/acceptance/setup/* — 20 failed / 24 passed on origin/main for the same
    test names; on this branch 5 failed / 39 passed for the same set. Setup and
    client-configuration tests, unrelated to PE code.
  • tests/boundary/filesystem/analysisSnapshot.test.ts,
    tests/boundary/filesystem/processCliFileInput.test.ts — 5 failed / 59 passed on
    origin/main, identical on this branch. Cancellation-timing tests.
  • tests/boundary/mcp/toolSchemaValidity.test.ts — 2 failed / 13 passed on
    origin/main, identical on this branch. 30s MCP stdio handshake timeouts.
  • tests/acceptance/applications/peResources.test.ts — fails identically on
    origin/main (30s MCP stdio handshake timeout).

Compatibility, safety, and release

  • Breaking changes or migration steps: none. The release is a minor version under
    always-bump-minor. PeResourceLayout's public behaviour and messages are
    unchanged; only the internal owner of PE image facts moved.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable — no provider,
    browser or OS-specific path changed. The PE reader is exercised through the
    real-file boundary test (tests/boundary/filesystem/peResources.test.ts), which
    admits the largest measured stock Windows resource table.
  • Package or release metadata impact: version 6.8.0 across package.json,
    package-lock.json, server.json, src/generatedPackageMetadata.ts,
    docs/installation.md and .release-please-manifest.json; CHANGELOG.md has a
    6.8.0 section. npm pack --dry-run produces rea-agents-6.8.0.tgz.
  • Security, privacy, process, or containment review: the new reader inspects bytes
    the caller already supplied. It adds no target execution, no network access and no
    credential handling, and it reports partial coverage explicitly rather than
    presenting missing extents as absent.

Author readiness

Human owner:

  • 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. — not applicable; no CLI or MCP surface changes.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

Update: rebased onto current main

main advanced 1,160 commits during review preparation. The branch is rebased onto
origin/main at 422ca5a8f and re-verified.

Two rebase resolutions worth review:

  • PeResourceLayout.ts — main had evolved its own inline header parsing.
    Resolved in favour of the shared PeImageLayout owner, which already carries the
    three checks main added (RVA range overflows, raw bytes overlap headers,
    overlapping raw file ranges). Behaviour is preserved; the owner moved.
  • src/generatedPackageMetadata.ts — kept main's new pinnedNodeVersion field
    alongside the 6.8.0 version bump.

Integration fix found by the rebase

origin/main added PeCertificateParser, which imported readPeHeaders from
PeResourceLayout — the exact export this branch had moved into PeImageLayout. The
rebase left that import dangling, and typecheck failed with TS2305.

Fixed by exposing the header offsets the parser needs (peOffset, optionalOffset,
optionalMagic, directoriesOffset) on PeImageLayout, and reading the security
directory through directoryOffset rather than recomputing it. The certificate
parser now shares one owner for PE header facts instead of carrying a second reader.

Re-validation after the rebase

Toolchain: pinned Node 24.22.1 / npm 11.19.1 (installed for this; .nvmrc pins
24.22.1 and engines requires ^24.22.1).

  • npm ci --ignore-scripts — succeeded, lockfile unchanged.
  • npm run check:fast — passed.
  • npm run typecheck — passed (was failing TS2305 before the integration fix).
  • npm run build:cached — passed.
  • npx vitest run --project acceptance tests/acceptance/peCertificatesCli.test.ts — 5 passed. This is the suite that exercises the parser I changed.
  • npx vitest run --project boundary --project conformance --project unit — 9169 passed, 3 failed. All three reproduced as failures on origin/main or pass in isolation:
    • productCatalog.test.ts and setupSkill.test.ts — stale generated catalog after the rebase; npm run docs:generate regenerates it and both then pass (27 tests).
    • kunaProvider.test.ts — passes in isolation (31 tests); contention-flaky.
  • npm run metadata:check — passed.
  • npm run docs:check — 9 passed.
  • npm run test:python — 91 passed.
  • npm run jscpd — 3.63% duplicated lines.
  • npm run scan:todos — no tech-debt markers.
  • npm run knip — clean.

🔄 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/7024 **Author:** [@NgLanNg](https://github.com/NgLanNg) **Created:** 10/24/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/pe-image-layout-and-exception-directory` --- ### 📝 Commits (6) - [`475da95`](https://github.com/morluto/rea/commit/475da95f240dcb67401cf6bb89dd279f5a0b79bd) feat(pe): share one image-layout owner and read the exception directory - [`a7c2931`](https://github.com/morluto/rea/commit/a7c29310add4fc214c355569c0ed739a60da1539) chore(vault): stop tracking the harness-managed FM26 session transcript - [`102b05e`](https://github.com/morluto/rea/commit/102b05ea38650edcf7aab84cf4c536fd6e846d7d) chore(vault): keep reverse-engineering evidence out of the repository - [`f266c63`](https://github.com/morluto/rea/commit/f266c63ccf4bb7590f8d1be852d4178e61221e58) chore: ignore local pi session exports - [`d284d32`](https://github.com/morluto/rea/commit/d284d3216d5e0a286a07c1912d95881b39e7ec4e) chore(release): 6.8.0 - [`9fa9aa1`](https://github.com/morluto/rea/commit/9fa9aa134c049f7164d53efac729d4f5c0c07728) fix(pe): route the certificate parser through the shared image-layout owner ### 📊 Changes **13 files changed** (+1358 additions, -151 deletions) <details> <summary>View changed files</summary> 📝 `.gitignore` (+8 -0) 📝 `.release-please-manifest.json` (+1 -1) 📝 `CHANGELOG.md` (+12 -0) 📝 `docs/installation.md` (+3 -3) 📝 `package-lock.json` (+2 -2) 📝 `package.json` (+1 -1) 📝 `server.json` (+2 -2) 📝 `src/generatedPackageMetadata.ts` (+1 -1) ➕ `src/native/PeExceptionDirectory.test.ts` (+446 -0) ➕ `src/native/PeExceptionDirectory.ts` (+438 -0) 📝 `src/native/pe/PeCertificateParser.ts` (+10 -6) ➕ `src/native/pe/PeImageLayout.ts` (+394 -0) 📝 `src/native/pe/PeResourceLayout.ts` (+40 -135) </details> ### 📄 Description ## Summary PE header, section-table and data-directory facts now have one shared owner, and a new reader exposes the image's exception directory as measured function extents. `PeImageLayout` owns header admission, the section table, data directories, virtual extent and file-backed RVA mapping, with tagged failure reasons. `PeResourceLayout` delegates its header and section facts to that owner and keeps only the resource-specific mapping rules and their messages. `PeExceptionDirectory` decodes the exception directory as `RUNTIME_FUNCTION` records and reports partial coverage and tagged failures instead of silently dropping extents that no section maps. ## Problem and expected behavior PE header and section-table facts were parsed in more than one place, so two readers could disagree about the same image. A reader that wanted a function boundary had no supported way to obtain one: the exception directory is the authoritative source for x64 function extents, and nothing read it. Expected: one owner for PE image facts, and a way to ask an image for its measured function extents with explicit failure reasons and coverage. ## Change and scope `PeImageLayout` becomes the single owner for MZ/PE header admission, the section table, data directories, virtual extent and file-backed RVA mapping. `PeResourceLayout` keeps its own resource mapping semantics — an empty interval still resolves at a section's virtual end, a zero-extent section owns no byte, and an ambiguous interval still fails — and only its messages. `PeExceptionDirectory` reads the exception directory and reports each measured extent, the coverage it achieved, and a tagged reason when the directory is absent, inconsistent, unmapped, not file-backed, empty or malformed. No target execution, no injection, no memory mutation, no protection recovery. This is static format inspection of an artifact the caller already possesses. ## Contract and boundary impact - Semantic owner and earliest changed stage: `src/native/pe/PeImageLayout.ts` owns PE image facts; `PeResourceLayout` consumes it. Native artifact inspection stage. - Contribution scope fit and linked maintainer decision: supported — "format inspection", "ordinary archive and standard-compression extraction, disassembly, decompilation, cross-references". No new provider, no target execution, no protection recovery. Not applicable. - CLI and MCP/tool-catalog contract: no CLI command, MCP tool, input schema or tool catalog entry changes. This adds library capability only. - Provider, bridge, target-format, or platform compatibility: PE only. Reads the `EXCEPTION` data directory of an existing PE image; no new dependency, no bridge change, no platform-specific code. - Evidence, artifact, provenance, or reconstruction contract: no Evidence record, artifact inventory or provenance field changes. The new reader reports partial coverage and tagged failures rather than defaulting to "absent". - Target selection, authority, upstream behavior, and cleanup details (if applicable): not applicable; the reader takes bytes already in memory and reads no target. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: the package version moves to 6.8.0 with matching `package-lock.json`, `server.json`, `src/generatedPackageMetadata.ts`, `docs/installation.md` and `.release-please-manifest.json`. CI regenerates and validates the ignored catalog and `skills/`; no authored skill instruction changed. Expected effects: - [x] 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. ## Evidence and regression coverage - Tests added or updated: `src/native/PeExceptionDirectory.test.ts` (new, 446 lines) covers record decoding, partial coverage, and each tagged failure reason. `tests/boundary/filesystem/peResources.test.ts` continues to cover resource mapping through the new shared owner. - Base reproduction or other evidence: the exception directory has no prior reader in this repository, so there is no base behaviour to regress. The resource reader's behaviour is covered by the existing boundary test, which passes unchanged. - User-visible CLI/MCP output (if applicable): none; this is library capability. - Remaining proof gaps: the exception-directory reader is not yet surfaced through a CLI command or MCP tool, so it is not reachable by users in this release. PE (32-bit and 64-bit) is covered; ELF, Mach-O and other formats are out of scope for this reader. 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 All commands below were executed on this branch. - `npm run check:fast` — passed (typecheck and lint clean, 0 errors). - `npx vitest run tests/boundary/native tests/boundary/filesystem/peResources.test.ts src/native` — 15 passed. - `npx vitest run tests/conformance/releaseConfiguration.test.ts` — 5 passed. - `npx vitest run tests/boundary/filesystem/releaseCheckpoint.test.ts` — 39 passed. - `npx vitest run tests/boundary/filesystem/releaseNotes.test.ts` — 5 passed. - `npm run metadata:check` — passed. - `npm run docs:check` — passed. - `npm run test:python` — 91 passed. - `npm run jscpd` — 3.40% duplicated lines, no threshold failure. - `npm run scan:todos` — no tech-debt markers. - `npm run knip` — clean. - `npm pack --dry-run` — `rea-agents-6.8.0.tgz`, 2110 files, 8.1 MB; contains no `vault/` path. - `npm ci --ignore-scripts` — succeeded and left `package-lock.json` unchanged. ### Pre-existing failures, not caused by this change Each was reproduced identically on clean `origin/main` in a separate worktree. - `npm run check:pr` — `test:run` was force-killed at the 50-minute task limit; the remaining suite steps (`test:python`, `docs:check`, `jscpd`, `scan:todos`) pass individually. - `tests/acceptance/setup/*` — 20 failed / 24 passed on `origin/main` for the same test names; on this branch 5 failed / 39 passed for the same set. Setup and client-configuration tests, unrelated to PE code. - `tests/boundary/filesystem/analysisSnapshot.test.ts`, `tests/boundary/filesystem/processCliFileInput.test.ts` — 5 failed / 59 passed on `origin/main`, identical on this branch. Cancellation-timing tests. - `tests/boundary/mcp/toolSchemaValidity.test.ts` — 2 failed / 13 passed on `origin/main`, identical on this branch. 30s MCP stdio handshake timeouts. - `tests/acceptance/applications/peResources.test.ts` — fails identically on `origin/main` (30s MCP stdio handshake timeout). ## Compatibility, safety, and release - Breaking changes or migration steps: none. The release is a minor version under `always-bump-minor`. `PeResourceLayout`'s public behaviour and messages are unchanged; only the internal owner of PE image facts moved. - Real Hopper/Ghidra, browser, or OS coverage: not applicable — no provider, browser or OS-specific path changed. The PE reader is exercised through the real-file boundary test (`tests/boundary/filesystem/peResources.test.ts`), which admits the largest measured stock Windows resource table. - Package or release metadata impact: version 6.8.0 across `package.json`, `package-lock.json`, `server.json`, `src/generatedPackageMetadata.ts`, `docs/installation.md` and `.release-please-manifest.json`; `CHANGELOG.md` has a 6.8.0 section. `npm pack --dry-run` produces `rea-agents-6.8.0.tgz`. - Security, privacy, process, or containment review: the new reader inspects bytes the caller already supplied. It adds no target execution, no network access and no credential handling, and it reports partial coverage explicitly rather than presenting missing extents as absent. ## Author readiness Human owner: <!-- @GitHub-handle --> - [ ] 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 - [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`. - [ ] 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. - [ ] User-visible CLI/MCP changes include representative output. — not applicable; no CLI or MCP surface changes. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. ## Update: rebased onto current main `main` advanced 1,160 commits during review preparation. The branch is rebased onto `origin/main` at `422ca5a8f` and re-verified. Two rebase resolutions worth review: - **`PeResourceLayout.ts`** — `main` had evolved its own inline header parsing. Resolved in favour of the shared `PeImageLayout` owner, which already carries the three checks `main` added (`RVA range overflows`, `raw bytes overlap headers`, `overlapping raw file ranges`). Behaviour is preserved; the owner moved. - **`src/generatedPackageMetadata.ts`** — kept `main`'s new `pinnedNodeVersion` field alongside the 6.8.0 version bump. ### Integration fix found by the rebase `origin/main` added `PeCertificateParser`, which imported `readPeHeaders` from `PeResourceLayout` — the exact export this branch had moved into `PeImageLayout`. The rebase left that import dangling, and `typecheck` failed with `TS2305`. Fixed by exposing the header offsets the parser needs (`peOffset`, `optionalOffset`, `optionalMagic`, `directoriesOffset`) on `PeImageLayout`, and reading the security directory through `directoryOffset` rather than recomputing it. The certificate parser now shares one owner for PE header facts instead of carrying a second reader. ### Re-validation after the rebase Toolchain: pinned Node 24.22.1 / npm 11.19.1 (installed for this; `.nvmrc` pins 24.22.1 and `engines` requires `^24.22.1`). - `npm ci --ignore-scripts` — succeeded, lockfile unchanged. - `npm run check:fast` — passed. - `npm run typecheck` — passed (was failing TS2305 before the integration fix). - `npm run build:cached` — passed. - `npx vitest run --project acceptance tests/acceptance/peCertificatesCli.test.ts` — 5 passed. This is the suite that exercises the parser I changed. - `npx vitest run --project boundary --project conformance --project unit` — 9169 passed, 3 failed. All three reproduced as failures on `origin/main` or pass in isolation: - `productCatalog.test.ts` and `setupSkill.test.ts` — stale generated catalog after the rebase; `npm run docs:generate` regenerates it and both then pass (27 tests). - `kunaProvider.test.ts` — passes in isolation (31 tests); contention-flaky. - `npm run metadata:check` — passed. - `npm run docs:check` — 9 passed. - `npm run test:python` — 91 passed. - `npm run jscpd` — 3.63% duplicated lines. - `npm run scan:todos` — no tech-debt markers. - `npm run knip` — clean. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#7583
No description provided.