@ghostpaw/affinity 0.2.4 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +222 -9
- package/SKILL.md +283 -0
- package/dist/cli.js +10604 -0
- package/dist/database-C__PzPpi.d.cts +19 -0
- package/dist/database-C__PzPpi.d.ts +19 -0
- package/dist/index.d.cts +1 -17
- package/dist/index.d.ts +1 -17
- package/dist/mcp-server.js +9080 -0
- package/dist/mcp.cjs +7947 -0
- package/dist/mcp.d.cts +99 -0
- package/dist/mcp.d.ts +99 -0
- package/dist/mcp.js +7939 -0
- package/package.json +55 -10
- package/skills/affinity/SKILL.md +283 -0
- package/skills/affinity/references/bootstrap-and-cold-start.md +50 -0
- package/skills/affinity/references/capture-transactions-and-commercial-events.md +48 -0
- package/skills/affinity/references/identify-and-locate-contacts.md +51 -0
- package/skills/affinity/references/import-history-without-faking-evidence.md +50 -0
- package/skills/affinity/references/manage-promises-and-agreements.md +49 -0
- package/skills/affinity/references/manage-recurring-dates-and-reminders.md +49 -0
- package/skills/affinity/references/model-structure-orgs-and-households.md +50 -0
- package/skills/affinity/references/reconcile-duplicates-and-merge-safely.md +49 -0
- package/skills/affinity/references/record-direct-evidence-well.md +52 -0
- package/skills/affinity/references/record-observations-and-referrals.md +48 -0
- package/skills/affinity/references/review-radar-progression-and-graph.md +48 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ghostpaw/affinity",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Relationship intelligence and social CRM model for Node.js — SQLite, zero dependencies, with a built-in LLM tool facade",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"bugs": {
|
|
16
16
|
"url": "https://github.com/GhostPawJS/affinity/issues"
|
|
17
17
|
},
|
|
18
|
-
"homepage": "https://
|
|
18
|
+
"homepage": "https://affinity.ghostpaw.dev/",
|
|
19
19
|
"funding": {
|
|
20
20
|
"type": "github",
|
|
21
21
|
"url": "https://github.com/sponsors/Anonyfox"
|
|
@@ -45,9 +45,19 @@
|
|
|
45
45
|
"agent",
|
|
46
46
|
"tools",
|
|
47
47
|
"typescript",
|
|
48
|
-
"zero-dependencies"
|
|
48
|
+
"zero-dependencies",
|
|
49
|
+
"mcp",
|
|
50
|
+
"mcp-server",
|
|
51
|
+
"model-context-protocol",
|
|
52
|
+
"agent-skills",
|
|
53
|
+
"cli",
|
|
54
|
+
"ghostpaw",
|
|
55
|
+
"ai-agents",
|
|
56
|
+
"llm-tools",
|
|
57
|
+
"node-sqlite",
|
|
58
|
+
"local-first"
|
|
49
59
|
],
|
|
50
|
-
"files": ["dist"],
|
|
60
|
+
"files": ["dist", "skills", "SKILL.md"],
|
|
51
61
|
"main": "./dist/index.cjs",
|
|
52
62
|
"module": "./dist/index.js",
|
|
53
63
|
"types": "./dist/index.d.ts",
|
|
@@ -61,7 +71,18 @@
|
|
|
61
71
|
"types": "./dist/index.d.cts",
|
|
62
72
|
"default": "./dist/index.cjs"
|
|
63
73
|
}
|
|
64
|
-
}
|
|
74
|
+
},
|
|
75
|
+
"./mcp": {
|
|
76
|
+
"import": {
|
|
77
|
+
"types": "./dist/mcp.d.ts",
|
|
78
|
+
"default": "./dist/mcp.js"
|
|
79
|
+
},
|
|
80
|
+
"require": {
|
|
81
|
+
"types": "./dist/mcp.d.cts",
|
|
82
|
+
"default": "./dist/mcp.cjs"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"./package.json": "./package.json"
|
|
65
86
|
},
|
|
66
87
|
"scripts": {
|
|
67
88
|
"build": "tsup",
|
|
@@ -74,22 +95,46 @@
|
|
|
74
95
|
"lint:fix": "biome check --fix",
|
|
75
96
|
"format": "biome format --write",
|
|
76
97
|
"typecheck": "tsc --noEmit",
|
|
77
|
-
"check": "
|
|
98
|
+
"check": "npm run check:types && npm run check:lint && npm test && npm run build && npm run check:deps && npm run check:surfaces && npm run check:size && npm run check:api && npm run check:consumer && npm run check:startup && npm run check:ratchet",
|
|
99
|
+
"check:deps": "node scripts/check-zero-deps.mjs",
|
|
78
100
|
"clean": "rm -rf dist demo",
|
|
79
|
-
"version": "biome format --write package.json package-lock.json && git add package.json package-lock.json",
|
|
80
|
-
"prepublishOnly": "npm run check
|
|
101
|
+
"version": "node scripts/sync_version.mjs && npm run surfaces && git add src/version.ts SKILL.md skills plugin.json mcp.json server.json .claude-plugin mcpb && biome format --write package.json package-lock.json && git add package.json package-lock.json",
|
|
102
|
+
"prepublishOnly": "npm run check",
|
|
81
103
|
"release:patch": "npm version patch && git push && git push --tags",
|
|
82
104
|
"release:minor": "npm version minor && git push && git push --tags",
|
|
83
|
-
"release:major": "npm version major && git push && git push --tags"
|
|
105
|
+
"release:major": "npm version major && git push && git push --tags",
|
|
106
|
+
"surfaces": "node --experimental-strip-types scripts/surfaces/generate.mjs",
|
|
107
|
+
"check:surfaces": "node --experimental-strip-types scripts/surfaces/generate.mjs --check",
|
|
108
|
+
"check:types": "tsc --noEmit",
|
|
109
|
+
"check:lint": "biome check",
|
|
110
|
+
"check:ratchet": "node --test scripts/guard/*.test.mjs && node scripts/guard/ratchet.mjs",
|
|
111
|
+
"budgets:update": "npm run build && node scripts/guard/size.mjs --update && node scripts/guard/api.mjs --update && node scripts/guard/startup.mjs --update",
|
|
112
|
+
"bench": "npm run build && node scripts/bench/bench.mjs",
|
|
113
|
+
"check:size": "node scripts/guard/size.mjs",
|
|
114
|
+
"check:api": "node scripts/guard/api.mjs",
|
|
115
|
+
"check:consumer": "node scripts/guard/consumer.mjs",
|
|
116
|
+
"check:startup": "node scripts/guard/startup.mjs",
|
|
117
|
+
"mcpb": "node scripts/mcpb/build.mjs",
|
|
118
|
+
"sea": "node scripts/sea/build.mjs",
|
|
119
|
+
"sea:smoke": "node scripts/sea/smoke.mjs",
|
|
120
|
+
"sea:bench": "node scripts/sea/bench.mjs"
|
|
84
121
|
},
|
|
85
122
|
"devDependencies": {
|
|
86
123
|
"@biomejs/biome": "^1.9.4",
|
|
87
124
|
"@types/node": "^24.12.0",
|
|
88
125
|
"@types/sql.js": "^1.4.10",
|
|
89
|
-
"esbuild": "^0.
|
|
126
|
+
"esbuild": "^0.28.1",
|
|
127
|
+
"fflate": "0.8.3",
|
|
90
128
|
"preact": "^10.29.0",
|
|
91
129
|
"sql.js": "^1.14.1",
|
|
92
130
|
"tsup": "^8.4.0",
|
|
93
131
|
"typescript": "^5.8.2"
|
|
132
|
+
},
|
|
133
|
+
"bin": {
|
|
134
|
+
"ghostpaw-affinity": "./dist/cli.js"
|
|
135
|
+
},
|
|
136
|
+
"mcpName": "io.github.GhostPawJS/affinity",
|
|
137
|
+
"overrides": {
|
|
138
|
+
"esbuild": "$esbuild"
|
|
94
139
|
}
|
|
95
140
|
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: affinity
|
|
3
|
+
description: "Search and maintain local contacts, identities, relationships, events, commitments, and recurring dates. Use when recording relationship evidence or reviewing a social CRM."
|
|
4
|
+
license: "MIT"
|
|
5
|
+
compatibility: "Node.js 24 or newer. MCP stdio or ghostpaw-affinity CLI."
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# affinity
|
|
9
|
+
|
|
10
|
+
Affinity is a local relationship model and social CRM. Search before creating contacts. Inspect before revising or merging. Record direct evidence honestly, keep identities and structural ties distinct from social links, and ask for clarification when a target is ambiguous. Review commitments and recurring dates regularly. Derived scores guide attention and do not prove relationship quality.
|
|
11
|
+
|
|
12
|
+
## Calling tools
|
|
13
|
+
|
|
14
|
+
MCP: connect to ghostpaw-affinity, then call a tool by name with its JSON arguments.
|
|
15
|
+
|
|
16
|
+
CLI: `ghostpaw-affinity call <tool> '<JSON object>'` or `ghostpaw-affinity <tool> --parameter value` (without a global install: `npx -y @ghostpaw/affinity <tool> ...`).
|
|
17
|
+
|
|
18
|
+
Inspect schemas with `ghostpaw-affinity describe <tool>`. Use `--db <path>` to select a database.
|
|
19
|
+
|
|
20
|
+
## search_affinity
|
|
21
|
+
|
|
22
|
+
Search contacts by name or identity, including exact natural-key lookups like email-style identifiers.
|
|
23
|
+
|
|
24
|
+
Use when: Use this when you want to find contacts from free text or a known routing identity such as an email or URL-like handle.
|
|
25
|
+
|
|
26
|
+
Not for: Do not use this when you already know the exact contact you want to inspect in depth.
|
|
27
|
+
|
|
28
|
+
Read-only.
|
|
29
|
+
|
|
30
|
+
| Parameter | Type | Required | Values / description |
|
|
31
|
+
| --- | --- | --- | --- |
|
|
32
|
+
| query | string | yes | Free-text or natural-key query. |
|
|
33
|
+
| kind | string | no | human, group, company, team, pet, service, other. Optional contact kind filter. |
|
|
34
|
+
| lifecycleState | string | no | active, dormant, merged, lost. Optional lifecycle state filter. |
|
|
35
|
+
| includeOwner | boolean | no | Whether owner contacts are included. |
|
|
36
|
+
| includeDormant | boolean | no | Whether dormant contacts are included. |
|
|
37
|
+
| limit | integer | no | Optional result limit. |
|
|
38
|
+
| offset | integer | no | Optional result offset. |
|
|
39
|
+
|
|
40
|
+
## review_affinity
|
|
41
|
+
|
|
42
|
+
Review one affinity surface such as contacts, journals, link queues, commitments, dates, graph state, or merge history.
|
|
43
|
+
|
|
44
|
+
Use when: Use this when you want a dashboard-style list or review view instead of inspecting one exact item.
|
|
45
|
+
|
|
46
|
+
Not for: Do not use this when you already know the exact contact or link you want to inspect in depth.
|
|
47
|
+
|
|
48
|
+
Read-only.
|
|
49
|
+
|
|
50
|
+
| Parameter | Type | Required | Values / description |
|
|
51
|
+
| --- | --- | --- | --- |
|
|
52
|
+
| view | string | yes | contacts.list, contacts.duplicates, events.contact_journal, events.link_timeline, events.moments, commitments.open, links.owner, links.observed, links.progression_readiness, links.radar, dates.upcoming, graph.chart, merges.history, merges.dismissed. Which review surface to return. |
|
|
53
|
+
| contact | object | no | Optional target contact locator. |
|
|
54
|
+
| link | object | no | Optional target link locator. |
|
|
55
|
+
| contactIds | array | no | Optional contact-id subset. |
|
|
56
|
+
| kind | string | no | Optional contact kind or link kind filter, depending on the view. |
|
|
57
|
+
| lifecycleState | string | no | active, dormant, merged, lost. Optional contact lifecycle-state filter. |
|
|
58
|
+
| linkState | string | no | active, dormant, strained, broken, archived. Optional link state filter. |
|
|
59
|
+
| includeOwner | boolean | no | Whether owner contacts are included. |
|
|
60
|
+
| includeDormant | boolean | no | Whether dormant rows are included. |
|
|
61
|
+
| includeArchived | boolean | no | Whether archived links are included. |
|
|
62
|
+
| includeObserved | boolean | no | Whether observed links are included. |
|
|
63
|
+
| eventTypes | array | no | Optional event-type filter. |
|
|
64
|
+
| momentKind | string | no | breakthrough, rupture, reconciliation, milestone, turning_point. Optional moment kind filter. |
|
|
65
|
+
| commitmentType | string | no | promise, agreement. Optional commitment type filter. |
|
|
66
|
+
| recurrenceKind | string | no | birthday, anniversary, renewal, memorial, custom_yearly. Optional recurrence-kind filter. |
|
|
67
|
+
| horizonDays | integer | no | Optional horizon-days filter. |
|
|
68
|
+
| exactOnly | boolean | no | Whether duplicate review is exact-only. |
|
|
69
|
+
| minScore | number | no | Optional duplicate minimum score. |
|
|
70
|
+
| includeDismissed | boolean | no | Whether dismissed pairs are included in duplicate review (marked with dismissed flag). |
|
|
71
|
+
| since | integer | no | Optional lower timestamp bound. |
|
|
72
|
+
| until | integer | no | Optional upper timestamp bound. |
|
|
73
|
+
| limit | integer | no | Optional result limit. |
|
|
74
|
+
| offset | integer | no | Optional result offset. |
|
|
75
|
+
|
|
76
|
+
## inspect_affinity_item
|
|
77
|
+
|
|
78
|
+
Inspect one exact affinity item such as the owner profile, a contact profile, or one link detail.
|
|
79
|
+
|
|
80
|
+
Use when: Use this when you already know the exact item you want to inspect in depth.
|
|
81
|
+
|
|
82
|
+
Not for: Do not use this for search-style discovery or dashboard-like list reviews.
|
|
83
|
+
|
|
84
|
+
Read-only.
|
|
85
|
+
|
|
86
|
+
| Parameter | Type | Required | Values / description |
|
|
87
|
+
| --- | --- | --- | --- |
|
|
88
|
+
| kind | string | yes | owner_profile, contact_profile, link. What to inspect. |
|
|
89
|
+
| contact | object | no | Target contact. Required when kind=contact_profile. Provide contactId or identity. |
|
|
90
|
+
| link | object | no | Target link. Required when kind=link. Provide linkId or endpoints. |
|
|
91
|
+
| topLinksLimit | integer | no | Optional top-links cap. |
|
|
92
|
+
| recentEventsLimit | integer | no | Optional recent-events cap. |
|
|
93
|
+
|
|
94
|
+
## manage_contact
|
|
95
|
+
|
|
96
|
+
Create a contact, revise one contact's core fields, or change lifecycle state. ALWAYS search_affinity first before creating — duplicates corrupt the graph.
|
|
97
|
+
|
|
98
|
+
Use when: Use this for contact creation and lifecycle-safe contact maintenance.
|
|
99
|
+
|
|
100
|
+
Not for: Do not use this for identities, links, attributes, or merges.
|
|
101
|
+
|
|
102
|
+
Writes: writes_state.
|
|
103
|
+
|
|
104
|
+
| Parameter | Type | Required | Values / description |
|
|
105
|
+
| --- | --- | --- | --- |
|
|
106
|
+
| action | string | yes | create, revise, set_lifecycle. Operation to perform. |
|
|
107
|
+
| input | object | no | New contact payload. Required when action=create. |
|
|
108
|
+
| contact | object | no | Target contact. Required when action=revise or set_lifecycle. Provide contactId or identity. |
|
|
109
|
+
| patch | object | no | Allowed contact patch. Required when action=revise. |
|
|
110
|
+
| lifecycleState | string | no | active, dormant, merged, lost. Target lifecycle state. Required when action=set_lifecycle. |
|
|
111
|
+
| options | object | no | Optional lifecycle metadata. |
|
|
112
|
+
|
|
113
|
+
## merge_contacts
|
|
114
|
+
|
|
115
|
+
Merge one loser contact into one winner contact using explicit contact locators.
|
|
116
|
+
|
|
117
|
+
Use when: Use this only when two contacts are confirmed duplicates and the system should consolidate them.
|
|
118
|
+
|
|
119
|
+
Not for: Do not use this for routine contact edits or identity cleanup.
|
|
120
|
+
|
|
121
|
+
Writes: writes_state.
|
|
122
|
+
|
|
123
|
+
| Parameter | Type | Required | Values / description |
|
|
124
|
+
| --- | --- | --- | --- |
|
|
125
|
+
| winner | object | yes | Winner contact. Provide contactId or identity. |
|
|
126
|
+
| loser | object | yes | Loser contact. Provide contactId or identity. |
|
|
127
|
+
| reasonSummary | string | no | Optional merge reason. |
|
|
128
|
+
| now | integer | no | Optional merge timestamp. |
|
|
129
|
+
|
|
130
|
+
## manage_duplicate_dismissal
|
|
131
|
+
|
|
132
|
+
Dismiss or un-dismiss a duplicate candidate pair so it does not resurface in listDuplicateCandidates.
|
|
133
|
+
|
|
134
|
+
Use when: Use dismiss after confirming two contacts are different people (not duplicates). Use undismiss to re-surface a pair for re-evaluation.
|
|
135
|
+
|
|
136
|
+
Not for: Do not use this to merge contacts — use merge_contacts for confirmed duplicates.
|
|
137
|
+
|
|
138
|
+
Writes: writes_state.
|
|
139
|
+
|
|
140
|
+
| Parameter | Type | Required | Values / description |
|
|
141
|
+
| --- | --- | --- | --- |
|
|
142
|
+
| action | string | yes | dismiss, undismiss. Action to perform. |
|
|
143
|
+
| left | object | yes | Left contact. Provide contactId or identity. |
|
|
144
|
+
| right | object | yes | Right contact. Provide contactId or identity. |
|
|
145
|
+
| reason | any | no | Optional reason for the dismissal. |
|
|
146
|
+
|
|
147
|
+
## manage_identity
|
|
148
|
+
|
|
149
|
+
Add, revise, verify, or remove one routing identity on a contact. Use this for emails, phone numbers, social handles, and URLs — anything that could locate a person. Do not use manage_attribute for these.
|
|
150
|
+
|
|
151
|
+
Use when: Use this for contact identity management such as email, handle, or phone routing keys.
|
|
152
|
+
|
|
153
|
+
Not for: Do not use this for contact core fields, links, or attributes.
|
|
154
|
+
|
|
155
|
+
Writes: writes_state.
|
|
156
|
+
|
|
157
|
+
| Parameter | Type | Required | Values / description |
|
|
158
|
+
| --- | --- | --- | --- |
|
|
159
|
+
| action | string | yes | add, revise, verify, remove. Operation to perform. |
|
|
160
|
+
| contact | object | no | Target contact. Required when action=add. Provide contactId or identity. |
|
|
161
|
+
| input | object | no | New identity payload. Required when action=add. |
|
|
162
|
+
| identityId | integer | no | Identity id. Required when action=revise, verify, or remove. |
|
|
163
|
+
| patch | object | no | Identity patch. Required when action=revise. |
|
|
164
|
+
| verifiedAt | integer | no | Verification timestamp. Optional for action=verify. |
|
|
165
|
+
| removedAt | integer | no | Removal timestamp. Optional for action=remove. |
|
|
166
|
+
|
|
167
|
+
## manage_relationship
|
|
168
|
+
|
|
169
|
+
Seed social links, revise bond and state, and manage structural ties. Seed a link as soon as a relationship is mentioned — do not wait for repeated evidence.
|
|
170
|
+
|
|
171
|
+
Use when: Use this for direct relationship modeling and link-state changes.
|
|
172
|
+
|
|
173
|
+
Not for: Do not use this for recording social evidence or resolving commitments.
|
|
174
|
+
|
|
175
|
+
Writes: writes_state.
|
|
176
|
+
|
|
177
|
+
| Parameter | Type | Required | Values / description |
|
|
178
|
+
| --- | --- | --- | --- |
|
|
179
|
+
| action | string | yes | seed_social_link, revise_bond, override_state, set_structural_tie, remove_structural_tie. Operation to perform. |
|
|
180
|
+
| from | object | no | Source contact. Required when action=seed_social_link or set_structural_tie. Provide contactId or identity. |
|
|
181
|
+
| to | object | no | Target contact. Required when action=seed_social_link or set_structural_tie. Provide contactId or identity. |
|
|
182
|
+
| kind | string | no | Link kind. Required for seed_social_link and set_structural_tie. Can be passed here or inside input. For seed_social_link: personal, family, professional, romantic, care, service, observed, other_relational. For set_structural_tie: works_at, manages, member_of, married_to, partner_of, parent_of, child_of, sibling_of, friend_of, client_of, vendor_of, reports_to, belongs_to, other_structural. |
|
|
183
|
+
| role | string | no | Optional role for seed_social_link or set_structural_tie. Can be passed here or inside input. |
|
|
184
|
+
| input | object | no | Full payload for seed_social_link or set_structural_tie. Alternative to top-level kind/role. |
|
|
185
|
+
| link | object | no | Target link. Required when action=revise_bond, override_state, or remove_structural_tie. Provide linkId or endpoints. |
|
|
186
|
+
| bond | any | no | Bond text. Required when action=revise_bond. Null to clear. |
|
|
187
|
+
| state | string | no | active, dormant, strained, broken, archived. Link state. Required when action=override_state. |
|
|
188
|
+
| options | object | no | Optional metadata. |
|
|
189
|
+
| removedAt | integer | no | Removal timestamp. Optional for action=remove_structural_tie. |
|
|
190
|
+
|
|
191
|
+
## record_event
|
|
192
|
+
|
|
193
|
+
Record one social event such as an interaction, observation, milestone, or transaction. For interactions, milestones, and transactions the owner contact is auto-injected into participants if missing. Observations may omit the owner when recording third-party evidence.
|
|
194
|
+
|
|
195
|
+
Use when: Use this when you are capturing something that happened in the relationship graph.
|
|
196
|
+
|
|
197
|
+
Not for: Do not use this for commitments, date anchors, or direct relationship state overrides.
|
|
198
|
+
|
|
199
|
+
Writes: writes_state.
|
|
200
|
+
|
|
201
|
+
| Parameter | Type | Required | Values / description |
|
|
202
|
+
| --- | --- | --- | --- |
|
|
203
|
+
| kind | string | yes | interaction, observation, milestone, transaction. Event kind. |
|
|
204
|
+
| input | object | yes | Event payload. Always required. Interaction events also require `type`. |
|
|
205
|
+
|
|
206
|
+
## manage_commitment
|
|
207
|
+
|
|
208
|
+
Record or resolve one commitment such as a promise or agreement. The owner contact is auto-injected into participants if missing.
|
|
209
|
+
|
|
210
|
+
Use when: Use this when the work is specifically about a commitment lifecycle rather than a general event.
|
|
211
|
+
|
|
212
|
+
Not for: Do not use this for ordinary interactions or direct relationship state changes.
|
|
213
|
+
|
|
214
|
+
Writes: writes_state.
|
|
215
|
+
|
|
216
|
+
| Parameter | Type | Required | Values / description |
|
|
217
|
+
| --- | --- | --- | --- |
|
|
218
|
+
| action | string | yes | record, resolve. Operation to perform. |
|
|
219
|
+
| input | object | no | Commitment payload. Required when action=record. |
|
|
220
|
+
| commitmentEventId | integer | no | Commitment event id. Required when action=resolve. |
|
|
221
|
+
| resolution | string | no | kept, cancelled, broken. How the commitment was resolved. Required when action=resolve. |
|
|
222
|
+
| options | object | no | Optional metadata. |
|
|
223
|
+
|
|
224
|
+
## manage_date_anchor
|
|
225
|
+
|
|
226
|
+
Add, revise, or remove recurring date anchors on contacts or links. Use this for birthdays, anniversaries, and yearly events — not manage_attribute.
|
|
227
|
+
|
|
228
|
+
Use when: Use this for birthdays, anniversaries, renewals, memorials, and other recurring anchors.
|
|
229
|
+
|
|
230
|
+
Not for: Do not use this for one-off events or relationship state changes.
|
|
231
|
+
|
|
232
|
+
Writes: writes_state.
|
|
233
|
+
|
|
234
|
+
| Parameter | Type | Required | Values / description |
|
|
235
|
+
| --- | --- | --- | --- |
|
|
236
|
+
| action | string | yes | add, revise, remove. Operation to perform. |
|
|
237
|
+
| input | object | no | Date anchor payload. Required when action=add. |
|
|
238
|
+
| anchorEventId | integer | no | Anchor event id. Required when action=revise or remove. |
|
|
239
|
+
| patch | object | no | Anchor patch. Required when action=revise. |
|
|
240
|
+
| options | object | no | Optional metadata. |
|
|
241
|
+
| removedAt | integer | no | Removal timestamp. Optional for action=remove. |
|
|
242
|
+
|
|
243
|
+
## manage_attribute
|
|
244
|
+
|
|
245
|
+
Set, unset, or replace custom metadata attributes on contacts and links. For emails, phones, handles, and URLs use manage_identity instead — those are routing keys, not attributes.
|
|
246
|
+
|
|
247
|
+
Use when: Use this for metadata such as tags, notes, or small labeled facts attached to a contact or link.
|
|
248
|
+
|
|
249
|
+
Not for: Do not use this for core contact fields, identities, or direct relationship mechanics.
|
|
250
|
+
|
|
251
|
+
Writes: writes_state.
|
|
252
|
+
|
|
253
|
+
| Parameter | Type | Required | Values / description |
|
|
254
|
+
| --- | --- | --- | --- |
|
|
255
|
+
| action | string | yes | set, unset, replace. Operation to perform. |
|
|
256
|
+
| target | object | no | Attribute target. Always required. |
|
|
257
|
+
| name | string | no | Attribute name. Required when action=set or unset. |
|
|
258
|
+
| value | any | no | Attribute value. Required when action=set. Null for presence/tag semantics. |
|
|
259
|
+
| entries | array | no | Key-value map to replace all attributes. Required when action=replace. |
|
|
260
|
+
| removedAt | integer | no | Removal timestamp. Optional for action=unset. |
|
|
261
|
+
|
|
262
|
+
## Workflow guides
|
|
263
|
+
|
|
264
|
+
- [bootstrap-and-cold-start](references/bootstrap-and-cold-start.md): Establish a clean Affinity baseline with one owner, one verified identity, and the minimum structure needed for later evidence and review work.
|
|
265
|
+
- [identify-and-locate-contacts](references/identify-and-locate-contacts.md): Find the right contact reliably, prefer stable natural keys when possible, and avoid creating duplicates through weak lookup discipline.
|
|
266
|
+
- [import-history-without-faking-evidence](references/import-history-without-faking-evidence.md): Import pre-existing relationship state honestly, using seeded links for known history instead of inventing fake journal evidence.
|
|
267
|
+
- [model-structure-orgs-and-households](references/model-structure-orgs-and-households.md): Model factual structure such as employment, membership, hierarchy, and household ties without confusing it with live relational mechanics.
|
|
268
|
+
- [record-direct-evidence-well](references/record-direct-evidence-well.md): Record direct owner-facing social evidence in a way that produces truthful mechanics, good moments, and useful future review surfaces.
|
|
269
|
+
- [record-observations-and-referrals](references/record-observations-and-referrals.md): Capture third-party and referral truth without overclaiming intimacy, directness, or trust that the operator did not actually earn.
|
|
270
|
+
- [capture-transactions-and-commercial-events](references/capture-transactions-and-commercial-events.md): Capture commercially meaningful interactions as transactions so operational and service relationships accumulate the right evidence shape.
|
|
271
|
+
- [manage-promises-and-agreements](references/manage-promises-and-agreements.md): Track obligations explicitly from creation to resolution so open commitments remain actionable and trust consequences stay honest.
|
|
272
|
+
- [manage-recurring-dates-and-reminders](references/manage-recurring-dates-and-reminders.md): Use date anchors for recurring salience so important birthdays, anniversaries, renewals, and memorials feed review surfaces cleanly.
|
|
273
|
+
- [review-radar-progression-and-graph](references/review-radar-progression-and-graph.md): Use the review surfaces to prioritize maintenance, understand progression readiness, and read the shape of the relationship graph without guessing from raw rows.
|
|
274
|
+
- [reconcile-duplicates-and-merge-safely](references/reconcile-duplicates-and-merge-safely.md): Review duplicate candidates carefully and merge only after the identity, history, and structural consequences are understood.
|
|
275
|
+
|
|
276
|
+
## Principles
|
|
277
|
+
|
|
278
|
+
- Honor evidence before narrative.
|
|
279
|
+
- Clarify before you act.
|
|
280
|
+
- Keep truths in their proper layer.
|
|
281
|
+
- Read derived signals with judgment.
|
|
282
|
+
- Protect relationship integrity over time.
|
|
283
|
+
- Follow the operational protocol.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Bootstrap And Cold Start
|
|
2
|
+
|
|
3
|
+
Primary tools:
|
|
4
|
+
- `manage_contact`
|
|
5
|
+
- `manage_identity`
|
|
6
|
+
- `inspect_affinity_item`
|
|
7
|
+
- `review_affinity`
|
|
8
|
+
|
|
9
|
+
Goal:
|
|
10
|
+
- Establish one clean owner record, make it reachable, and verify the system is ready for later relationship work.
|
|
11
|
+
|
|
12
|
+
When to use:
|
|
13
|
+
- The database is new or logically empty.
|
|
14
|
+
- A harness needs to initialize its own operator profile before doing anything else.
|
|
15
|
+
|
|
16
|
+
When not to use:
|
|
17
|
+
- The owner already exists and you only need to update profile fields.
|
|
18
|
+
- You are importing historical relationships; use the import-focused skill after bootstrap.
|
|
19
|
+
|
|
20
|
+
Step-by-step sequence:
|
|
21
|
+
1. Assume the schema is already initialized and the database is live before using any tool.
|
|
22
|
+
2. Use `manage_contact` with `action: "create"` and `bootstrapOwner: true` exactly once for the operator.
|
|
23
|
+
3. Immediately attach at least one routing identity with `manage_identity` so future lookups can use a stable natural key.
|
|
24
|
+
4. Use `inspect_affinity_item` with `kind: "owner_profile"` to confirm that the owner profile exists and reads back cleanly.
|
|
25
|
+
5. Use `review_affinity` with `view: "contacts.list"` to confirm that the portfolio is still minimal and no duplicate owner-like records were created during setup.
|
|
26
|
+
|
|
27
|
+
Validation checks:
|
|
28
|
+
- The owner profile loads successfully.
|
|
29
|
+
- The owner has at least one live identity.
|
|
30
|
+
- The contact list shows exactly the records you expect at this early stage.
|
|
31
|
+
|
|
32
|
+
Pitfalls:
|
|
33
|
+
- Do not create a non-owner placeholder and plan to convert it later if the harness can bootstrap the real owner immediately.
|
|
34
|
+
- Do not skip identity attachment, or later natural-key lookup will be weaker and duplicate-prone.
|
|
35
|
+
- Do not seed relationships before the owner exists if later evidence is meant to be owner-facing.
|
|
36
|
+
|
|
37
|
+
Tips and tricks:
|
|
38
|
+
- Prefer an identity that is stable across sessions, such as a primary email or canonical profile URL.
|
|
39
|
+
- Keep the first dataset tiny. Bootstrap is for a trustworthy base, not a full import.
|
|
40
|
+
- If setup feels ambiguous, inspect first and add less rather than more.
|
|
41
|
+
|
|
42
|
+
Tool calls to prefer:
|
|
43
|
+
- `manage_contact` for owner creation
|
|
44
|
+
- `manage_identity` for first routing key
|
|
45
|
+
- `inspect_affinity_item` for confirmation
|
|
46
|
+
- `review_affinity` for early portfolio sanity checks
|
|
47
|
+
|
|
48
|
+
Related skills:
|
|
49
|
+
- `identify-and-locate-contacts`
|
|
50
|
+
- `import-history-without-faking-evidence`
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Capture Transactions And Commercial Events
|
|
2
|
+
|
|
3
|
+
Primary tools:
|
|
4
|
+
- `record_event`
|
|
5
|
+
- `inspect_affinity_item`
|
|
6
|
+
- `review_affinity`
|
|
7
|
+
|
|
8
|
+
Goal:
|
|
9
|
+
- Represent deals, placements, closings, sponsorships, and operationally meaningful exchanges as transactions instead of flattening them into generic social notes.
|
|
10
|
+
|
|
11
|
+
When to use:
|
|
12
|
+
- Money, deliverables, placements, closings, or other commercially meaningful exchanges just occurred.
|
|
13
|
+
- The relationship is service-oriented, professional, or business-critical.
|
|
14
|
+
|
|
15
|
+
When not to use:
|
|
16
|
+
- The main truth is a personal conversation or ordinary activity.
|
|
17
|
+
- The important action is really a promise or agreement that still needs later resolution.
|
|
18
|
+
|
|
19
|
+
Step-by-step sequence:
|
|
20
|
+
1. Confirm the right counterparties first.
|
|
21
|
+
2. Use `record_event` with `kind: "transaction"` for the commercial event itself.
|
|
22
|
+
3. Keep the summary concrete enough that future review explains what was exchanged and why it mattered.
|
|
23
|
+
4. Use significance according to the real business weight, not just enthusiasm.
|
|
24
|
+
5. Review the affected relationship if the commercial event should meaningfully change trust, cadence, or graph visibility.
|
|
25
|
+
|
|
26
|
+
Validation checks:
|
|
27
|
+
- The transaction now appears in the relevant timeline or journal views.
|
|
28
|
+
- The resulting relationship effect matches the commercial importance of the event.
|
|
29
|
+
- Later maintenance views now have the right recency signal.
|
|
30
|
+
|
|
31
|
+
Pitfalls:
|
|
32
|
+
- Do not bury closings, placements, or sponsorship deliveries inside generic conversations.
|
|
33
|
+
- Do not record a transaction when the truth is still only a pending agreement.
|
|
34
|
+
- Do not expect transactions to create the same kind of affinity movement as rich direct social evidence.
|
|
35
|
+
|
|
36
|
+
Tips and tricks:
|
|
37
|
+
- A relationship can be commercially strong and emotionally shallow. That is normal.
|
|
38
|
+
- Use transactions to preserve crisp operational history for later portfolio review.
|
|
39
|
+
- Follow major transactions with review views to confirm the graph and maintenance surfaces updated as expected.
|
|
40
|
+
|
|
41
|
+
Tool calls to prefer:
|
|
42
|
+
- `record_event` with `transaction`
|
|
43
|
+
- `inspect_affinity_item` for exact relationship read-back
|
|
44
|
+
- `review_affinity` for owner-link portfolio review
|
|
45
|
+
|
|
46
|
+
Related skills:
|
|
47
|
+
- `manage-promises-and-agreements`
|
|
48
|
+
- `review-radar-progression-and-graph`
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Identify And Locate Contacts
|
|
2
|
+
|
|
3
|
+
Primary tools:
|
|
4
|
+
- `search_affinity`
|
|
5
|
+
- `inspect_affinity_item`
|
|
6
|
+
- `manage_identity`
|
|
7
|
+
- `manage_contact`
|
|
8
|
+
|
|
9
|
+
Goal:
|
|
10
|
+
- Resolve the right contact before mutating anything, using the strongest available locator.
|
|
11
|
+
|
|
12
|
+
When to use:
|
|
13
|
+
- A harness receives a name, email, phone number, URL, or ambiguous reference to a person or organization.
|
|
14
|
+
- You need to confirm whether a contact already exists before creating a new one.
|
|
15
|
+
|
|
16
|
+
When not to use:
|
|
17
|
+
- You already have one exact internal id from a prior successful tool result.
|
|
18
|
+
- You are reviewing a list surface rather than identifying one exact target.
|
|
19
|
+
|
|
20
|
+
Step-by-step sequence:
|
|
21
|
+
1. Start with `search_affinity` whenever the target might already exist.
|
|
22
|
+
2. If you have a strong natural key such as email, phone, or URL-like handle, use that query first rather than a vague display name.
|
|
23
|
+
3. If search returns one strong candidate, use `inspect_affinity_item` to confirm the profile before mutating.
|
|
24
|
+
4. If the target does not exist, create it with `manage_contact`.
|
|
25
|
+
5. Immediately add the best routing key with `manage_identity` so future lookup becomes exact rather than fuzzy.
|
|
26
|
+
6. If the system returns ambiguity, stop and clarify instead of guessing.
|
|
27
|
+
|
|
28
|
+
Validation checks:
|
|
29
|
+
- The inspected profile matches the intended person or organization.
|
|
30
|
+
- The best known routing identity is attached and, when appropriate, verified.
|
|
31
|
+
- Later searches by that identity return the same contact cleanly.
|
|
32
|
+
|
|
33
|
+
Pitfalls:
|
|
34
|
+
- Do not trust names alone when a natural key is available.
|
|
35
|
+
- Do not create a second contact just because search returned multiple plausible matches.
|
|
36
|
+
- Do not remove or revise identities casually; they are your best future locator surface.
|
|
37
|
+
|
|
38
|
+
Tips and tricks:
|
|
39
|
+
- Prefer exact identities over integer ids when the harness needs to survive across sessions or partial memory loss.
|
|
40
|
+
- After creating a contact from a vague mention, upgrade it with a real identity as soon as possible.
|
|
41
|
+
- If multiple weak matches appear, inspect before mutating.
|
|
42
|
+
|
|
43
|
+
Tool calls to prefer:
|
|
44
|
+
- `search_affinity` for candidate discovery
|
|
45
|
+
- `inspect_affinity_item` for exact confirmation
|
|
46
|
+
- `manage_identity` for routing-key upgrades
|
|
47
|
+
- `manage_contact` only after lookup fails honestly
|
|
48
|
+
|
|
49
|
+
Related skills:
|
|
50
|
+
- `bootstrap-and-cold-start`
|
|
51
|
+
- `reconcile-duplicates-and-merge-safely`
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Import History Without Faking Evidence
|
|
2
|
+
|
|
3
|
+
Primary tools:
|
|
4
|
+
- `manage_contact`
|
|
5
|
+
- `manage_identity`
|
|
6
|
+
- `manage_relationship`
|
|
7
|
+
- `inspect_affinity_item`
|
|
8
|
+
|
|
9
|
+
Goal:
|
|
10
|
+
- Represent real pre-system relationship state without fabricating a timeline of events that never existed inside Affinity.
|
|
11
|
+
|
|
12
|
+
When to use:
|
|
13
|
+
- You are migrating from another CRM, notes system, or memory set.
|
|
14
|
+
- You already know a relationship exists and roughly how strong or active it is, but you do not want to reconstruct every past interaction.
|
|
15
|
+
|
|
16
|
+
When not to use:
|
|
17
|
+
- A new event just happened and should affect mechanics now.
|
|
18
|
+
- You are recording a specific conversation, milestone, transaction, or observation.
|
|
19
|
+
|
|
20
|
+
Step-by-step sequence:
|
|
21
|
+
1. Create or locate the relevant contacts first.
|
|
22
|
+
2. Add the strongest identities you know so the imported graph stays addressable later.
|
|
23
|
+
3. Use `manage_relationship` with `action: "seed_social_link"` to establish a relational link that already existed before the system.
|
|
24
|
+
4. Set only the fields you can justify: kind, rough rank, trust, cadence, state, and optional bond.
|
|
25
|
+
5. Inspect the result with `inspect_affinity_item` if you need to verify the exact post-import state.
|
|
26
|
+
6. From that point forward, switch to evidence tools for all new real-world activity.
|
|
27
|
+
|
|
28
|
+
Validation checks:
|
|
29
|
+
- The imported contact pair now has the expected relational link.
|
|
30
|
+
- The seeded state looks plausible when inspected.
|
|
31
|
+
- Later direct events continue progression from the seeded baseline rather than from zero.
|
|
32
|
+
|
|
33
|
+
Pitfalls:
|
|
34
|
+
- Do not backfill dozens of fake conversations just to reach a desired rank.
|
|
35
|
+
- Do not use import seeding for ordinary day-to-day relationship maintenance.
|
|
36
|
+
- Do not overstate confidence on rank or trust when the historical truth is actually vague.
|
|
37
|
+
|
|
38
|
+
Tips and tricks:
|
|
39
|
+
- Seed conservatively if you are unsure. It is safer to underclaim and let real future evidence move the link.
|
|
40
|
+
- Use bond text sparingly as a narrative reminder of why the imported state is what it is.
|
|
41
|
+
- Prefer one honest seed over many synthetic event reconstructions.
|
|
42
|
+
|
|
43
|
+
Tool calls to prefer:
|
|
44
|
+
- `manage_relationship` with `seed_social_link`
|
|
45
|
+
- `manage_contact` and `manage_identity` before seeding
|
|
46
|
+
- `inspect_affinity_item` for post-import verification
|
|
47
|
+
|
|
48
|
+
Related skills:
|
|
49
|
+
- `bootstrap-and-cold-start`
|
|
50
|
+
- `record-direct-evidence-well`
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Manage Promises And Agreements
|
|
2
|
+
|
|
3
|
+
Primary tools:
|
|
4
|
+
- `manage_commitment`
|
|
5
|
+
- `review_affinity`
|
|
6
|
+
- `inspect_affinity_item`
|
|
7
|
+
|
|
8
|
+
Goal:
|
|
9
|
+
- Keep promises and agreements visible, resolvable, and mechanically meaningful instead of letting them disappear into narrative history.
|
|
10
|
+
|
|
11
|
+
When to use:
|
|
12
|
+
- Someone committed to doing something later.
|
|
13
|
+
- A promise, agreement, or operational obligation needs follow-through.
|
|
14
|
+
|
|
15
|
+
When not to use:
|
|
16
|
+
- The event is complete already and no unresolved obligation exists.
|
|
17
|
+
- A date is recurring and belongs in the date-anchor surface instead.
|
|
18
|
+
|
|
19
|
+
Step-by-step sequence:
|
|
20
|
+
1. When the commitment is made, use `manage_commitment` with `action: "record"`.
|
|
21
|
+
2. Choose `promise` vs `agreement` honestly rather than treating them as stylistic synonyms.
|
|
22
|
+
3. Include a due time when the obligation has a meaningful time boundary.
|
|
23
|
+
4. Use `review_affinity` with the open-commitment view during regular review cycles.
|
|
24
|
+
5. When the outcome is known, resolve it with `manage_commitment` as `kept`, `cancelled`, or `broken`.
|
|
25
|
+
6. Inspect the relevant profile or review the relevant queue again if you need to confirm closure.
|
|
26
|
+
|
|
27
|
+
Validation checks:
|
|
28
|
+
- Open commitments appear when they should and disappear when resolved.
|
|
29
|
+
- Resolution state matches real-world truth.
|
|
30
|
+
- Trust effects feel consistent with whether the promise was kept or broken.
|
|
31
|
+
|
|
32
|
+
Pitfalls:
|
|
33
|
+
- Do not hide real obligations inside ordinary event summaries.
|
|
34
|
+
- Do not resolve a commitment optimistically before the outcome is actually known.
|
|
35
|
+
- Do not misuse `cancelled` when the truth is actually `broken`.
|
|
36
|
+
|
|
37
|
+
Tips and tricks:
|
|
38
|
+
- If an obligation matters enough to disappoint someone when missed, record it.
|
|
39
|
+
- Review open commitments regularly; the value of the system drops fast if this queue goes stale.
|
|
40
|
+
- When a commitment resolution also deserves narrative context, pair the resolution with an appropriate event in the surrounding workflow.
|
|
41
|
+
|
|
42
|
+
Tool calls to prefer:
|
|
43
|
+
- `manage_commitment` for record and resolve
|
|
44
|
+
- `review_affinity` for the open-commitment queue
|
|
45
|
+
- `inspect_affinity_item` when you need exact context on the affected relationship
|
|
46
|
+
|
|
47
|
+
Related skills:
|
|
48
|
+
- `capture-transactions-and-commercial-events`
|
|
49
|
+
- `manage-recurring-dates-and-reminders`
|