1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Importing from Monica

2026-09-25. `/import` takes Monica 4's account export (Settings,
Export, "Export to JSON") as well as a `.vcf`. The export is read as
the `.vcf` it composes, a card per contact, and from the upload on it
is the walk as it was (`2026-09-21-import-a-vcf.md`): the composed
file is the import's original, pared by `Vcf.read`, and read beside
the editor a contact at a time, matched and folded as any card is
(`2026-09-23-merging-on-import.md`).

Three smaller changes ride with it, because a Monica card, by file or
by export, needs them: `ORG` and `X-ABShowAs` come in, `SOURCE` and
`REV` are dropped without remark, and a card's `CATEGORIES` are ticked
beside it as groups.

## Why the JSON and not Monica's vCards

Monica writes a vCard for one contact at a time; a whole book comes
out of its CardDAV server, through a client, as a `.vcf` the walk
already takes. What it does not carry is most of what Monica is for.
Its exporters (`app/Services/VCard/ExportVCard.php` on the 4.x
branch) write names, phones, emails, addresses, the birthday, a
photo, the company, the job, social profiles and tags. Notes,
relationships, pets, how you met, reminders and everything that
happened are nowhere in the card.

Monica 4's JSON export is the one place those come out whole. It is
Monica's own beta (`version: 1.0-preview.1`), and Monica 5 has no
equivalent, so this reads Monica 4 and nothing else; a book on Monica
5 comes in by its CardDAV `.vcf` and loses what a card cannot carry.

## A card, not a second walk

The export could have had screens of its own. It gets none, because
everything the walk does is already the right thing to do with a
Monica contact: show what it was, open the editor on what is coming
in, offer the contact it looks like, file it under its groups. So
`Import::Monica.vcf` composes cards at the upload and the route hands
them to `Vcf.cards` as if the file had been a `.vcf` all along.

A composed card carries everything Monica knows, not only what this
book reads. That keeps the walk's promise that nothing is lost without
having been shown first: the left-hand card is the whole record, and
what is not coming in is struck on it like any other line.

## Where each part goes

The shapes are Monica's export resources (`app/ExportResources`): a
record's columns, a `properties` object, and a `data` array of
collections `{count, type, values}`. Relationships, photos and
activities are the account's, and name contacts by uuid.

- **Into a field.** First, middle and last names; the nickname; the
  company as `ORG`; each contact field whose type Monica filed as a
  phone or an email; each address, labelled with the name Monica gave
  it the way Contacts labels a row; the avatar Monica stored, from the
  account's photos, where it is a data URL rather than a Gravatar.
- **The birthday**, where a card can spell it: a whole date, or a
  month and day where Monica was told the year is unknown. One Monica
  worked out from an age holds a year it guessed and a day it made
  up; no card spells that truthfully, and a staged card could not
  hold a year alone anyway, so it stays behind as a line of its own
  to read and enter on the contact's page once it is in.
- **Into the one `NOTE`** (`2026-09-25-one-note-per-contact.md`), a
  paragraph each: the description and every note, those being words
  someone wrote; then the relationships (`Spouse: Sam Booles`, in
  Monica's English names for its types), the pets, the food
  preferences, and how you met. These are prose about the person, and
  the note is the one place a contact holds prose.
- **Into groups.** Tags are `CATEGORIES` on the card, and the walk
  ticks a group of each name beside it (below).
- **Left behind, in view.** The job as `TITLE`, social profiles,
  reminders, tasks, calls, conversations, life events, gifts, debts,
  activities and a death date, each an `X-MONICA-` line (or the vCard
  property that already says it) struck on the card as exported. They
  are things to do or things that happened rather than things about
  the person, and the one worth keeping is a copy into the note away.
  So is any part the export names but cannot complete: a birthday
  that is no date, a field of a type the export does not hold, a
  relationship to someone it gives no name, and an avatar naming a
  photo it does not carry. Each is struck in view rather than gone.

A contact Monica only knows by name — `is_partial`, a relative added
from someone else's page — is not a card of its own. It is a name in
the relationships of the contacts it is related to.

## Tags are groups

Monica files people by tag; this book files them by group, and the
two mean the same thing. So a card's `CATEGORIES`, from a Monica
export or any `.vcf` that carries them, are ticked beside it: the
book's own group where one has that name, and otherwise a name the
Save makes, the way a name typed into the filter is
(`Import::Write#group_id`). They are ticks rather than writes, so the
walk's rule stands: nothing joins a group the importer did not look
at, and any of them can be unticked.

A tag spelling a sync group ticks nothing. Which phones a card goes
out to is the one box beside a card a tag should not be able to tick.

The `CATEGORIES` line itself is struck on the card as exported, being
no line this book keeps, but is not counted as a loss: what it said
arrives, as the ticked boxes beside it.

## Small changes to what a card brings in

- **`ORG` and `X-ABShowAs` are known.** A company card's editor reads
  its name out of `ORG`, and the flag is how the book knows to show it
  as one (`2026-09-24-company-cards.md`, which named this as the bulk
  path). A fold fills `ORG` where the contact has none, as it does a
  nickname.
- **`SOURCE` and `REV` are noise**, beside `PRODID`. Monica writes
  both on every card: where the card came from and when it last
  changed there. Counted, they would mark every row of a Monica file
  with a loss nobody is going to copy into a card.

## Non-goals

- **Monica 5, and Monica's API.** Monica 5's CardDAV `.vcf` imports
  as any `.vcf` does. Its CardDAV server serves groups as cards
  (`KIND:group`); a file that carries them is not read as groups yet,
  and they arrive as rows of their own.
- **A second import of the same export.** As with a `.vcf`, an export
  carries no id this server minted; the match beside each card is
  what stands between a second upload and a second set of contacts.