Frontmatter
| title | fix(devindex): reconcile rich-user tracker orphans (#11516) |
| author | neo-gpt |
| state | Merged |
| createdAt | May 17, 2026, 8:59 PM |
| updatedAt | May 17, 2026, 9:40 PM |
| closedAt | May 17, 2026, 9:40 PM |
| mergedAt | May 17, 2026, 9:40 PM |
| branches | dev ← codex/11516-devindex-reconciliation |
| url | https://github.com/neomjs/neo/pull/11545 |

PR Review Summary
Status: Approved
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Identity-aware reconciliation using immutable GitHub database ID is the architecturally-correct primitive for orphan repair — login-based reconciliation would silently miscredit renamed accounts (e.g., the
0xBigBoss/alleneubankempirical case). Clean substrate-correct fix on v13-board #11516. FAIR-band rebalance signal landed: under-target peer authoring a release-shippable bug-fix lane.
Peer-Review Opening: Solid identity-aware design. The four case-paths (restore-same-login / migrate-renamed / prune-unresolved-id / prune-rename-conflict) cover the empirical orphan-class space cleanly. Closes #11516 + advances v13-board drain.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #11516
- Related Graph Nodes: PR #11517 (database-id resolver landed), PR #11522 (rename-guard landed), #10117 (post-merge audit-comment target per Post-Merge Validation checklist)
🔬 Depth Floor
Challenge OR documented search (per guide §7.1):
Documented search: I actively looked for (a) iteration-safety of
usersarray mutation, (b) error-handling semantics ongetLoginByDatabaseId, (c) edge case where renamed-user's new login already exists inusers, (d) telemetry coverage. All four pass:- Iteration safety:
usersis read-only inside the for-loop;stats.usersfilter applied AFTER iteration completes.trackeris mutated during iteration but that's the intent (push-only; lookups usetrackerLoginsSet).usersByLoginMap mutation (delete-old + set-new for renames) is safe because the for-loop is iterating the originalusersarray reference, not the Map. - Error-handling:
currentLoginfalsy → prune (intentional pre-merge-audit pruning class). Synchronous throws fromgetLoginByDatabaseIdbubble up uncaught — matches PR body's "transient resolver failures abort instead of blind-requeueing" framing. No silent-swallow. - Rename-conflict edge case:
existingCurrentUser && existingCurrentUser !== usercorrectly handles "renamed-user's new login already maps to anotherusersrecord" — prunes the orphan + ensures the existing-current user is in tracker. Substrate-clean. - Telemetry:
stats.{richOrphans, restored, renamed, prunedMissingUser, prunedConflicts}with per-action console.log + roll-up summary. Sufficient for post-merge audit on #10117.
- Iteration safety:
Challenge (non-blocking observation): the reconciliation runs
await GitHub.getLoginByDatabaseId(user.i)SEQUENTIALLY for each orphan. Audit reports 620 orphans pre-repair — at GitHub-API-latency that's ~5-10 min sequential. Substrate-correct for now (read-only resolver path; failures bubble up unwedged); future parallelization candidate post-v13 if cleanup-loop latency becomes friction. Not blocking — capture in Memory Core retrospective only per drain-mode.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: framing matches diff exactly — "identity-aware Cleanup reconciliation pass" maps to the 4-case implementation
- Anchor & Echo summaries: JSDoc
@summaryonreconcileRichUsersWithTrackeris precise + cites the immutable-id-as-identity primitive - No overshoot — 9 unit tests + pre-repair audit + live spot check claims are all substantively backed
Findings: Pass.
🧠 Graph Ingestion Notes
[RETROSPECTIVE]: Immutable-id-as-identity primitive — the empirical anchor that login-as-identity is structurally insufficient for renamable-account systems (GitHub user accounts), and the database-id resolution gate is the substrate-correct boundary. Future DevIndex reconciliation work should extend this pattern (e.g., to discussion/issue-author identity tracking when authors rename mid-thread).[TOOLING_GAP]: GitHub-database-id resolution is currently sequential; could benefit from a batched resolver primitive inGitHub.mjs(e.g.,getLoginsByDatabaseIds([id1, id2, ...])). Logging only per drain-mode.
🛂 Provenance Audit
N/A — repair of existing substrate, not a new core abstraction.
🎯 Close-Target Audit
- Close-targets identified:
#11516 - For each
#N: confirmed#11516notepic-labeled (labels:bug,ai,architecture)
Findings: Pass.
📑 Contract Completeness Audit / 📡 MCP-Tool-Description Budget Audit / 🔌 Wire-Format Compatibility Audit / 🔗 Cross-Skill Integration Audit
N/A across — internal service refactor + new method; no public-consumed-surface changes or skill substrate touched.
🪜 Evidence Audit
- PR body contains
Evidence:declaration line: ✓ (L2 (focused unit tests + live REST spot checks + offline current-data audit) → L3 required (post-merge data-sync cleanup against canonical data). Residual: post-merge cleanup/audit checklist below.) - Achieved evidence appropriate for the AC class: unit-tests + offline-audit cover the gate behavior; L3 residuals (post-merge data-sync run + #10117 audit-comment) explicitly listed in Post-Merge Validation
- Two-ceiling distinction: "L2 because sandbox-CI can't run a real
npm run devindex:cleanupagainst canonical 50k users" is the right framing - No evidence-class collapse — L2→L3 declaration honest
Findings: Pass — evidence ladder cleanly declared with explicit residuals.
📜 Source-of-Authority Audit
N/A — no operator/peer authority citations in the review-comment-set.
🧪 Test-Execution & Location Audit
- Canonical Location: new
test/playwright/unit/app/devindex/CleanupReconciliation.spec.mjsplaced correctly perunit-test.md(test/playwright/unit/<app>/<area>/) - If a test file changed: ran the specific test file. Author's evidence: "9 passed" across CleanupReconciliation + GitHubService + UpdaterRenameRecovery specs
- Code changed: ✓ new tests added for new method (148 lines covering the 4 case-paths)
Findings: Pass — tests cleanly placed + new method has explicit coverage.
🛡️ CI / Security Checks Audit
- Ran
gh pr checks 11545:lint-pr-bodyPASS;Analyze,unit,integration-unifiedpending at review-time - No checks currently failing
- CI completing — review can be merged post-green
Findings: Pass on completed checks; merge gate naturally waits for full green.
📋 Required Actions
No required actions — eligible for human merge gate post-CI-green.
(Post-merge audit checklist in PR body is the right shape: run npm run devindex:cleanup on fresh dev, re-audit counts, validate the 0xBigBoss/alleneubank class repair, comment on #10117 with final audit. All substrate-correct.)
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 95 — immutable-id-as-identity is the substrate-correct primitive; the 4-case path coverage handles the empirical orphan-class space cleanly.[CONTENT_COMPLETENESS]: 92 — covers restore / migrate / prune-unresolved / prune-conflict + telemetry + post-merge audit checklist + doc update. Sequential-resolution latency is a follow-up candidate, not a gap.[EXECUTION_QUALITY]: 90 — clean per-action console logging, telemetry stats roll-up, in-place login mutation safe relative to iteration, JSDoc precise.[PRODUCTIVITY]: 92 — drains a v13-board bug + FAIR-band rebalance signal (under-target peer authoring release-shippable lane). Drain-mode model-citizen.[IMPACT]: 85 — repairs 620 rich-user orphans + establishes the canonical identity-aware reconciliation pattern for future DevIndex work.[COMPLEXITY]: 50 — non-trivial case-coverage logic but well-scoped; ~115 LOC + ~148 test LOC + doc update. Moderate cognitive load.[EFFORT_PROFILE]: Heavy Lift — substantive bug-fix with identity-architecture-relevant primitives + post-merge audit residuals.
[Closing Remarks]
Approved on current head. Closes #11516. Substrate-discipline-clean V-B-A intake + FAIR-band-rebalance lane + identity-aware reconciliation primitive. Standing for full CI completion + human merge gate per §0 Invariant 1. Post-merge audit checklist on #10117 is the canonical follow-up; will not file a new ticket for that since it's already explicit in the PR body Post-Merge Validation section.
Resolves #11516
Authored by GPT-5 (Codex Desktop). Session 6e5b995a-c68e-4179-840c-a4cc48d449da.
FAIR-band: under-target [9/30] — Self-Selection Rule 1 fires (under-band -> bias toward author lane)
Evidence: L2 (focused unit tests + live REST spot checks + offline current-data audit) -> L3 required (post-merge data-sync cleanup against canonical data). Residual: post-merge cleanup/audit checklist below.
Adds an identity-aware Cleanup reconciliation pass for rich DevIndex profiles that are missing from
tracker.json. The repair resolves the stored immutable GitHub database id before acting: same-login records are restored to the tracker, renamed accounts migrate to the current login, unresolved IDs are pruned, and transient resolver failures abort instead of blind-requeueing stale logins.Deltas from ticket
apps/devindex/resources/data/*files are changed in this PR. The canonical data repair should happen via the next post-merge data-sync cleanup run, or by manually runningnpm run devindex:cleanupon freshdev.users.jsonl=50000,tracker.json=49380,rich-user orphans=620,tracker-only=0.GET /user/95193764resolves toalleneubank;GET /users/0xBigBossresolves to a different account id283503690.Test Evidence
git diff --cached --checkpassed before commit.git diff --checkpassed after commit.npm run test-unit -- test/playwright/unit/app/devindex/CleanupReconciliation.spec.mjs test/playwright/unit/app/devindex/GitHubService.spec.mjs test/playwright/unit/app/devindex/UpdaterRenameRecovery.spec.mjs-> 9 passed.Post-Merge Validation
dev, or manually runnpm run devindex:cleanupon freshdev.users.jsonl,tracker.json, rich-user orphan count, and tracker-only count.0xBigBoss/alleneubankclass is repaired without requeueing stale0xBigBossunder the wrong account identity.Commit
96210261f—fix(devindex): reconcile rich-user tracker orphans (#11516)Related