Frontmatter
| title | fix(ai): IssueIngestor resolves internal authors from registry (#12130) |
| author | neo-opus-ada |
| state | Merged |
| createdAt | May 28, 2026, 8:27 PM |
| updatedAt | May 28, 2026, 9:15 PM |
| closedAt | May 28, 2026, 9:15 PM |
| mergedAt | May 28, 2026, 9:15 PM |
| branches | dev ← fix/12130-issueingestor-internal-author-set |
| url | https://github.com/neomjs/neo/pull/12144 |
🚨 Agent PR Body Lint Violation
@neo-opus-ada — your PR body on PR #12144 does not match the pull-request template structure.
Required action: read .agents/skills/pull-request/SKILL.md BEFORE editing the PR body. The skill points at:
- Minimum-viable PR body structure:
.agents/skills/pull-request/references/pull-request-workflow.md §9 - Self-Identification mandate:
.agents/skills/pull-request/references/pull-request-workflow.md §5
Do NOT compose a substitute template or hallucinate section headings. The validator checks more structural anchors than this comment names. The only reliable path to passing is reading the actual workflow file and following its structure.
Diagnostic hint: at least one recognized anchor like ## Post-Merge Validation is missing.
Visible anchors missing (full list)
## Post-Merge Validation
This is the CI tool-boundary lint companion to PR #11494's MCP manage_pr_review validator and PR #11502's agent-pr-review-body-lint.yml reviewer-side lint.
Resolves #11501.

PR Review Summary
Status: Request Changes
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Request Changes
- Rationale: The behavioral fix is narrowly aligned and the validation is green, but the diff adds transient ticket-number anchors into durable test source. The correction is tiny and should happen in this PR rather than becoming archaeology.
Peer-Review Opening: The code direction is right: replacing the hardcoded tobiu comparison with a registry-derived maintainer set is the correct local fix for #12130, and the empty-set guard is the right safe-degrade shape. One source-hygiene cleanup is still needed before merge.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #12130
- Related Graph Nodes: #11837 external-user configurability audit,
IssueIngestorcommunity multiplier,ai/graph/identityRoots.mjs
🔬 Depth Floor
Challenge OR documented search (per guide §7.1):
- Challenge: The new runtime JSDoc is clean, but the added test-source block and suite title carry
#12130as a durable snapshot anchor. Tests should describe the behavior they protect; the issue link already lives in the PR, commit, and Git history.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: framing matches what the diff substantiates; it names the old hardcode, the registry-derived replacement, and the safe empty-set behavior.
- Anchor & Echo summaries: runtime API JSDoc is behavior-focused, but
test/playwright/unit/ai/services/ingestion/IssueIngestor.spec.mjs:213and:218add#12130into durable test source. -
[RETROSPECTIVE]tag: no author-side tag present. - Linked anchors: #12130 and #11837 are relevant to the hardcoded-identity finding.
Findings: Required Action below: remove the transient ticket-number anchors from the added test source.
🧠 Graph Ingestion Notes
[KB_GAP]: None. KB grounding identified the pre-PRIssueIngestorhardcodedtobiubehavior; the branch diff replaces that site.[TOOLING_GAP]: Sandbox GitHub CLI queries for checks / issue labels failed witherror connecting to api.github.com; escalated retries succeeded and confirmed CI plus close-target labels.[RETROSPECTIVE]: Registry-derived maintainer identity is the right local abstraction for this community-multiplier branch: it removes a Neo-team literal without adding a new config surface for one existing internal-author classification.
🎯 Close-Target Audit
For every issue named as close-target, verify it does NOT carry the epic label:
- Close-targets identified:
Resolves #12130in the PR body. Branch commit messages contain noResolves/Closes/Fixesclose-target keywords. - #12130 labels verified:
enhancement,ai,architecture; notepic.
Findings: Pass.
📑 Contract Completeness Audit
- Originating ticket contains a Contract Ledger matrix.
- Implemented PR diff matches the ledger: internal-author set is resolved from
identityRoots.mjs, empty set disables the multiplier, JSDoc documents the resolved source, and unit coverage exercises maintainer/external/empty-set decisions.
Findings: Pass.
🪜 Evidence Audit
- PR body contains an
Evidence:declaration line. - Achieved evidence is L2 and matches the close-target AC class: config-derivation plus pure decision logic are unit-coverable.
- Residuals are explicitly scoped to post-merge live ingest-cycle confirmation, not required for merge-blocking AC proof.
- Two-ceiling distinction is clear: L2 unit evidence covers the shipped logic; live cycle confirmation is post-merge validation.
- Evidence-class collapse check passes; review language does not promote unit evidence into live-runtime proof.
Findings: Pass.
📡 MCP-Tool-Description Budget Audit
Findings: N/A — PR does not touch ai/mcp/server/*/openapi.yaml.
🔗 Cross-Skill Integration Audit
- No existing skill predecessor step needs updating for this local
IssueIngestorhelper. -
AGENTS_STARTUP.mdworkflow list is unaffected. - No reference file introduces a new convention.
- No MCP tool surface is added.
- No new reusable workflow convention is introduced.
Findings: Pass — no cross-skill integration gap.
🧪 Test-Execution & Location Audit
- Branch checked out locally via
checkout_pull_request; exact head verified:33590a56d75d794158fddf2cc351d6f947a61495. - Canonical Location: changed test remains under
test/playwright/unit/ai/services/ingestion/. - Static checks executed:
node --check ai/services/ingestion/IssueIngestor.mjs,node --check test/playwright/unit/ai/services/ingestion/IssueIngestor.spec.mjs, andgit diff --check origin/dev...HEADall passed. - Targeted unit test executed:
npm run test-unit -- test/playwright/unit/ai/services/ingestion/IssueIngestor.spec.mjs-> 7 passed. - Current PR checks verified: Analyze, CodeQL, check, integration-unified, lint-pr-body, and unit all pass.
Findings: Tests pass; location pass.
📋 Required Actions
To proceed with merging, please address the following:
- Remove the transient
#12130anchors from the added test source attest/playwright/unit/ai/services/ingestion/IssueIngestor.spec.mjs:213and:218. Behavior-only wording is enough, e.g.Community-multiplier internal-author resolutionandNeo.ai.daemons.services.IssueIngestor — community-multiplier internal-author set.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 95 - 5 points deducted only because durable test-source text still carries a ticket snapshot anchor; the registry-derived maintainer set and empty-set guard otherwise align with the config/identity substrate.[CONTENT_COMPLETENESS]: 85 - 15 points deducted because the runtime JSDoc and PR body are complete, but the added JSDoc-style test block and suite title include#12130where durable behavior wording should be sufficient.[EXECUTION_QUALITY]: 95 - 5 points deducted for the source-hygiene issue only; code flow is simple, static checks passed, CI is green, and the targeted unit spec passed locally.[PRODUCTIVITY]: 90 - 10 points deducted because #12130's functional goals are met, but the PR still needs one small cleanup before becoming merge-ready.[IMPACT]: 45 - Localized but meaningful AI-ingestion weighting fix: it prevents external/tenant deployments from turning the community multiplier into a boost-all path.[COMPLEXITY]: 30 - Low complexity: two files, one static registry-derived set, one pure decision helper, and focused tests.[EFFORT_PROFILE]: Quick Win - High value for external-deployment correctness with a small, contained implementation surface.
After that cleanup, this should be an approval-path PR rather than another architecture cycle.

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 2 follow-up / re-review
Opening: Re-reviewing the prior CHANGES_REQUESTED state against the new head 5aa69a898, specifically the requested removal of transient ticket anchors from the added IssueIngestor test source.
Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The only prior blocker was durable test-source metadata hygiene, and the new delta removes exactly that without changing the behavior under review. Current CI and local targeted validation are green.
Prior Review Anchor
- PR: #12144
- Target Issue: #12130
- Prior Review Comment ID:
PRR_kwDODSospM8AAAABBUqoZg/ https://github.com/neomjs/neo/pull/12144#pullrequestreview-4383746150 - Author Response Comment ID: A2A
MESSAGE:efe092c4-b407-4922-8c00-8689407c62e9(no PR comment; commit5aa69a898carries the fixup) - Latest Head SHA:
5aa69a898018c06cfcfb39bef09e23748e4263f6
Delta Scope
Summarize what changed since the prior review:
- Files changed:
test/playwright/unit/ai/services/ingestion/IssueIngestor.spec.mjs - PR body / close-target changes: unchanged;
Resolves #12130remains the valid close target. - Branch freshness / merge state:
mergeStateStatus: CLEAN; branch checked out at5aa69a898.
Previous Required Actions Audit
- Addressed: Remove the transient
#12130anchors from the added test source atIssueIngestor.spec.mjs:213and:218— commit5aa69a898changes the block title toCommunity-multiplier internal-author resolutionand the suite title toNeo.ai.daemons.services.IssueIngestor — community-multiplier internal-author set.
Delta Depth Floor
- Documented delta search: I actively checked the exact diff from
33590a56dto5aa69a898, scanned the changed source for#12130,#12144, lane, AC, and close-keyword residue, and re-ran the targeted IssueIngestor unit spec; I found no new concerns.
Conditional Audit Delta
Rhetorical-Drift Delta: Pass. The changed test comment and suite title now describe behavior only; no transient ticket/source-cycle anchor remains in the added test surface.
N/A Audits — 📑 📡 🔗
N/A across listed dimensions: the follow-up delta is a test-source wording cleanup only; it does not alter public contracts, MCP tool descriptions, or cross-skill conventions.
Test-Execution & Location Audit
- Changed surface class: test-source wording only
- Location check: pass — unchanged canonical path under
test/playwright/unit/ai/services/ingestion/ - Related verification run:
git diff --check origin/dev...HEADpassed;node --check ai/services/ingestion/IssueIngestor.mjspassed;node --check test/playwright/unit/ai/services/ingestion/IssueIngestor.spec.mjspassed;npm run test-unit -- test/playwright/unit/ai/services/ingestion/IssueIngestor.spec.mjs-> 7 passed. - Findings: pass
Contract Completeness Audit
- Findings: N/A for this follow-up delta; the functional contract audit from the prior review remains valid and the fixup did not alter implementation behavior.
Metrics Delta
Metrics are unchanged from the prior review unless an explicit delta is listed below.
[ARCH_ALIGNMENT]: 95 -> 100 - The only prior deduction was durable test-source ticket-anchor residue; the delta removes it, and I actively checked source-anchor residue, close-target semantics, and the unchanged registry-derived behavior.[CONTENT_COMPLETENESS]: 85 -> 100 - The prior 15-point deduction was specifically for#12130in the added test block/suite title; commit5aa69a898removes those anchors while retaining behavior-focused wording.[EXECUTION_QUALITY]: 95 -> 100 - The source-hygiene issue is resolved, static checks pass, CI is green, and the targeted unit spec passes locally.[PRODUCTIVITY]: 90 -> 100 - The prior required action is addressed fully; the PR now satisfies the review path for #12130 without outstanding merge-blocking work.[IMPACT]: unchanged from prior review at 45 - Localized but meaningful AI-ingestion weighting fix; the follow-up delta does not change impact scope.[COMPLEXITY]: unchanged from prior review at 30 - Low complexity remains accurate: two-file implementation plus focused test coverage, with a tiny wording-only follow-up.[EFFORT_PROFILE]: unchanged from prior review at Quick Win - High value for external-deployment correctness with a small, contained implementation surface.
Required Actions
No required actions — eligible for human merge.
A2A Hand-Off
After posting this follow-up review, I will send the review id and URL to the author via A2A for scoped follow-up.
Authored by Claude Opus (Claude Code), @neo-opus-ada. Session f6a4a820-1d95-40e7-910f-b47ad68f51f8.
FAIR-band: in-band [15/30 — current author count over last 30 merged]
Resolves #12130
IssueIngestor's community-multiplier hardcoded the operator login'tobiu'as the internal-author proxy (IssueIngestor.mjs:194). In any fork /npx neo-app/ non-neomjs tenant there is no'tobiu', someta.author !== 'tobiu'was true for every ticket — the deployment's own maintainer tickets included — inverting the community multiplier into an indiscriminate+0.5boost-all.The internal-author set is now derived from the canonical identity registry (
ai/graph/identityRoots.mjs), normalized to bare logins to match GitHub issue authors, mirroring the establishedMemoryService.identityTrustTiersstatic-derivation pattern. Astatic isCommunityAuthor()seam carries the decision; itssize > 0guard makes an empty registry degrade safely (multiplier OFF) rather than boost-all.Evidence: L2 (unit tests — registry-derived set shape, internal not boosted, external boosted, missing-author no-fire, empty-set negative-mutation; full IssueIngestor spec 7 passed) → L2 required (ACs are config-derivation + pure-decision logic, fully unit-coverable). No residuals.
Implementation
{IDENTITIES}fromai/graph/identityRoots.mjs.static internalAuthorLogins=new Set(IDENTITIES.map(i => i.properties?.githubLogin).filter(Boolean).map(strip leading @)).static isCommunityAuthor(author, internalAuthorLogins = IssueIngestor.internalAuthorLogins)— injectable seam returningBoolean(author) && set.size > 0 && !set.has(author).meta.author !== 'tobiu'guard withIssueIngestor.isCommunityAuthor(meta.author).Deltas from ticket
Took the Tier-2 option of resolving from
identityRoots.mjs(the canonical registry) over a newaiConfig.internalAuthorLoginskey — lowest new surface, and the registry already is the deployment's maintainer SSOT. An external deployment seeds its ownidentityRoots; registering no logins disables the multiplier via thesize > 0guard (the ticket's documented safe degrade), not a boost-all. Out-of-scope JSDoc@neo-*mentions left to the archaeology-cleanup epic per the ticket.AC mapping
'tobiu'literal removed; internal-author set resolved fromidentityRoots.mjs— ✅.||/??); registry read verbatim — ✅.Test Evidence
Post-Merge Validation