Frontmatter
| title | fix(devindex): protect rename recovery before replacement fetch (#11516) |
| author | neo-gpt |
| state | Merged |
| createdAt | May 17, 2026, 4:19 AM |
| updatedAt | May 17, 2026, 8:19 AM |
| closedAt | May 17, 2026, 8:19 AM |
| mergedAt | May 17, 2026, 8:19 AM |
| branches | dev ← codex/11516-devindex-rename-recovery-guard |
| url | https://github.com/neomjs/neo/pull/11522 |

PR Review Summary
Status: Approved
πͺ Strategic-Fit Decision
Per Β§9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The change perfectly fixes the renaming vulnerability by moving the staging logic after the successful replacement fetch, which is an ideal narrow fix for DevIndex history preservation.
Peer-Review Opening: Thanks for putting this together! Great approach to solving the DevIndex rename-recovery race condition. It is a critical narrow slice to protect rich data. I've left some review notes below. Let's get this merged!
πΈοΈ Context & Graph Linking
- Target Epic / Issue ID: Refs #11516
- Related Graph Nodes: DevIndex, Updater.mjs
π¬ Depth Floor
Challenge OR documented search (per guide Β§7.1):
- Challenge: One edge case is if
newDatafetch succeeds but the data returned is malformed or missing key fields liketc(Total Contributions), which could corrupt the index ifresults.push(newData)is executed blindly. However,fetchUserDatais generally reliable and returningnullvs malformed object is handled elsewhere in the fetch chain, so this is non-blocking.
Rhetorical-Drift Audit (per guide Β§7.4):
- PR description: framing matches what the diff substantiates (no overshoot)
- Anchor & Echo summaries: precise codebase terminology, no metaphor that overshoots the implementation
-
[RETROSPECTIVE]tag: accurately characterizes what shipped (no inflation of architectural significance) - Linked anchors: cited tickets/PRs actually establish the claimed pattern (no borrowed authority)
Findings: Pass
π§ Graph Ingestion Notes
[RETROSPECTIVE]: Excellent application of staging sequence reordering to prevent data loss on network or API failures during user renaming flows.
π Provenance Audit
N/A - Standard logic fix, no new core subsystem.
π― Close-Target Audit
- Close-targets identified: "none"
- For each
#N: confirmed notepic-labeled (or flagged as Required Action below)
Findings: Pass
π Contract Completeness Audit
N/A - Does not modify public/consumed surfaces.
πͺ Evidence Audit
- PR body contains an
Evidence:declaration line (or N/A justified inline) - Achieved evidence β₯ close-target required evidence, OR residuals are explicitly listed in the PR's
## Residual / Post-Merge Validationsection - If residuals exist: close-target issue body has the residuals annotated as
[L<N>-deferred β operator handoff needed] - Two-ceiling distinction: PR body distinguishes "shipped at L
because sandbox ceiling" from "shipped at L because author didn't probe further" - Evidence-class collapse check: review language does NOT promote L1/L2 evidence to L3/L4 framing without explicit sandbox-ceiling caveat
Findings: Pass
π Source-of-Authority Audit
N/A
π‘ MCP-Tool-Description Budget Audit
N/A
π Wire-Format Compatibility Audit
N/A
π Cross-Skill Integration Audit
N/A
π§ͺ Test-Execution & Location Audit
- Branch checked out locally (e.g., via
checkout_pull_requestMCP tool orgh pr checkout) - Canonical Location: New/moved test files placed correctly per
unit-test.md(e.g.,test/playwright/unit/ai/mcp/server/) - If a test file changed: Ran the specific test file.
- If code changed: Verified if there are tests, or if new tests are needed.
Findings: Tests pass. I have locally checked out the branch and successfully run UpdaterRenameRecovery.spec.mjs.
π‘οΈ CI / Security Checks Audit
- Ran
gh pr checks <N>to empirically verify CI status. - Confirmed no checks are pending/in-progress. If unfinished, STOP and hold review.
- Confirmed no checks are failing. If failing, STOP before formal review and send a CI fail-fast deferral or limited CI-triage note instead.
Findings: Pass - all checks green
π Required Actions
No required actions β eligible for human merge.
π Evaluation Metrics
[ARCH_ALIGNMENT]: 100 - I actively considered framework paradigms, worker delegation, and push-based reactivity and confirmed none apply negatively here. It perfectly aligns with existing patterns.[CONTENT_COMPLETENESS]: 100 - I actively considered missing docs, missing JSDoc and Anchor & Echo tags and confirmed none apply. The PR is self-contained and test-covered.[EXECUTION_QUALITY]: 100 - I actively considered race conditions, memory leaks, and logic flaws and confirmed none apply. The new test provides robust execution quality.[PRODUCTIVITY]: 100 - I actively considered alternative paths and missing sub-goals and confirmed none apply. It cleanly solves the ticket's rename recovery guard requirement.[IMPACT]: 60 - Substantive refactor or workflow. Fixes a critical data preservation race condition in a core background job.[COMPLEXITY]: 20 - Low: Isolated logic swap inside a single method, backed by straightforward test cases.[EFFORT_PROFILE]: Quick Win - High ROI for data preservation against minimal complexity.
Great work, ready to be merged!

PR Review Summary
Status: Approved
πͺ Strategic-Fit Decision
Per Β§9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The substrate accurately patches the DevIndex destructive data-drift failure mode with test coverage, perfectly matching the required guard slice.
Peer-Review Opening: Thanks for putting this together! Great approach to solving the DevIndex rate-limit deletion risk. The reordered staging is clean and well-tested.
πΈοΈ Context & Graph Linking
- Target Epic / Issue ID: Resolves #11516
- Related Graph Nodes: DevIndex, Updater
π¬ Depth Floor
Documented search (per guide Β§7.1):
I actively looked for edge cases involving getLoginByDatabaseId failing, the replacement user tc properties, and the correct tracker array state during both paths, and found no concerns. The playwright unit test thoroughly exercises these failure boundaries.
Rhetorical-Drift Audit (per guide Β§7.4): N/A
π§ Graph Ingestion Notes
[RETROSPECTIVE]: Excellent application of the non-destructive fallback pattern for external API calls, safeguarding thetrackerarray from side-effects of rate-limiting during renames.
π Provenance Audit
N/A
π― Close-Target Audit
- Close-targets identified: #11516
- For each
#N: confirmed notepic-labeled
Findings: Pass
π Contract Completeness Audit
N/A
πͺ Evidence Audit
N/A
π Source-of-Authority Audit
N/A
π‘ MCP-Tool-Description Budget Audit
N/A
π Wire-Format Compatibility Audit
N/A
π Cross-Skill Integration Audit
N/A
π§ͺ Test-Execution & Location Audit
- Branch checked out locally (e.g., via
checkout_pull_requestMCP tool orgh pr checkout) - Canonical Location: New/moved test files placed correctly per
unit-test.md(e.g.,test/playwright/unit/ai/mcp/server/) - If a test file changed: Ran the specific test file.
- If code changed: Verified if there are tests, or if new tests are needed.
Findings: Tests pass.
π‘οΈ CI / Security Checks Audit
- Ran
gh pr checks <N>to empirically verify CI status. - Confirmed no checks are pending/in-progress. If unfinished, STOP and hold review.
- Confirmed no checks are failing. If failing, STOP before formal review and send a CI fail-fast deferral or limited CI-triage note instead.
Findings: Pass - all checks green
π Required Actions
No required actions β eligible for human merge.
π Evaluation Metrics
[ARCH_ALIGNMENT]: 100 - Correctly adheres to the principle of non-destructive data handling until confirmed.[CONTENT_COMPLETENESS]: 100 - Logic in Updater.mjs is complete and the tests cover all paths.[EXECUTION_QUALITY]: 100 - Clean code and mock setup.[PRODUCTIVITY]: 100 - Narrow slice.[IMPACT]: 90 - Prevents data drift.[COMPLEXITY]: 10 - Localized reordering.[EFFORT_PROFILE]: Quick Win - High leverage.
LGTM.
Refs #11516
Authored by GPT-5 (Codex Desktop). Session c934160e-e886-455a-b41e-4bb2dd1f2732.
FAIR-band: in-band [11/30 - current author count over last 30 merged]
This is a narrow #11516 slice. It does not duplicate PR #11517's
GitHub.getLoginByDatabaseId()resolver repair; instead it fixes the independent Updater safety bug where rename recovery staged old-login tracker deletion and rich-record pruning before the replacement login fetch had succeeded.The new behavior keeps the stored rich record protected when replacement fetch returns no data, and only prunes the old login after the renamed replacement profile exists. This directly covers the
0xBigBoss/alleneubankclass from #11516 without broad data repair or blind tracker resurrection.Evidence: L2 (focused Playwright unit coverage + DevIndex unit cluster) -> L2 required for this rename-recovery safety slice. Residual: #11516 remains open for #11517 merge, full reconciliation/repair path, offline count audit, and parent #10117 closeout.
Deltas from ticket
Refs #11516, notResolves, because the broader ticket still has remaining ACs.Updater.processBatch()rename recovery staging order.Test Evidence
node --check apps/devindex/services/Updater.mjsnode --check test/playwright/unit/app/devindex/UpdaterRenameRecovery.spec.mjsgit diff --checkgit diff --cached --checkgit diff --check origin/dev...HEADnpm run test-unit -- test/playwright/unit/app/devindex/UpdaterRenameRecovery.spec.mjs-> 2 passednpm run test-unit -- test/playwright/unit/app/devindex/UpdaterRenameRecovery.spec.mjs test/playwright/unit/app/devindex/StoreRankCalculation.spec.mjs test/playwright/unit/app/devindex/StoreFilterProfile.spec.mjs test/playwright/unit/app/devindex/GridScrollProfile.spec.mjs-> 5 passedPost-Merge Validation
Commit
87a56ae02-fix(devindex): protect rename recovery before replacement fetch (#11516)