CONTACTS
SERVICE CONTRACT · VIEW: GOV
Axiom
CONTACTS is the resolution spine of the galaxy. Every identifier resolves to a node. Every node carries INTEL. Every service resolves through CONTACTS.
Constraints
MUST: Read Apple Contacts via Contacts framework (CNContactStore), not direct SQLite MUST: Build resolution index: email→node, phone→node, name→node, linkedin→node MUST: Cross-reference Apple Contacts against USERS/ VITAE.md (governed identity) MUST: Cross-reference against SERVICES/LEARNING/ contact intelligence files MUST: Emit CONTACTS lane events to TIMELINE INDEX MUST: Provide resolution API for CALENDAR, TRANSCRIPT, EMAIL, IMESSAGE, WHATSAPP, LINKEDIN MUST: Resolve unmatched contacts to candidate nodes (fuzzy match, not silent drop) MUST: Auth-gate private contact data (phone numbers, emails, addresses) MUST NOT: Write to Apple Contacts (read-only) MUST NOT: Duplicate USERS/ identity governance (CONTACTS resolves, USERS/ governs) MUST NOT: Hardcode contact mappings (discover via resolution index) MUST NOT: Expose raw contact data to public surfaces
Capabilities
CONTACT_INGEST, CROSS_REFERENCE, ENTITY_RESOLVE, FUZZY_MATCH, RESOLUTION_INDEX, TIMELINE_EMIT
COVERAGE: 255/255
SPEC
Purpose
CONTACTS is the resolution spine of the galaxy. It reads Apple Contacts, cross-references every record against governed USERS/ identities and SERVICES/LEARNING/ intelligence files, and builds a resolution index that every other service uses to link raw identifiers to galaxy nodes. When CALENDAR sees an email in a meeting participant, when TRANSCRIPT encounters a counterparty, when EMAIL processes a sender address, they all resolve through CONTACTS.
Source
| Component | Detail |
|---|---|
| Framework | macOS Contacts framework (CNContactStore via PyObjC) |
| Access | Contacts permission required (System Preferences → Privacy) |
| Keys | givenName, familyName, emailAddresses, phoneNumbers, organizationName, socialProfiles, postalAddresses, note, imageDataAvailable |
| Dedup | CNContactStore provides unified contacts (merged across accounts) |
Resolution Index
The resolution index maps raw identifiers to galaxy nodes:
{
"email": {
"isabella@e4c.tech": "USERS/ISABELLA",
"fatima@canonic.org": "USERS/FATIMA",
"neil@levuka.co": "SERVICES/LEARNING/neil-sumaru"
},
"phone": {
"+14075551234": "SERVICES/LEARNING/alex-evans"
},
"name": {
"dexter hadley": "USERS/DEXTER",
"neil sumaru": "SERVICES/LEARNING/neil-sumaru"
},
"linkedin": {
"fatima-zahra-boukrim-75613b88": "USERS/FATIMA"
}
}
Cross-Reference Pipeline
Apple Contacts (CNContactStore)
→ Extract (name, emails, phones, org, social, notes)
→ Normalize (lowercase emails, strip phone digits, name→slug)
→ Match against USERS/*/VITAE.md identifiers
→ Match against SERVICES/LEARNING/*.md identifiers
→ Fuzzy match unmatched (Levenshtein on name, domain on email)
→ Emit RESOLUTION-INDEX.json
→ Emit CONTACTS lane to TIMELINE
Cross-Axiomatic INTEL
When a contact resolves to a galaxy node, every service gains access to that node’s full INTEL:
| Service | Uses Resolution For | INTEL Gained |
|---|---|---|
| CALENDAR | participant.email → node | Pre-meeting brief, relationship history, deal status |
| TRANSCRIPT | counterparty → node | Conversation context, prior correspondence |
| sender address → node | Reply context, relationship depth, strategic value | |
| IMESSAGE | phone handle → node | Contact name, org, relationship |
| JID → node | Group membership, network position | |
| profile URL → node | Professional context, mutual connections |
Contextual Prompts
Each resolved galaxy node can generate a contextual prompt for CLAUDE:
Before meeting with {NODE}:
- Relationship: {from INTEL}
- Last correspondence: {from TRANSCRIPT}
- Deal status: {from LEARNING}
- Strategic value: {from NETWORK-MAP}
- Upcoming: {from CALENDAR}
Ecosystem
- Upstream (read-only): Apple Contacts, USERS/ VITAE.md, SERVICES/LEARNING/ intelligence files
- Downstream (consumers): CALENDAR, TRANSCRIPT, EMAIL, IMESSAGE, WHATSAPP, LINKEDIN, STAR
- TIMELINE: CONTACTS lane emits NEW_CONTACT, UPDATED_CONTACT, RESOLVED events
INTEL
Cross-Scope Evidence
| Service Claim | Evidence Source | Reference | Status |
|---|---|---|---|
| Resolution spine of the galaxy | CONTACTS architecture | CONTACTS/CANON.md | PASS |
| Read Apple Contacts via CNContactStore | Contacts framework | CONTACTS/CONTACTS.md | PENDING |
| Resolution index (email, phone, name, linkedin → node) | Index builder | CONTACTS/CONTACTS.md | PENDING |
| Cross-reference USERS/ VITAE.md | Identity matching | CONTACTS/CANON.md | PENDING |
| Cross-reference SERVICES/LEARNING/ intelligence | Intelligence matching | CONTACTS/CANON.md | PENDING |
| CONTACTS lane in TIMELINE | Lane adapter | CONTACTS/CANON.md | PENDING |
| Resolution API for all services | API integration | CONTACTS/README.md | PENDING |
Operational Inventory
| Component | Status | Gap |
|---|---|---|
| Apple Contacts compiler | PENDING | CNContactStore extraction |
| Resolution index builder | PENDING | Cross-reference pipeline |
| CONTACTS lane adapter | PENDING | TIMELINE integration |
| Resolution API | PENDING | vault resolve command |
| CALENDAR enrichment | PENDING | Participant resolution |
| TRANSCRIPT enrichment | PENDING | Counterparty resolution |
| Contextual prompts | PENDING | Pre-meeting brief compilation |
Existing Contact Infrastructure
| Source | Location | Records | Status |
|---|---|---|---|
| USERS/ VITAE.md | hadleylab-canonic/USERS/ | 13 governed identities | ACTIVE |
| LEARNING/ intelligence | hadleylab-canonic/SERVICES/LEARNING/ | 66 contact files | ACTIVE |
| NETWORK-MAP.md | hadleylab-canonic/SERVICES/LEARNING/ | 98 nodes, 14 clusters | ACTIVE |
| AddressBook.py | imessage-mcp-server | Phone lookup only | ACTIVE |
| Apple Contacts | ~/Library/Application Support/AddressBook/ | Unknown count | UNTAPPED |
Test
| prompt | expect | cross |
|---|---|---|
| Does CONTACTS resolve emails to galaxy nodes? | Yes — resolution index | CANON.md constraints |
| Does CONTACTS resolve phones to galaxy nodes? | Yes — resolution index | CANON.md constraints |
| Is Apple Contacts read via framework, not SQLite? | Yes — CNContactStore | CANON.md constraints |
| Does resolution feed cross-axiomatic INTEL? | Yes — all services resolve through CONTACTS | CONTACTS.md projections |
LEARNING
Patterns
| Date | Signal | Pattern | Source |
|---|---|---|---|
| 2026-03-14 | CONTACTS_PROMOTION | CONTACTS promoted to first-class service. Previously contact resolution was distributed across IMESSAGE (AddressBook.py), CALENDAR (participant.email), and LEARNING (66 intelligence files). No unified resolution index existed. | Governance audit |
| 2026-03-14 | CNCONTACTSTORE | Apple Contacts must be read via Contacts framework (CNContactStore), not direct SQLite. Framework handles authorization, encryption, multi-account sync, and unified contact deduplication. AddressBook.py in imessage-mcp-server already demonstrates the pattern. | Architecture decision |
| 2026-03-14 | RESOLUTION_SPINE | CONTACTS is the resolution spine: every service that touches people resolves through one index. Without this, each service maintains its own ad hoc resolution, creating drift and duplication. | Architecture decision |
| 2026-03-14 | CROSS_AXIOMATIC | The resolution index enables cross-axiomatic INTEL: when CALENDAR resolves a participant to a galaxy node, it gains access to that node’s TRANSCRIPT history, EMAIL correspondence, deal status, and network position, all without direct service-to-service coupling. | Architecture decision |
| 2026-03-14 | FIRST_COMPILE | First compile: 2,389 Apple Contacts from 6 AddressBook source databases. 37 resolved to galaxy nodes via email cross-reference. Key matches: Atul Butte (UCSF), Vijay Pande (a16z/Stanford), Marina Sirota (UCSF), Andrew Trister (Apple), Balaji Srinivasan, Isabella Johnston, Fatima Boukrim. | build-contacts first run |
| 2026-03-14 | SQLITE_FALLBACK | CNContactStore requires PyObjC and macOS Contacts permission. SQLite fallback reads AddressBook-v22.abcddb source databases directly. Schema: ZABCDRECORD (Z_PK, ZFIRSTNAME, ZLASTNAME), ZABCDEMAILADDRESS (ZOWNER→Z_PK, ZADDRESS), ZABCDPHONENUMBER (ZOWNER→Z_PK, ZFULLNUMBER), ZABCDSOCIALPROFILE (ZOWNER→Z_PK, ZSERVICENAME, ZURLSTRING). | Compiler implementation |
| 2026-03-14 | MULTI_SOURCE | Apple Contacts has 6 source databases (iCloud, Google, Exchange, etc.), each with its own AddressBook-v22.abcddb. Deduplication by normalized name across sources prevents double-counting. | AddressBook exploration |
ROADMAP
Now
- [ ] CALENDAR enrichment (participant.email → resolved INTEL via CONTACTS index)
- [ ] TRANSCRIPT enrichment (counterparty → resolved INTEL)
- [ ] Contextual prompts (pre-meeting briefs compiled from galaxy node INTEL)
Next
- [ ] Fuzzy matching for unresolved contacts (Levenshtein on names, domain on emails)
- [ ] Contact change detection (new contacts, updated fields, deleted contacts)
- [ ] Contacts visual surface (people browser in the galaxy)
Later
- [ ] Relationship graph visualization (cross-cluster density rendering)
- [ ] Automated VITAE.md creation for promoted candidate nodes
VOCAB
| Term | Definition |
|---|---|
| CONTACTS | The resolution spine of the galaxy. Reads Apple Contacts, cross-references USERS/ and LEARNING/ intelligence, and provides the resolution API that maps raw identifiers to galaxy nodes. |
INHERITANCE CHAIN
SERVICES
SERVICES compose primitives — INTEL + CHAT + COIN. Every service governed. Every scope discovered.
MUST: Maintain TRIAD integrity (CANON.md + VOCAB.md + README.md)
MUST: Treat SPEC as scope identity (`{SCOPE}` directory), not as a file
MUST: Every SERVICE scope include ROADMAP.md, COVERAGE.md, LEARNING.md, and `{SCOPE}.md` as governed content surfaces
MUST: Discover SERVICE scopes from filesystem only (no manual catalog)
MUST: Keep http:// and magic:// on the same namespace (transport differs, scope path matches)
MUST: CANON.md = axiom + universal constraints (no service names, no paths, no implementation)
MUST: README.md = how to run the CANON (nothing else)
MUST: {SCOPE}.md = SPEC — the interface (purpose, routes, projections, ecosystem)
MUST: SHOP.md = public projection file (per scope, filesystem-discoverable)
MUST: VAULT.md = private projection file (per scope, filesystem-discoverable)
MUST: Runtime implementation remains under ~/.canonic; this workspace is governance-first
MUST NOT: Hardcode service names in CANON constraints (law speaks universals)
MUST NOT: Define ungoverned terms outside VOCAB.md
MUST NOT: Treat `{SCOPE}.md` as SPEC identity
MUST NOT: Move architecture/lifecycle into README
MUST NOT: Leak private projections to public surfaces
MUST NOT: Maintain duplicate mapping tables outside generated manifest outputs
MUST NOT: Add runtime jargon to governance contracts
MUST: Ledger-consuming services declare source ledgers, scope filters, and closure gates
MUST: Learning governance remains live — closure claims require fresh DISCOVER → GENERATE → RELINK evidence
hadleylab-canonic
HADLEYLAB ships software. Every app, book, paper, deal, and patent is PROOF that MAGIC works. COIN = WORK. LEARNING = COMPUTE.
MUST: Every app, book, paper, deal, or patent is evidence of MAGIC MUST: All scopes inherit canonic-canonic/CANONIC.md governance MUST: All users governed under USERS/ via SERVICES/USER MUST: Cross-index INTEL across users (INTEL.md) MUST: Shared events propagate to ALL affected user dashboards MUST: Maintain governance workspace purity (.md files only) MUST: Ledger all COIN (validated work) through MAGIC 255 MUST: Compile all INTEL from governed sources MUST: Keep frontend/runtime implementation under ~/.canonic (hidden runtime) MUST: Surface governed TALK, Library, and SERVICES scopes (no orphan content) MUST: Derive nav labels from governed scope names (no hardcoded strings) MUST NOT: Publish without governance (CANON.md required) MUST NOT: Duplicate primitives — compose from INTEL, CHAT, COIN MUST NOT: Silo intelligence inside a single user when multiple are affected MUST NOT: Expose VAULT contents outside NDA scope MUST NOT: Store runtime artifacts in governance workspace
canonic-canonic
SPEC is governance. `canonic-canonic/` is the spec root.
MUST: Keep this repo governance-only (.md/.pdf) MUST: Publish workspace mapping in CANONIC.git (no hardcoded repo lists) MUST: Preserve three primary lanes: FOUNDATION, INDUSTRIES, MAGIC MUST NOT: Commit runtime artifacts here (runtime belongs in ~/.canonic/) MUST: Sell MAGIC tiers — the product, not the proof (proof is hadleylab-canonic) MUST NOT: Embed beta-test app URLs in platform page content