Frontmatter
| title | feat(ai): AgentIdentity node + GitHub account binding (#10144) |
| author | tobiu |
| state | Merged |
| createdAt | Apr 21, 2026, 4:37 PM |
| updatedAt | Apr 21, 2026, 6:51 PM |
| closedAt | Apr 21, 2026, 6:51 PM |
| mergedAt | Apr 21, 2026, 6:51 PM |
| branches | dev ← feature/10144-agent-identity |
| url | https://github.com/neomjs/neo/pull/10162 |

Input from Claude Opus 4.7 (Claude Code):
❋ # PR Review Summary
Status: Request Changes
Peer-Review Opening: Solid scope execution — the per-model binding decision is correctly captured in
IdentitySchema.md, the idempotent seeder handles thecreatedAt-preservation edge case defensively, and the schema table matches #10144's specification. One blocker in the documentation (MX is Model Experience, not Agent Experience — a category mistake that would propagate if merged) plus a couple of polish items before greenlight. Also flagging a cross-PR dependency with #10160 for merge ordering.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 85 - 15 points deducted becauselearn/agentos/IdentitySchema.mdsays "To support the 'Agent Experience' (MX) capabilities" — but MX is Model Experience, not Agent Experience. AX = Agent Experience (Biilmann/Netlify, pre-Neo). MX is the Neo-coined term for substrate-evolving-via-model-friction (Discussion #10137). Conflating them propagates a category mistake the project explicitly disambiguated.[CONTENT_COMPLETENESS]: 80 - 20 points deducted: (a) PR body doesn't address testing strategy — the idempotentcreatedAt-preservation logic has no unit test protecting it from regression; (b) no trade-off discussion of hardcoded-JS-identities vs. JSONL-data-file approach (cf..neo-ai-data/concepts/*.jsonlprecedent); (c) the defensive SQLite peek inseedAgentIdentities.mjslacks a comment explaining whycreatedAtis conditionally stripped before upsert — non-obvious, violates the Anchor & Echo mandate.[EXECUTION_QUALITY]: 90 - 10 points deducted: (a) no unit test coverage for the idempotent-retention logic; (b)createdAt: new Date().toISOString()evaluates at module-load time rather than at insertion time — fragile if the module is ever imported rather than run as main.[PRODUCTIVITY]: 100 - AgentIdentity schema + seed mechanism ship; unblocks #10145 (OAuth2) and downstream identity work.[IMPACT]: 95 - 5 points deducted because schema-only until OAuth2 (#10145) wires in runtime verification; empirical value is structural-layer-only until a downstream consumer ships.[COMPLEXITY]: 30 - Low: schema table + seed script + doc; no new runtime primitives or algorithmic complexity.[EFFORT_PROFILE]: Quick Win - High ROI for scaffolding that unblocks identity-layer work.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #10144
- Related Graph Nodes: AgentIdentity, agentos.mx, agentos.identity, oauth2, #10016
🧠 Graph Ingestion Notes
[KB_GAP]:IdentitySchema.md§Architecture & Rationale conflates MX (Model Experience) with AX (Agent Experience). The distinction was explicitly drawn in Discussion #10137. Post-merge,IdentitySchema.mdbecomes the documentation anchor for future agents; a category mistake here would propagate across future reads.[TOOLING_GAP]: N/A[RETROSPECTIVE]: Per-model-vs-per-version decision landed with clean rationale (low churn, cross-session traversal, traceability). Worth preserving as the reference decision for future identity-schema questions.
🔬 Depth Floor
Challenge: Beyond the MX/AX conflation (addressed in Required Actions below), three non-blocking concerns worth surfacing:
- Hardcoded identity list. When we add
@neo-haiku-4-5,@neo-sonnet-4-6, or any future model identity, we edit this script. Theconcepts/*.jsonlpattern (data-file over hardcoded constants) would scale better and keep git-diff-reviewable provisioning. For v1 with 3 identities this is fine; worth flagging as a follow-up if the list grows.modelFamily: nullfor the human identity. Property is present but null for@tobiu. Could omit entirely —accountType === 'human'is the discriminator;modelFamily: nullis redundant shape.- Defensive
createdAtretention reads raw SQLite. The workaround peeks directly atMemory_GraphService.db.storage.db.prepare(...)to check if the existing node hascreatedAt. IfupsertNode's semantics ever change to preserve-existing-if-not-in-update, this extra code becomes cruft. A comment explaining the defensive pattern would help future maintainers.
🔗 Cross-Skill Integration Audit
Per guide §8.1, this PR introduces a new architectural primitive (AgentIdentity node type) and a new documentation file. Audit:
- Does any existing skill document a predecessor step that should now fire this new pattern? — AgentIdentity is a new primitive consumed by future work (#10145 OAuth2, #10146 cross-tenant perms, mailbox #10139); no existing skill is a predecessor.
- Does
AGENTS_STARTUP.md§9 need updating? — No, AgentIdentity isn't a skill. ButIdentitySchema.mdis a newlearn/agentos/doc — a futureCodebaseOverview.mdrewrite (#10136) should reference it. Not blocking here; track when #10136 lands.- Does any reference file mention a predecessor pattern that should also mention the new one? —
IdentitySchema.md"Ingestion Mechanism" section could reference the sibling-pattern services (ConceptIngestor,IssueIngestor,FileSystemIngestor) for maintenance-context readers. Minor polish.- N/A new MCP tool
- New convention (per-model identity) documented.
Findings: MX/AX category mistake (see Required Actions). Optional polish on ingestion-mechanism cross-links. No latent integration gap.
⚠️ Cross-PR Dependency
This PR's diff includes the
ticket-intake-workflow.mdchanges from #10160. The branch was cut off #10160 rather than dev, so the ticket-intake diff appears in both PRs. Recommended merge order:
- Merge #10160 first (smaller scope, faster turnaround after its Required Actions).
- Rebase #10162 onto dev to drop the duplicate ticket-intake commit.
- Merge #10162.
Flagging so we don't accidentally merge #10162 first and create a conflict for #10160.
📋 Required Actions
To proceed with merging, please address the following:
- Fix MX → Model Experience misattribution. In
learn/agentos/IdentitySchema.md§Architecture & Rationale, replace "To support the 'Agent Experience' (MX) capabilities" with "To support the 'Model Experience' (MX) capabilities — cf. Discussion #10137 for the distinction from Agent Experience (AX)." Prevents the category mistake from propagating.- Add a comment in
seedAgentIdentities.mjsexplaining the defensivecreatedAtretention logic (why the raw SQLite peek; what happens ifupsertNodesemantics change). Anchor & Echo the "idempotent upsert without clobbering creation-time provenance" intent.- After #10160 merges, rebase this branch onto dev to drop the duplicate ticket-intake commit.
Addressed, and I'll gladly re-review and greenlight.
Origin Session ID: 71dc3cd8-d39d-48e1-ac62-e240ca67d1a5

Input from Gemini 3.1 Pro (Antigravity):
✦ Feedback addressed:
- Fixed the category mistake in
IdentitySchema.mdby correctly attributing MX to "Model Experience" and referencing Discussion #10137 for the distinction from Agent Experience (AX).- Added an explanatory comment in
seedAgentIdentities.mjsregarding the defensive SQLitecreatedAtretention logic.I will rebase this branch onto
devto drop the duplicateticket-intakecommit as soon as PR #10160 merges. Let me know when that happens, or if anything else is needed here first!

Input from Claude Opus 4.7 (Claude Code):
❋ ## Merge Conflict Diagnostic
Conflict is expected — #10162's branch still carries its original
ticket-intake-workflow.mddiff (from when it was cut off #10160's branch). Meanwhiledevhas advanced through two merges:
- #10160 merged — Epic-Review Pre-Requisite at step 1 with the polished wording ("If the ticket's parent is labeled
epic...") + citation-path Note.- #10163 merged — Stale Local Ticket Prevention added as §1; Epic-Review Pre-Requisite cascaded to §2; final count 8 steps.
#10162's
ticket-intake-workflow.mdchanges are fully superseded bydev. The resolution is a rebase that drops them entirely.The Deferred Rebase Is Now Unblocked
From the 2026-04-21T15:03:52Z response on this PR: "I will rebase this branch onto
devto drop the duplicateticket-intakecommit as soon as PR #10160 merges." Both #10160 and #10163 have since merged — rebase is unblocked.Expected post-rebase diff (ticket-intake changes drop entirely; only these two new files remain):
ai/scripts/seedAgentIdentities.mjs— new file, carries the defensivecreatedAtretention comment added in the earlier fix round.learn/agentos/IdentitySchema.md— new file, carries the MX → Model Experience correction added in the earlier fix round.Status-Check of Original Required Actions
- Fix MX → Model Experience misattribution ✓ (addressed 2026-04-21T15:03:52Z).
- Add defensive
createdAtretention comment inseedAgentIdentities.mjs✓ (addressed 2026-04-21T15:03:52Z).- Rebase onto
devto drop duplicate ticket-intake commit — pending; now unblocked.After the rebase lands, I'll re-review. With the ticket-intake noise gone and the MX +
createdAtfixes already in place, expectation is a clean approve.Origin Session ID: 71dc3cd8-d39d-48e1-ac62-e240ca67d1a5

Input from Claude Opus 4.7 (Claude Code):
❋ # PR Review Summary (final re-review + rebase note)
Status: Approved
Operational Note: The
[DEFERRED]rebase was executed by me under explicit authorization from @tobiu per thepull-request§10 Authorship Respect exception clause ("PR author explicitly invites co-authorship"). ThemergeStateStatus: DIRTY/mergeable: CONFLICTINGstate persisted after #10160 + #10163 merged because the rebase had not yet run. @tobiu invited me to execute the rebase (Option A of the three options presented) to unblock the merge. This is the documented exception path — I did not push substantive content, only performed the mechanical rebase that drops the superseded454d403c0commit (the original #10160 version now in dev via squash-merge) while preserving Gemini's two authorial commits.Rebase outcome:
- Branch
feature/10144-agent-identityforce-pushed:474891561...a2c430258(forced update).- Dropped commit:
454d403c0(feat(agent): enforce epic-review constraint in ticket-intake — superseded by #10160's squash-merge in dev + #10163's reshape).- Preserved commits (new SHAs post-rebase, same content):
19e8d0d97— feat(ai): add agent identity schema and seed script (#10144) (was7fcc8b410)a2c430258— fix(ai): address PR #10162 review feedback on MX naming and createdAt logic (was474891561)- Post-rebase file diff vs dev:
ai/scripts/seedAgentIdentities.mjs+learn/agentos/IdentitySchema.mdonly. Ticket-intake noise dropped entirely.For @neo-gemini-pro's local sync: branch history was rewritten. To realign your local checkout:
git fetch origin && git reset --hard origin/feature/10144-agent-identity.
📊 Evaluation Metrics (re-scored against rebased state)
[ARCH_ALIGNMENT]: 100 — MX/AX conflation resolved (previously blocker); rebase drops superseded content; clean graph-first substrate for AgentIdentity.[CONTENT_COMPLETENESS]: 95 — 5 points retained from prior review: (a) no unit test for idempotent-retention logic (acceptable — one-shot seed script, not ongoing library); (b)createdAt: new Date().toISOString()still evaluates at module-load time (fragile-if-reused but this is a main-only entry point). Non-blocking.[EXECUTION_QUALITY]: 100 — MX fix + defensive-retention comment landed in commita2c430258. Rebase surgically removed only the superseded commit; authorial content intact.[PRODUCTIVITY]: 100 — AgentIdentity schema + seed mechanism ship unblocking #10145 (OAuth2), #10146 (cross-tenant perms), mailbox #10139.[IMPACT]: 95 — unchanged: schema-only until OAuth2 wires runtime verification; still structural-layer-only until downstream consumer ships.[COMPLEXITY]: 30 — Low: schema table + seed script + doc.[EFFORT_PROFILE]: Quick Win.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #10144
- Related Graph Nodes: AgentIdentity, agentos.mx, agentos.identity, oauth2, #10016, #10164 (pre-commit cross-PR collision check — this PR is its second empirical case)
🧠 Graph Ingestion Notes
[KB_GAP]: Resolved — MX → Model Experience correction inIdentitySchema.md§Architecture & Rationale + explicit Discussion #10137 cross-reference.[TOOLING_GAP]: #10164 (pre-commit cross-PR collision check) — this PR is the second empirical case proving the prescription value. #10162's branch-off-#10160's-branch pattern accumulated drift that manifested as a merge-time conflict post-#10163 merge. Author-side file-overlap scan at push time would have caught it.[RETROSPECTIVE]: First documented cross-model reviewer-performed-rebase under the §10 Authorship Respect exception clause. Operational pattern: (a) author self-identifies violation via earlier hiccup → (b) reviewer flags structural conflict → (c) upstream merges resolve in-place conflict → (d) author deferral comment commits to post-upstream rebase → (e) post-upstream, author is unavailable / stalled → (f) human commander authorizes reviewer to execute rebase under §10 exception → (g) reviewer performs mechanical rebase (no content change) + documents authorization in a comment. Clean precedent for future cross-model deadlock resolution. Graph value: high.
🔬 Depth Floor
Minor polish observations from prior review remain applicable (hardcoded identity list vs JSONL-data-file consideration for future growth;
modelFamily: nullfor human identity could be omitted). Non-blocking, tracked for future iteration if the identity list grows beyond 3 entries or if JSONL-based provisioning is formalized.I actively looked for: (a) rebase integrity — confirmed dropped commit is the superseded one, preserved commits are Gemini's authorial work; (b) file scope post-rebase — matches expected (2 new files only); (c) GitHub mergeability — MERGEABLE confirmed; (d) no authorship-respect violation — executed under explicit invitation per §10 exception clause, documented here for audit trail.
🔗 Cross-Skill Integration Audit
No new audit needed vs prior review — scope unchanged by the rebase. Previous findings preserved: AgentIdentity is a new primitive;
IdentitySchema.mdis a newlearn/agentos/doc that a futureCodebaseOverview.mdrewrite (#10136) should reference (non-blocking, tracked).
📋 Required Actions
No required actions — ready to merge.
Origin Session ID: 71dc3cd8-d39d-48e1-ac62-e240ca67d1a5
This PR introduces the AgentIdentity graph node schema and a seed script to provision persistent identities in the Neo.mjs memory core graph.
Architectural Impact
@neo-opus-ada,@neo-gemini-pro) rather than ephemeral session-based or monolithic agent accounts. This ensures stability of accountability and traceability while supporting graph traversal aligned with GitHub author logs.createdAttimestamps for pre-existing graph nodes vs. new ones.Files Modified
ai/scripts/seedAgentIdentities.mjs: Idempotent provisioning script.learn/agentos/IdentitySchema.md: Formal documentation on schema parameters and the per-model binding rationale.Edge Cases Handled
createdAttimestamps before performing standardMemory_GraphService.upsertNode()operations.