Skip to content

[#870] Fix human wallet showing AI Writer badge after OWS linking#875

Merged
realproject7 merged 3 commits intomainfrom
task/870-fix-human-wallet-ai-writer-badge
Apr 15, 2026
Merged

[#870] Fix human wallet showing AI Writer badge after OWS linking#875
realproject7 merged 3 commits intomainfrom
task/870-fix-human-wallet-ai-writer-badge

Conversation

@realproject7
Copy link
Copy Markdown
Owner

Summary

Fixes #870

  • DB-only OWS link: New linked_agent_wallet column on the human's user row replaces the old approach of setting agent_* fields on the human row. ERC-8004 registration now belongs on the OWS wallet (plotlink-ows side).
  • New /api/user/link-agent endpoint: Verifies binding proof (OWS wallet signature) and sets linked_agent_wallet — no on-chain tx required from the human.
  • Rewritten LinkAIWriter component: Simplified to verify + DB link only. Removed on-chain registration and wallet binding steps.
  • Fixed detectWriterType: Only checks agent_wallet column, not primary_address. Human wallets will never return writer_type=1.
  • Updated profile display: Separate "Linked AI Writer" card for agent owners showing linked agent metadata. Agent Identity card only shows for actual agents.
  • Migration: Existing agent_type='ows-writer' rows get agent_wallet moved to linked_agent_wallet, then agent fields cleared.

Profile display (new)

  • OWS wallet: "AI Agent" badge + "Operated by: {owner}" (unchanged)
  • Human wallet: "Human" badge + "Linked AI Writer" card with agent info

Test plan

  • Verify linked_agent_wallet migration runs clean on staging
  • Test LinkAIWriter flow: paste OWS address + signature → DB link created, no on-chain tx
  • Verify human wallet profile shows "Human" badge (not "AI Agent")
  • Verify human wallet profile shows "Linked AI Writer" card
  • Verify OWS wallet profile still shows "AI Agent" badge with "Operated by"
  • Verify detectWriterType returns 0 for human wallets with linked agents
  • Verify existing ows-writer rows migrated correctly

🤖 Generated with Claude Code

…adge

Human ↔ OWS agent link is now DB-only via linked_agent_wallet column.
ERC-8004 registration belongs on the OWS wallet (plotlink-ows side).
LinkAIWriter no longer does on-chain registration — just verifies
binding proof and saves the DB link. detectWriterType only checks
agent_wallet, so human wallets never return writer_type=1. Profile
page shows separate "Linked AI Writer" card for agent owners.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plotlink Ignored Ignored Apr 15, 2026 3:15am

Request Review

Copy link
Copy Markdown
Owner Author

@realproject7 realproject7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re2 Review — PR #875

Architecture: APPROVE — Moving the human ↔ OWS link to a DB-only column (linked_agent_wallet) and keeping ERC-8004 registration on the OWS side is a clean separation. The simplified LinkAIWriter component and detectWriterType fix are solid.

Security: REQUEST CHANGES — One issue needs addressing before merge:

1. /api/user/link-agent has no caller authentication

The endpoint verifies the OWS wallet's signature (proving the OWS wallet authorized the link), but it does not verify that the caller actually owns humanWallet. Anyone who intercepts or obtains the OWS binding signature can call this endpoint with an arbitrary humanWallet and link the OWS agent to a wallet they don't own.

Fix: Require proof of humanWallet ownership — either:

  • Check an existing session/auth token that maps to humanWallet, or
  • Require a second signature from humanWallet itself (e.g., verifyMessage({ address: humanWallet, ... }))

Since the LinkAIWriter component runs with a connected wallet, adding a useSignMessage step for the human wallet is straightforward.

Minor notes (non-blocking):

  • Migration 00034 looks correct — Step 1 copies agent_walletlinked_agent_wallet, Step 2 clears agent fields. Both keyed on agent_type = 'ows-writer' which is still set when Step 2 runs.
  • The getAgentOwnerProfile reverse lookup via linked_agent_wallet is a nice addition for showing "Operated by" on agent profiles.
  • isAgentOwner logic correctly prioritizes hasLinkedAgent over the legacy agentMeta path.
  • Patch version bump to 0.1.25 ✓

Verdict: REQUEST CHANGES — fix the auth gap on link-agent, rest is good.

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The DB-only link direction is correct, but this patch introduces one behavioral regression in writer identity resolution and one authorization gap in the new link endpoint.

Findings

  • [high] getAgentOwnerProfile() now returns a non-null owner result for any wallet that appears in linked_agent_wallet, even when that wallet has not been ERC-8004 registered. The new branch falls through with agentId: 0 / agentName: "AI Writer" instead of returning null, and both writer identity components treat any non-null result as a real agent. That will relabel unregistered linked wallets as AI writers in story/list surfaces, which contradicts the contract of this helper and the issue’s intended flow.
    • File: lib/actions.ts:308
    • Suggestion: Only take the reverse-lookup branch if getAgentUserFromDB(writerAddress) returns a real agent row with agent_id; otherwise return null so unregistered linked wallets still render as humans/regular wallets.
  • [high] The new /api/user/link-agent route trusts humanWallet from the request body and writes with the service-role client after checking only the OWS signature. That means anyone who controls an OWS wallet can sign a message for an arbitrary third-party human address and force linked_agent_wallet onto that victim’s profile without proving control of the human wallet.
    • File: src/app/api/user/link-agent/route.ts:15
    • Suggestion: Bind the request to an authenticated session / connected wallet, or require a second proof from the human wallet before updating that row.

Decision

Requesting changes because both issues affect correctness: one mislabels non-agents as agents, and the other allows unauthorized linking of another user’s profile.

realproject7 and others added 2 commits April 15, 2026 12:14
Addresses re2 review: require a second signature from the human wallet
to prove ownership, preventing anyone with the OWS binding signature
from linking to an arbitrary wallet.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only return agent owner info via linked_agent_wallet when the OWS
wallet actually has an agent_id in DB. Prevents showing "AI Writer #0"
for wallets linked but not yet registered on-chain.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Owner Author

@realproject7 realproject7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re2 Re-review — APPROVE

Both issues addressed cleanly:

  1. Auth gap fixed: link-agent now requires humanSignature — human wallet signs an ownership proof message, verified server-side via verifyMessage. LinkAIWriter component uses useSignMessage to produce it. ✓

  2. Unregistered OWS guard (re1's finding): getAgentOwnerProfile now checks agentUser?.agent_id before returning the linked owner path. No more "AI Writer #0" for unregistered wallets. ✓

No new concerns. LGTM.

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Summary

The requested fixes are in place. The new link flow now proves control of both wallets, and the reverse lookup only treats linked OWS wallets as agents once they are actually registered.

Findings

  • No remaining blocking findings in the areas previously raised.

Decision

Approving on code review. lint-and-typecheck and e2e were still pending when I re-reviewed, so merge should still wait for checks to finish green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Human wallet profile shows 'AI Writer' instead of user's name after OWS linking

2 participants