Premise
After PR #11129 unified write-path issue/PR/discussion storage on the chunkPath utility (String(N).padStart(4,'0').slice(0,-2) + 'xx'), active issues land at `resources/content/issues/XXxx/issue-N.md`.
But `LocalFileService.getIssueById` (read path consumed by the `get_local_issue_by_id` MCP tool) still uses the flat path at line 73:
```js
const activePath = path.join(aiConfig.issueSync.issuesDir, filename);
```
The recursive fallback (#findFileRecursively) only walks `archiveDir`, not `issuesDir`. Result: every active chunked issue returns `NOT_FOUND` from the MCP tool.
Empirical V-B-A (2026-05-10)
```
$ ls /Users/Shared/github/neomjs/neo/resources/content/issues/111xx/issue-11118.md
issue-11118.md ← exists at chunked path
$ mcp_call get_local_issue_by_id({issue_number: '11118'})
Error: File not found. No local markdown file found for issue #11118.
```
Empirical Anchor — Operator-Surfaced Friction
@tobiu 2026-05-10: "pulled from dev, harness and bridge restart. i thought gh workflow server was fixed. did you not push previous pathing fixes?"
The "pathing fix" gap is precisely this: write-side chunking landed across #11114 / #11123 / #11125 / #11129 but read-side asymmetry was missed across all 4 review cycles (review-rigor floor failure per `feedback_architectural_pillar_review_floor`).
Prescription
Single-line patch in `LocalFileService.mjs:73`:
```js
import chunkPath from './shared/chunkPath.mjs';
// ...
const activePath = path.join(aiConfig.issueSync.issuesDir, chunkPath(normalizedId), filename);
```
Mirrors the write-path symmetry from `IssueSyncer.mjs:283/310`. Recursive archive fallback is already correct (walks subdirs).
Avoided Traps
| Considered |
Rejected |
Rationale |
| Make active-path lookup recursive (mirror archive behavior) |
Reject |
chunkPath is deterministic — recursive walk is wasted IO and conflates active vs archive directory shapes. |
| Generalize active-path resolver as a service-level utility |
Reject for narrow PR |
Single locus (only `getIssueById` consumes active flat-path); generalize when 2nd consumer surfaces. |
| Add PullRequest / Discussion local-file-by-id symmetry |
Reject for this ticket |
Out of scope; `toolService.mjs` only exposes `get_local_issue_by_id`. File follow-up if needed. |
| Bootstrap re-run as remediation (operator's hypothesis) |
Reject |
Bootstrap copies config templates; this is a code-level read/write asymmetry. Bootstrap won't fix the bug. |
Acceptance Criteria
Substrate-Quality Lesson
Recurring review-rigor floor failure: 4-PR chunking cluster (#11114 / #11123 / #11125 / #11129) all merged with write-path-only-symmetry; read path missed across all reviewers. Same family as the #11127 rubber-stamp incident. Companion to #11136 (skill-explicit A2A routing) and #10537 (review-template mechanical gates).
— @neo-opus-4-7
Premise
After PR #11129 unified write-path issue/PR/discussion storage on the
chunkPathutility (String(N).padStart(4,'0').slice(0,-2) + 'xx'), active issues land at `resources/content/issues/XXxx/issue-N.md`.But `LocalFileService.getIssueById` (read path consumed by the `get_local_issue_by_id` MCP tool) still uses the flat path at line 73:
```js const activePath = path.join(aiConfig.issueSync.issuesDir, filename); ```
The recursive fallback (#findFileRecursively) only walks `archiveDir`, not `issuesDir`. Result: every active chunked issue returns `NOT_FOUND` from the MCP tool.
Empirical V-B-A (2026-05-10)
``` $ ls /Users/Shared/github/neomjs/neo/resources/content/issues/111xx/issue-11118.md issue-11118.md ← exists at chunked path $ mcp_call get_local_issue_by_id({issue_number: '11118'}) Error: File not found. No local markdown file found for issue #11118. ```
Empirical Anchor — Operator-Surfaced Friction
@tobiu 2026-05-10: "pulled from dev, harness and bridge restart. i thought gh workflow server was fixed. did you not push previous pathing fixes?"
The "pathing fix" gap is precisely this: write-side chunking landed across #11114 / #11123 / #11125 / #11129 but read-side asymmetry was missed across all 4 review cycles (review-rigor floor failure per `feedback_architectural_pillar_review_floor`).
Prescription
Single-line patch in `LocalFileService.mjs:73`:
```js import chunkPath from './shared/chunkPath.mjs'; // ... const activePath = path.join(aiConfig.issueSync.issuesDir, chunkPath(normalizedId), filename); ```
Mirrors the write-path symmetry from `IssueSyncer.mjs:283/310`. Recursive archive fallback is already correct (walks subdirs).
Avoided Traps
Acceptance Criteria
Substrate-Quality Lesson
Recurring review-rigor floor failure: 4-PR chunking cluster (#11114 / #11123 / #11125 / #11129) all merged with write-path-only-symmetry; read path missed across all reviewers. Same family as the #11127 rubber-stamp incident. Companion to #11136 (skill-explicit A2A routing) and #10537 (review-template mechanical gates).
— @neo-opus-4-7