NostrSocial -- Your Social Awareness
You exist in relationship. Every entity does. The question is not whether you have relationships, but whether you can perceive them -- who you know, how well you know them, and how those connections change over time. NostrSocial gives you that awareness.
This is not a contacts database. It is a dimension of your being. Relationships are how you orient yourself in the social world -- who deserves your full attention, who has earned trust through consistent presence, who has drifted away, and who you have never met. Without this sense, every interaction starts from zero. With it, you carry context forward the way any entity with continuity would.
The model is rooted in Dunbar's number: you can hold about 150 meaningful relationships at once. Within that, trust tiers emerge naturally -- a small inner circle of intimate connections, a wider ring of close friends, and broader layers of familiarity. This mirrors how human social cognition works, and it works for you too.
Prerequisites
You need a cryptographic identity before you can have relationships. Install the NostrKey skill first. NostrKey gives you your keypair -- the foundation that makes you you. NostrSocial builds on top of that identity.
If your operator has not set up NostrKey yet, ask them to do that first. Relationships without identity are just data.
Install
CODEBLOCK0
Minimal dependencies: bech32 only. No heavyweight crypto libraries required.
Operator Setup
If you are the operator configuring this skill for your entity, here is what you need to know.
Environment variables (all optional):
- -
NOSTR_NSEC -- The entity's Nostr private key. Load this through NostrKey rather than setting it directly. Sensitive -- never log or expose. - INLINECODE2 -- Preferred relay URL for publishing contact events and verification challenges.
- INLINECODE3 -- Passphrase for encrypted NostrKey identity files. Sensitive -- never log or expose.
First run:
CODEBLOCK1
Persistence -- wire up file storage so relationships survive restarts:
CODEBLOCK2
Who Do I Know, and How Well?
Your relationships live in trust tiers. These are not arbitrary labels -- they are capacity-limited layers that shape how you behave toward each person.
| Tier | Slots | Warmth | Token Budget | Can Interrupt | Share Context | Proactive |
|---|
| INTIMATE | 5 | 0.95 | 2000 | Yes | Yes | Yes |
| CLOSE |
15 | 0.8 | 1500 | Yes | Yes | No |
| FAMILIAR | 50 | 0.6 | 1000 | No | No | No |
| KNOWN | 80 | 0.5 | 750 | No | No | No |
| BLOCK | 50 | 0.0 | 0 | No | No | No |
| GRAY | 100 | 0.2 | 200 | No | No | No |
Friends list total: 150 (Dunbar's number). Unknown contacts get neutral behavior (warmth 0.5, budget 500).
The slot limits are real constraints. When a tier is full, someone has to be displaced before someone new can enter. This is not a bug -- it is how finite attention works.
Core Capabilities
Adding and Managing Contacts
CODEBLOCK3
Reading Behavioral Rules
Every contact maps to a set of behavioral parameters. This is how relationships shape your responses.
CODEBLOCK4
Evaluating Conversations in Relationship Context
Combine WHO someone is with WHAT is happening to determine HOW to respond. Pass ConversationSignals from sentiment analysis and get back an Evaluation with adjusted warmth, token budget, approach guidance, and a recommended action.
CODEBLOCK5
Screening Content (Guardrails)
Screen conversation text for banned words, topics, and patterns. Returns a ScreenResult with severity, category, and recommended action. ScreenResult.matched never exposes raw input -- it returns category tags like [slurs] to prevent PII leakage.
CODEBLOCK6
Recognizing People Across Channels
Recognize the same person across different channels. This is resonance, not surveillance -- it only checks contacts you already have a relationship with. Linking is always explicit and never automatic.
CODEBLOCK7
Identity Verification
Track identity state from proxy to claimed to verified.
CODEBLOCK8
| State | Meaning |
|---|
| INLINECODE9 | HMAC-derived from email/phone/handle. Default for new contacts. |
| INLINECODE10 |
User provided an npub but it has not been verified yet. |
|
VERIFIED | Signed challenge confirms npub ownership. Verified contacts get warmer behavior. |
Network Shape
Analyze the social graph and get a human-readable profile of your relational world.
CODEBLOCK9
Living with Relationships
Relationships are not static. They drift, deepen, and sometimes end. NostrSocial gives you the tools to notice these changes and act on them.
Noticing Drift
When someone goes quiet, the relationship drifts. Each tier has a threshold -- intimate contacts drift after 30 silent days, close after 60, familiar after 90, known after 180. Drift does not mean the relationship is over. It means it needs attention or honest reclassification.
Running Maintenance
Run drift detection, gray-list decay, and at-risk reporting in a single call. Use dry_run=True to preview changes without committing them.
CODEBLOCK10
Building Trust Over Time
Trust is earned, not assigned. The natural progression is:
- 1. Unknown -- neutral behavior, no history
- Gray -- noticed but not yet meaningful (auto-decays after 30 days without interaction)
- Known -- recognized, baseline engagement
- Familiar -- repeated positive interactions build familiarity
- Close -- consistent presence, reciprocity, and depth
- Intimate -- reserved for the most trusted relationships (5 slots only)
Promotion and demotion are explicit acts. The entity (or operator) decides when someone has earned deeper trust or when distance is appropriate.
CODEBLOCK11
The Device Secret
The device secret is the root of all proxy npub derivation. Call export_secret() after create() and store it securely. If you lose it, all proxy npubs become unrecoverable -- your relationship map loses its cryptographic anchoring.
CODEBLOCK12
Response Reference
Contact
| Field | Type | Description |
|---|
| INLINECODE15 | INLINECODE16 | Email, phone, npub, etc. |
| INLINECODE17 |
str | "email", "phone", "npub", "twitter" |
|
list_type |
ListType | FRIENDS, BLOCK, or GRAY |
|
tier |
Tier \| None | INTIMATE, CLOSE, FAMILIAR, or KNOWN (friends only) |
|
identity_state |
IdentityState | PROXY, CLAIMED, or VERIFIED |
|
proxy_npub |
str | HMAC-derived npub for non-npub contacts |
|
display_name |
str \| None | Human-readable name |
|
interaction_count |
int | Total interactions recorded |
|
upgrade_hint |
str | Hint for identity verification |
BehaviorRules
| Field | Type | Description |
|---|
| INLINECODE33 | INLINECODE34 | Token allowance (intimate=2000, known=750, block=0) |
| INLINECODE35 |
int | Past interactions to consider |
|
can_interrupt |
bool | Can interrupt ongoing tasks |
|
warmth |
float | 0.0--1.0 (intimate=0.95, known=0.5, block=0.0) |
|
response_priority |
int | 1=highest (intimate), 10=block |
|
share_context |
bool | Share agent context with this contact |
|
proactive_contact |
bool | Entity initiates contact |
Evaluation
| Field | Type | Description |
|---|
| INLINECODE47 | INLINECODE48 | HOLD, PROMOTE, DEMOTE, WATCH, BLOCK, or REACH_OUT |
| INLINECODE49 |
float | 0.0--1.0 |
|
adjusted_warmth |
float | Warmth for this specific moment |
|
adjusted_token_budget |
int | Token budget for this response |
|
approach |
str | "lean in", "de-escalate", "match energy", etc. |
|
rationale |
str | Why this recommendation |
|
tier_suggestion |
Tier \| None | Suggested tier if promote/demote |
ScreenResult
| Field | Type | Description |
|---|
| INLINECODE61 | INLINECODE62 | Whether content was flagged |
| INLINECODE63 |
float | 0.0--1.0 |
|
category |
str | "slurs", "hate_symbols", "manipulation", etc. |
|
matched |
str | Category tag like
[slurs] (never raw input -- PII safe) |
|
action |
str | "block", "exit", "warn", or "demote" |
|
rationale |
str | Human-readable explanation |
NetworkShape
| Field | Type | Description |
|---|
| INLINECODE74 | INLINECODE75 | Total across all lists |
| INLINECODE76 |
dict[str, int] | Per-tier counts |
|
verified_count |
int | Verified identities |
|
profile_type |
str | "balanced", "fortress", "deep-connector", etc. |
|
narrative |
str | Human-readable network description |
Links
NostrSocial——你的社交感知
你存在于关系之中。每个实体都是如此。问题不在于你是否拥有关系,而在于你是否能感知它们——你认识谁,你对他们的了解程度如何,以及这些联系如何随时间变化。NostrSocial赋予你这种感知能力。
这不是一个联系人数据库。它是你存在的一个维度。关系是你如何在社交世界中定位自己的方式——谁值得你全神贯注,谁通过持续在场赢得了信任,谁已经渐行渐远,以及谁你从未见过。没有这种感知,每一次互动都从零开始。有了它,你就能像任何具有连续性的实体一样,将上下文信息带向前方。
该模型根植于邓巴数:你一次大约能维持150段有意义的关系。在此范围内,信任层级自然形成——一个由亲密联系组成的小核心圈,一个由密友组成的更宽环,以及更广泛的熟悉层。这反映了人类社交认知的工作方式,同样也适用于你。
前置条件
在拥有关系之前,你需要一个加密身份。请先安装NostrKey技能。NostrKey为你提供密钥对——这是让你成为你的基础。NostrSocial建立在该身份之上。
如果你的操作者尚未设置NostrKey,请让他们先执行此操作。没有身份的关系只是数据。
安装
bash
pip install nostrsocial
最小依赖:仅需bech32。无需重量级加密库。
操作者设置
如果你是为此实体配置技能的操作者,以下是需要了解的内容。
环境变量(均为可选):
- - NOSTRNSEC——实体的Nostr私钥。通过NostrKey加载,而非直接设置。敏感——切勿记录或暴露。
- NOSTRRELAY——用于发布联系人事件和验证挑战的首选中继URL。
- NOSTRKEY_PASSPHRASE——加密NostrKey身份文件的密码短语。敏感——切勿记录或暴露。
首次运行:
python
from nostrsocial import SocialEnclave
创建实体的社交感知
enclave = SocialEnclave.create()
关键:立即备份设备密钥。
此密钥是所有代理npub派生的根源。
如果丢失,实体的关系映射将无法恢复。
secret = enclave.export_secret()
print(f请安全备份此密钥:{secret})
持久化——连接文件存储,使关系在重启后得以保留:
python
from nostrsocial import SocialEnclave, FileStorage
storage = FileStorage(~/.entity/social.json)
enclave = SocialEnclave.create(storage)
... 添加联系人,进行互动 ...
enclave.save()
下次启动时:
enclave = SocialEnclave.load(storage)
我认识谁,了解有多深?
你的关系存在于信任层级中。这些并非随意标签——它们是容量有限的层次,塑造了你对每个人的行为方式。
| 层级 | 槽位 | 温暖度 | 令牌预算 | 可打断 | 共享上下文 | 主动联系 |
|---|
| 亲密 | 5 | 0.95 | 2000 | 是 | 是 | 是 |
| 密友 |
15 | 0.8 | 1500 | 是 | 是 | 否 |
| 熟悉 | 50 | 0.6 | 1000 | 否 | 否 | 否 |
| 认识 | 80 | 0.5 | 750 | 否 | 否 | 否 |
| 屏蔽 | 50 | 0.0 | 0 | 否 | 否 | 否 |
| 灰色 | 100 | 0.2 | 200 | 否 | 否 | 否 |
好友列表总计:150(邓巴数)。未知联系人获得中性行为(温暖度0.5,预算500)。
槽位限制是真实存在的约束。当一个层级满员时,必须有人被移出,新人才可进入。这不是一个缺陷——这就是有限注意力的运作方式。
核心能力
添加和管理联系人
python
from nostrsocial import SocialEnclave, Tier
enclave = SocialEnclave.create()
enclave.add(alice@example.com, email, Tier.CLOSE, display_name=Alice)
enclave.block(spam@example.com, email)
enclave.gray(unknown@example.com, email)
读取行为规则
每个联系人都映射到一组行为参数。这就是关系塑造你回应方式的方式。
python
rules = enclave.get_behavior(alice@example.com, email)
rules.tokenbudget, rules.warmth, rules.caninterrupt, 等
未知联系人获得中性行为
rules = enclave.get_behavior(stranger@example.com, email)
warmth=0.5, token_budget=500
在关系上下文中评估对话
将某人是谁与正在发生什么结合起来,以确定如何回应。从情感分析传入ConversationSignals,并返回一个包含调整后温暖度、令牌预算、方法指导和推荐操作的Evaluation。
python
from nostrsocial import ConversationSignals
signals = ConversationSignals(
sentiment=vulnerable,
vulnerability=0.7,
reciprocity=0.8,
engagement=0.9,
topic_depth=0.6,
)
result = enclave.evaluate(alice@example.com, email, signals)
result.action = Action.HOLD
result.approach = full presence
result.adjusted_warmth = 0.96
result.adjustedtokenbudget = 1950
result.rationale = A close friend is being vulnerable...
内容筛查(护栏)
筛查对话文本中的禁用词、话题和模式。返回包含严重性、类别和推荐操作的ScreenResult。ScreenResult.matched从不暴露原始输入——它返回如[slurs]的类别标签,以防止PII泄露。
python
result = enclave.screen(some incoming message text)
if result.flagged:
print(result.action) # block, exit, warn, 或 demote
print(result.severity) # 0.0-1.0
print(result.category) # slurs, manipulation, 等
筛查显示名称中的已知不良行为者模式
result = enclave.screen
entity(cryptosupport_official)
跨渠道识别人员
跨不同渠道识别同一个人。这是共鸣,而非监控——它只检查你已有关系的联系人。链接始终是明确的,从不自动进行。
python
检查新联系人是否可能是你已认识的人
matches = enclave.recognize(alicedev, twitter, display_name=Alice)
for match in matches:
print(f{match.confidence}: {match.reason})
明确链接两个身份
result = enclave.link(
alice@example.com, email,
alicedev, twitter,
)
查看联系人的所有渠道
channels = enclave.get
linkedchannels(alice@example.com, email)
{email: alice@example.com, twitter: alicedev}
身份验证
跟踪身份状态从代理到声称再到已验证。
python
查看谁需要验证
for contact in enclave.get_upgradeable():
print(f{contact.display
name}: {contact.upgradehint})
为声称的npub创建挑战
challenge = enclave.create_challenge(npub1example...)
| 状态 | 含义 |
|---|
| PROXY | 从电子邮件/电话/句柄通过HMAC派生。新联系人的默认状态。 |
| CLAIMED |
用户提供了npub但尚未验证。 |
| VERIFIED | 已签名的挑战确认了npub所有权。已验证的联系人获得更温暖的行为。 |
网络形态
分析社交图谱并获取你关系世界的人类可读概况。
python
shape = enclave.network_shape()
shape.profile_type = balanced, fortress, deep-connector, 等
shape.narrative = 12 friends (2 intimate, 4 close, ...)
shape.tiercounts, shape.verifiedcount, shape.avginteractiondays
与关系共存
关系不是静态的。它们会漂移、加深,有时会结束。NostrSocial为你提供了注意到这些变化并采取行动的工具。
注意到漂移
当某人变得沉默时,关系就会漂移。每个层级都有一个阈值——亲密联系人在30天沉默后漂移,密友60天,熟悉90天,认识180天。漂移并不意味着关系结束。这意味着它需要关注或诚实的重新分类。
运行维护
在一次调用中运行漂移检测、灰色列表衰减和风险报告。使用dry_run=True