@ghostpaw/affinity 0.4.1 → 0.6.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.
@@ -0,0 +1,489 @@
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: "The release binary needs no runtime. 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, identity, attributes, link roles, bonds and event text. All whitespace tokens must match. Dormant and lost contacts are excluded by default; use includeDormant and includeLost to include them.
23
+
24
+ Use when:
25
+
26
+ Not for:
27
+
28
+ Read-only.
29
+
30
+ | Parameter | Type | Required | Values / description |
31
+ | --- | --- | --- | --- |
32
+ | scope | string | no | contacts, events, all. Search scope; defaults to contacts. |
33
+ | query | string | yes | Free-text or natural-key query. |
34
+ | kind | string | no | human, group, company, team, pet, service, other. Optional contact kind filter. |
35
+ | lifecycleState | string | no | active, dormant, merged, lost. Optional lifecycle state filter. |
36
+ | attribute | string / array | no | |
37
+ | tag | string / array | no | |
38
+ | includeLost | boolean | no | Include lost contacts (search excludes them by default). |
39
+ | includeOwner | boolean | no | Whether owner contacts are included. |
40
+ | includeDormant | boolean | no | Whether dormant contacts are included. |
41
+ | limit | integer | no | Optional result limit. |
42
+ | offset | integer | no | Optional result offset. |
43
+
44
+ ```sh
45
+ ghostpaw-affinity search "Jana"
46
+ ```
47
+
48
+ ## review_affinity
49
+
50
+ Review one affinity surface such as contacts, journals, link queues, commitments, dates, graph state, or merge history.
51
+
52
+ Use when:
53
+
54
+ Not for:
55
+
56
+ Read-only.
57
+
58
+ | Parameter | Type | Required | Values / description |
59
+ | --- | --- | --- | --- |
60
+ | ref | object | no | |
61
+ | includeContent | boolean | no | Include verbatim content in event rows; defaults to false. |
62
+ | channel | string | no | Filter events by channel. |
63
+ | view | string | yes | contacts.list, contacts.duplicates, events.thread, 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. |
64
+ | now | integer / string | no | Optional current timestamp for overdue calculations. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
65
+ | contact | object | no | Optional target contact locator. |
66
+ | link | object | no | Optional target link locator. |
67
+ | contactIds | array | no | Optional contact-id subset. |
68
+ | kind | string | no | Optional contact kind or link kind filter, depending on the view. |
69
+ | lifecycleState | string | no | active, dormant, merged, lost. Optional contact lifecycle-state filter. |
70
+ | linkState | string | no | active, dormant, strained, broken, archived. Optional link state filter. |
71
+ | attribute | string / array | no | |
72
+ | tag | string / array | no | |
73
+ | includeLost | boolean | no | Include lost contacts (search excludes them by default). |
74
+ | includeOwner | boolean | no | Whether owner contacts are included. |
75
+ | includeDormant | boolean | no | Whether dormant rows are included. |
76
+ | includeArchived | boolean | no | Whether archived links are included. |
77
+ | includeObserved | boolean | no | Whether observed links are included. |
78
+ | eventTypes | array | no | Optional event-type filter. |
79
+ | momentKind | string | no | breakthrough, rupture, reconciliation, milestone, turning_point. Optional moment kind filter. |
80
+ | commitmentType | string | no | promise, agreement. Optional commitment type filter. |
81
+ | recurrenceKind | string | no | birthday, anniversary, renewal, memorial, custom_yearly. Optional recurrence-kind filter. |
82
+ | horizonDays | integer | no | Optional horizon-days filter. |
83
+ | exactOnly | boolean | no | Whether duplicate review is exact-only. |
84
+ | minScore | number | no | Optional duplicate minimum score. |
85
+ | includeDismissed | boolean | no | Whether dismissed pairs are included in duplicate review (marked with dismissed flag). |
86
+ | since | integer / string | no | Optional lower timestamp bound. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
87
+ | until | integer / string | no | Optional upper timestamp bound. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
88
+ | limit | integer | no | Optional result limit. |
89
+ | offset | integer | no | Optional result offset. |
90
+ | refSource | string | no | External reference source. |
91
+ | refId | string | no | External reference id. |
92
+ | withContent | boolean | no | Include verbatim event content. |
93
+ | ref.source | string | yes | External source; trimmed and lowercased. |
94
+ | ref.id | string | yes | Non-empty external id. |
95
+ | contact.contactId | integer | no | Exact contact id. |
96
+ | contact.identity | object | no | Contact identity locator. |
97
+ | link.linkId | integer | no | Exact link id. |
98
+ | link.endpoints | object | no | Endpoint-based link locator. |
99
+
100
+ ```sh
101
+ ghostpaw-affinity review events.contact_journal --with-content --channel bluesky --contact '{"contactId":2}'
102
+ ```
103
+
104
+ ## inspect_affinity_item
105
+
106
+ Inspect one exact affinity item such as the owner profile, a contact profile, or one link detail.
107
+
108
+ Use when:
109
+
110
+ Not for:
111
+
112
+ Read-only.
113
+
114
+ | Parameter | Type | Required | Values / description |
115
+ | --- | --- | --- | --- |
116
+ | kind | string | yes | event, owner_profile, contact_profile, link. What to inspect. |
117
+ | eventId | integer | no | Exact event id. |
118
+ | ref | object | no | |
119
+ | contact | object | no | Target contact. Required when kind=contact_profile. Provide contactId or identity. |
120
+ | link | object | no | Target link. Required when kind=link. Provide linkId or endpoints. |
121
+ | topLinksLimit | integer | no | Optional top-links cap. |
122
+ | recentEventsLimit | integer | no | Optional recent-events cap. |
123
+ | refSource | string | no | External reference source. |
124
+ | refId | string | no | External reference id. |
125
+ | ref.source | string | yes | External source; trimmed and lowercased. |
126
+ | ref.id | string | yes | Non-empty external id. |
127
+ | contact.contactId | integer | no | Exact contact id. |
128
+ | contact.identity | object | no | Contact identity locator. |
129
+ | link.linkId | integer | no | Exact link id. |
130
+ | link.endpoints | object | no | Endpoint-based link locator. |
131
+
132
+ ```sh
133
+ ghostpaw-affinity show contact_profile --contact '{"contactId":2}'
134
+ ```
135
+
136
+ ## manage_contact
137
+
138
+ Create, revise, export or permanently delete a contact (confirm: true required; owner cannot be deleted). Export without contact exports the whole database. Lifecycle lost is soft delete. ALWAYS search_affinity first before creating — duplicates corrupt the graph.
139
+
140
+ Use when:
141
+
142
+ Not for:
143
+
144
+ Writes: writes_state.
145
+
146
+ | Parameter | Type | Required | Values / description |
147
+ | --- | --- | --- | --- |
148
+ | action | string | yes | create, revise, set_lifecycle, export, delete. Operation to perform. |
149
+ | input | object | no | New contact payload. Required when action=create. |
150
+ | confirm | boolean | no | Required true for permanent deletion. |
151
+ | contact | object | no | Target contact. Required when action=revise or set_lifecycle. Provide contactId or identity. |
152
+ | patch | object | no | Allowed contact patch. Required when action=revise. |
153
+ | lifecycleState | string | no | active, dormant, merged, lost. Target lifecycle state. Required when action=set_lifecycle. |
154
+ | options | object | no | Optional lifecycle metadata. |
155
+ | input.identities | array | no | Optional identities to attach. An identity owned by another live contact causes a conflict, or returns that contact when ifExists=return. |
156
+ | input.ifExists | string | no | Identity collision policy; return attaches nothing. |
157
+ | input.name | string | yes | Contact name. |
158
+ | input.kind | string | yes | Contact kind. |
159
+ | input.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
160
+ | input.bootstrapOwner | boolean | no | Whether this contact should be the owner. |
161
+ | contact.contactId | integer | no | Exact contact id. |
162
+ | contact.identity | object | no | Contact identity locator. |
163
+ | patch.name | string | no | Optional replacement name. |
164
+ | options.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
165
+
166
+ ```sh
167
+ ghostpaw-affinity contact create '{"name":"Fox","kind":"human","bootstrapOwner":true}'
168
+ ```
169
+
170
+ ## merge_contacts
171
+
172
+ Merge one loser contact into one winner contact using explicit contact locators.
173
+
174
+ Use when:
175
+
176
+ Not for:
177
+
178
+ Writes: writes_state.
179
+
180
+ | Parameter | Type | Required | Values / description |
181
+ | --- | --- | --- | --- |
182
+ | winner | object | yes | Winner contact. Provide contactId or identity. |
183
+ | loser | object | yes | Loser contact. Provide contactId or identity. |
184
+ | reasonSummary | string | no | Optional merge reason. |
185
+ | now | integer / string | no | Optional merge timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
186
+ | winner.contactId | integer | no | Exact contact id. |
187
+ | winner.identity | object | no | Contact identity locator. |
188
+ | loser.contactId | integer | no | Exact contact id. |
189
+ | loser.identity | object | no | Contact identity locator. |
190
+
191
+ ```sh
192
+ ghostpaw-affinity contact merge --winner '{"contactId":2}' --loser '{"contactId":8}' --reason-summary "same person"
193
+ ```
194
+
195
+ ## manage_duplicate_dismissal
196
+
197
+ Dismiss or un-dismiss a duplicate candidate pair so it does not resurface in review_affinity contacts.duplicates.
198
+
199
+ Use when:
200
+
201
+ Not for:
202
+
203
+ Writes: writes_state.
204
+
205
+ | Parameter | Type | Required | Values / description |
206
+ | --- | --- | --- | --- |
207
+ | action | string | yes | dismiss, undismiss. Action to perform. |
208
+ | left | object | yes | Left contact. Provide contactId or identity. |
209
+ | right | object | yes | Right contact. Provide contactId or identity. |
210
+ | reason | any | no | Optional reason for the dismissal. |
211
+ | left.contactId | integer | no | Exact contact id. |
212
+ | left.identity | object | no | Contact identity locator. |
213
+ | right.contactId | integer | no | Exact contact id. |
214
+ | right.identity | object | no | Contact identity locator. |
215
+
216
+ ```sh
217
+ ghostpaw-affinity duplicate dismiss --left '{"contactId":5}' --right '{"contactId":10}' --reason '"different people"'
218
+ ```
219
+
220
+ ## manage_identity
221
+
222
+ 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.
223
+
224
+ Use when:
225
+
226
+ Not for:
227
+
228
+ Writes: writes_state.
229
+
230
+ | Parameter | Type | Required | Values / description |
231
+ | --- | --- | --- | --- |
232
+ | action | string | yes | add, revise, verify, remove. Operation to perform. |
233
+ | contact | object | no | Target contact. Required when action=add. Provide contactId or identity. |
234
+ | input | object | no | New identity payload. Required when action=add. |
235
+ | identityId | integer | no | Identity id. Required when action=revise, verify, or remove. |
236
+ | patch | object | no | Identity patch. Required when action=revise. |
237
+ | verifiedAt | integer / string | no | Verification timestamp. Optional for action=verify. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
238
+ | removedAt | integer / string | no | Removal timestamp. Optional for action=remove. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
239
+ | contact.contactId | integer | no | Exact contact id. |
240
+ | contact.identity | object | no | Contact identity locator. |
241
+ | input.ifExists | string | no | Return an existing identity on this contact without changes. |
242
+ | input.type | string | yes | Identity type: did, atproto_did, email, phone, url, website, handle, x, twitter, linkedin, github, mastodon, bluesky, telegram, whatsapp, signal, matrix, discord, slack, instagram, facebook, youtube, tiktok, address, other, account_id, alias, or custom:<name> (lowercase a-z, 0-9, underscore or hyphen). |
243
+ | input.value | string | yes | Identity value. |
244
+ | input.label | string | no | Optional label. |
245
+ | input.verified | boolean | no | Whether the identity starts verified. |
246
+ | input.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
247
+ | patch.type | string | no | Optional identity type: did, atproto_did, email, phone, url, website, handle, x, twitter, linkedin, github, mastodon, bluesky, telegram, whatsapp, signal, matrix, discord, slack, instagram, facebook, youtube, tiktok, address, other, account_id, alias, or custom:<name> (lowercase a-z, 0-9, underscore or hyphen). |
248
+ | patch.value | string | no | Optional identity value. |
249
+ | patch.label | string | no | Optional label. |
250
+
251
+ ```sh
252
+ ghostpaw-affinity identity add --contact '{"contactId":2}' --input '{"type":"email","value":"jana@x.de"}'
253
+ ```
254
+
255
+ ## manage_relationship
256
+
257
+ 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.
258
+
259
+ Use when:
260
+
261
+ Not for:
262
+
263
+ Writes: writes_state.
264
+
265
+ | Parameter | Type | Required | Values / description |
266
+ | --- | --- | --- | --- |
267
+ | action | string | yes | seed_social_link, revise_bond, override_state, set_structural_tie, remove_structural_tie. Operation to perform. |
268
+ | from | object | no | Source contact. Required when action=seed_social_link or set_structural_tie. Provide contactId or identity. |
269
+ | to | object | no | Target contact. Required when action=seed_social_link or set_structural_tie. Provide contactId or identity. |
270
+ | 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. |
271
+ | role | string | no | Optional role for seed_social_link or set_structural_tie. Can be passed here or inside input. |
272
+ | input | object | no | Full payload for seed_social_link or set_structural_tie. Alternative to top-level kind/role. |
273
+ | link | object | no | Target link. Required when action=revise_bond, override_state, or remove_structural_tie. Provide linkId or endpoints. |
274
+ | bond | any | no | Bond text. Required when action=revise_bond. Null to clear. |
275
+ | state | string | no | active, dormant, strained, broken, archived. Link state. Required when action=override_state. |
276
+ | options | object | no | Optional metadata. |
277
+ | removedAt | integer / string | no | Removal timestamp. Optional for action=remove_structural_tie. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
278
+ | from.contactId | integer | no | Exact contact id. |
279
+ | from.identity | object | no | Contact identity locator. |
280
+ | to.contactId | integer | no | Exact contact id. |
281
+ | to.identity | object | no | Contact identity locator. |
282
+ | link.linkId | integer | no | Exact link id. |
283
+ | link.endpoints | object | no | Endpoint-based link locator. |
284
+ | options.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
285
+
286
+ ```sh
287
+ ghostpaw-affinity relationship tie --from '{"contactId":2}' --to '{"contactId":3}' --kind works_at --role Founder
288
+ ```
289
+
290
+ ## record_event
291
+
292
+ 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.
293
+
294
+ Use when:
295
+
296
+ Not for:
297
+
298
+ Writes: writes_state.
299
+
300
+ | Parameter | Type | Required | Values / description |
301
+ | --- | --- | --- | --- |
302
+ | kind | string | yes | interaction, observation, milestone, transaction. Event kind. |
303
+ | input | object | yes | Event payload. Always required. Interaction events also require `type`. |
304
+ | input.type | string | no | Interaction subtype. Required when kind=interaction, omit otherwise. |
305
+ | input.affectsBond | boolean | no | Whether evidence affects the relationship; defaults false for observations with significance <=2. |
306
+ | input.content | string | no | Verbatim text, including empty text; at most 1 MB UTF-8. Summary may be omitted when content is supplied. |
307
+ | input.externalRef | object | no | |
308
+ | input.channel | string | no | Free-text channel, trimmed and lowercased, at most 40 characters. |
309
+ | input.parentRef | object | no | |
310
+ | input.parentEventId | integer | no | Parent event id. |
311
+ | input.threadRef | object | no | |
312
+ | input.momentKind | string | no | Optional moment kind. |
313
+ | input.occurredOn | string | no | Calendar day. |
314
+ | input.provenance | oneOf | no | |
315
+ | input.occurredAt | oneOf | yes | When the event occurred, Unix timestamp in milliseconds. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
316
+ | input.summary | string | no | Event summary. Must be non-empty. |
317
+ | input.significance | integer | yes | Event significance from 1 to 10. |
318
+ | input.participants | array | yes | Participant list. Must be non-empty and include the owner contact. |
319
+ | input.now | oneOf | no | Optional timestamp override. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
320
+
321
+ ```sh
322
+ ghostpaw-affinity event record --kind interaction --input '{"type":"conversation","occurredAt":"today","summary":"Call re pilot","significance":6,"participants":[{"contactId":2,"role":"recipient","directionality":"mutual"}]}'
323
+ ```
324
+
325
+ ## manage_commitment
326
+
327
+ Record or resolve one commitment such as a promise or agreement. The owner contact is auto-injected into participants if missing.
328
+
329
+ Use when:
330
+
331
+ Not for:
332
+
333
+ Writes: writes_state.
334
+
335
+ | Parameter | Type | Required | Values / description |
336
+ | --- | --- | --- | --- |
337
+ | action | string | yes | record, resolve. Operation to perform. |
338
+ | input | object | no | Commitment payload. Required when action=record. |
339
+ | commitmentEventId | integer | no | Commitment event id. Required when action=resolve. |
340
+ | resolution | string | no | kept, cancelled, broken. How the commitment was resolved. Required when action=resolve. |
341
+ | options | object | no | Optional metadata. |
342
+ | input.commitmentType | string | yes | Promise or agreement. |
343
+ | input.affectsBond | boolean | no | Whether evidence affects the relationship; defaults false for observations with significance <=2. |
344
+ | input.content | string | no | Verbatim text, including empty text; at most 1 MB UTF-8. Summary may be omitted when content is supplied. |
345
+ | input.externalRef | object | no | |
346
+ | input.channel | string | no | Free-text channel, trimmed and lowercased, at most 40 characters. |
347
+ | input.parentRef | object | no | |
348
+ | input.parentEventId | integer | no | Parent event id. |
349
+ | input.threadRef | object | no | |
350
+ | input.momentKind | string | no | Optional moment kind. |
351
+ | input.occurredOn | string | no | Calendar day. |
352
+ | input.provenance | oneOf | no | |
353
+ | input.occurredAt | oneOf | yes | When the commitment was made, Unix timestamp in milliseconds. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
354
+ | input.summary | string | no | Commitment summary. Must be non-empty. |
355
+ | input.significance | integer | yes | Commitment significance from 1 to 10. |
356
+ | input.dueAt | oneOf | no | Optional due timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
357
+ | input.dueOn | string | no | Due calendar day. |
358
+ | input.participants | array | yes | Participant list. Must be non-empty and include the owner contact. |
359
+ | input.now | oneOf | no | Optional timestamp override. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
360
+ | options.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
361
+ | options.resolvingEvent | object | no | |
362
+
363
+ ```sh
364
+ ghostpaw-affinity commitment record --input '{"commitmentType":"promise","occurredAt":"today","dueAt":"+3d","summary":"Send proposal","significance":6,"participants":[{"contactId":2,"role":"recipient"}]}'
365
+ ```
366
+
367
+ ## manage_date_anchor
368
+
369
+ Add, revise, or remove recurring date anchors on contacts or links. Use this for birthdays, anniversaries, and yearly events — not manage_attribute.
370
+
371
+ Use when:
372
+
373
+ Not for:
374
+
375
+ Writes: writes_state.
376
+
377
+ | Parameter | Type | Required | Values / description |
378
+ | --- | --- | --- | --- |
379
+ | action | string | yes | add, revise, remove. Operation to perform. |
380
+ | input | object | no | Date anchor payload. Required when action=add. |
381
+ | anchorEventId | integer | no | Anchor event id. Required when action=revise or remove. |
382
+ | patch | object | no | Anchor patch. Required when action=revise. |
383
+ | options | object | no | Optional metadata. |
384
+ | removedAt | integer / string | no | Removal timestamp. Optional for action=remove. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
385
+ | input.target | object | yes | Date-anchor target. |
386
+ | input.recurrenceKind | string | yes | Recurrence kind. |
387
+ | input.anchorMonth | integer | yes | Anchor month, 1–12. |
388
+ | input.anchorDay | integer | yes | Anchor day, 1–31 (validated per month). |
389
+ | input.summary | string | yes | Summary. Must be non-empty. |
390
+ | input.significance | integer | yes | Significance from 1 to 10. |
391
+ | input.now | oneOf | no | Optional timestamp override. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
392
+ | input.force | boolean | no | Whether to bypass duplicate checks. |
393
+ | patch.recurrenceKind | string | no | Optional recurrence kind. |
394
+ | patch.anchorMonth | integer | no | Optional month, 1–12. |
395
+ | patch.anchorDay | integer | no | Optional day, 1–31. |
396
+ | patch.summary | string | no | Optional summary. |
397
+ | patch.significance | integer | no | Optional significance, 1–10. |
398
+ | options.now | oneOf | no | Optional timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
399
+ | options.force | boolean | no | Whether duplicate checks should be bypassed. |
400
+
401
+ ```sh
402
+ ghostpaw-affinity date add --input '{"target":{"kind":"contact","contact":{"contactId":2}},"recurrenceKind":"birthday","anchorMonth":11,"anchorDay":3,"summary":"Jana bday","significance":4}'
403
+ ```
404
+
405
+ ## manage_attribute
406
+
407
+ Set, unset, or replace custom metadata attributes on contacts, links and events. For emails, phones, handles, and URLs use manage_identity instead — those are routing keys, not attributes.
408
+
409
+ Use when:
410
+
411
+ Not for:
412
+
413
+ Writes: writes_state.
414
+
415
+ | Parameter | Type | Required | Values / description |
416
+ | --- | --- | --- | --- |
417
+ | action | string | yes | set, unset, replace. Operation to perform. |
418
+ | target | object | no | Attribute target. Always required. |
419
+ | name | string | no | Attribute name. Required when action=set or unset. |
420
+ | value | any | no | Attribute value. Required when action=set. Null for presence/tag semantics. |
421
+ | entries | array | no | Key-value map to replace all attributes. Required when action=replace. |
422
+ | removedAt | integer / string | no | Removal timestamp. Optional for action=unset. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
423
+ | target.kind | string | yes | Target kind. |
424
+ | target.eventId | integer | no | Target event id. |
425
+ | target.contact | object | no | Contact locator. Required when kind=contact. Provide contactId or identity. |
426
+ | target.link | object | no | Link locator. Required when kind=link. Provide linkId or endpoints. |
427
+ | entries.name | string | yes | Attribute name. |
428
+ | entries.value | oneOf | no | Attribute value, or null for presence/tag semantics. |
429
+
430
+ ```sh
431
+ ghostpaw-affinity attribute set --target '{"kind":"contact","contact":{"contactId":2}}' --name pipeline_stage --value '"proposal"'
432
+ ```
433
+
434
+ ## manage_event
435
+
436
+ Revise or delete one event by eventId or external reference. Delete requires confirm=true and recomputes affected relationships.
437
+
438
+ Use when:
439
+
440
+ Not for:
441
+
442
+ Writes: writes_state.
443
+
444
+ | Parameter | Type | Required | Values / description |
445
+ | --- | --- | --- | --- |
446
+ | action | string | yes | revise, delete. Action. |
447
+ | eventId | integer | no | Event id; provide eventId or ref. |
448
+ | ref | object | no | |
449
+ | confirm | boolean | no | Must be true to delete. |
450
+ | patch | object | no | Fields to revise; externalRef may only be added when absent. |
451
+ | refSource | string | no | External reference source. |
452
+ | refId | string | no | External reference id. |
453
+ | ref.source | string | yes | External source; trimmed and lowercased. |
454
+ | ref.id | string | yes | Non-empty external id. |
455
+ | patch.summary | string | no | Short non-empty label. |
456
+ | patch.content | string | no | Verbatim content, at most 1 MB UTF-8. |
457
+ | patch.occurredAt | oneOf | no | Event timestamp. Accepts epoch milliseconds integer, ISO 8601 date-time with Z/offset, YYYY-MM-DD, DD.MM.YYYY, today, tomorrow, yesterday, +3d or -2d. UTC midnight for dates; dueAt uses UTC end of day. |
458
+ | patch.significance | integer | no | Significance 1..10. |
459
+ | patch.channel | string | no | Channel, at most 40 characters. |
460
+ | patch.type | string | no | Type within the same event kind. |
461
+ | patch.externalRef | object | no | |
462
+
463
+ ```sh
464
+ ghostpaw-affinity event revise --event-id 1 --patch '{"summary":"Corrected"}'
465
+ ```
466
+
467
+ ## Workflow guides
468
+
469
+ - `ghostpaw-affinity skill bootstrap-and-cold-start`: Establish a clean Affinity baseline with one owner, one verified identity, and the minimum structure needed for later evidence and review work.
470
+ - `ghostpaw-affinity skill identify-and-locate-contacts`: Find the right contact reliably, prefer stable natural keys when possible, and avoid creating duplicates through weak lookup discipline.
471
+ - `ghostpaw-affinity skill import-history-without-faking-evidence`: Import pre-existing relationship state honestly, using seeded links for known history instead of inventing fake journal evidence.
472
+ - `ghostpaw-affinity skill model-structure-orgs-and-households`: Model factual structure such as employment, membership, hierarchy, and household ties without confusing it with live relational mechanics.
473
+ - `ghostpaw-affinity skill record-direct-evidence-well`: Record direct owner-facing social evidence in a way that produces truthful mechanics, good moments, and useful future review surfaces.
474
+ - `ghostpaw-affinity skill record-observations-and-referrals`: Capture third-party and referral truth without overclaiming intimacy, directness, or trust that the operator did not actually earn.
475
+ - `ghostpaw-affinity skill capture-transactions-and-commercial-events`: Capture commercially meaningful interactions as transactions so operational and service relationships accumulate the right evidence shape.
476
+ - `ghostpaw-affinity skill manage-promises-and-agreements`: Track obligations explicitly from creation to resolution so open commitments remain actionable and trust consequences stay honest.
477
+ - `ghostpaw-affinity skill manage-recurring-dates-and-reminders`: Use date anchors for recurring salience so important birthdays, anniversaries, renewals, and memorials feed review surfaces cleanly.
478
+ - `ghostpaw-affinity skill review-radar-progression-and-graph`: Use the review surfaces to prioritize maintenance, understand progression readiness, and read the shape of the relationship graph without guessing from raw rows.
479
+ - `ghostpaw-affinity skill reconcile-duplicates-and-merge-safely`: Review duplicate candidates carefully and merge only after the identity, history, and structural consequences are understood.
480
+ - `ghostpaw-affinity skill tools`: Tool parameters, nested fields, and examples.
481
+
482
+ ## Principles
483
+
484
+ - Honor evidence before narrative.
485
+ - Clarify before you act.
486
+ - Keep truths in their proper layer.
487
+ - Read derived signals with judgment.
488
+ - Protect relationship integrity over time.
489
+ - Follow the operational protocol.