service-people — the identity ledger service
editorial(services): rewrite service-people (Track-B) — confirmed real ACS engine is Anchor-Claim-Source (2 entities, regex email-only), not the fabricated 3-entity Anchor-Claim-Socket/Chart-of-Accounts model; confirmed zero Discovery-status/gravity-scoring/30-day-aging code anywhere in the crate; confirmed real 3-tool MCP surface (identity.append/lookup/scan_text over POST /mcp); cross-links to already-verified identity-ledger-schema-design.md rather than re-deriving the schema; register-clean EN+ES
@@ -1,6 +1,6 @@ --- schema: foundry-doc-v1 title: "Identity ledger" title: "service-people" slug: service-people category: services type: concept @@ -11,59 +11,63 @@ status: active audience: vendor-public bcsc_class: public-disclosure-safe language_protocol: PROSE-TOPIC last_edited: 2026-05-15 last_edited: 2026-08-22 editor: pointsav-engineering paired_with: service-people.es.md short_description: "service-people maintains the Totebox's deterministic identity ledger — the F2 surface in os-console, using an Anchor-Claim-Socket data model that never overwrites." short_description: "service-people is the F2 surface in os-console — an MCP server over an append-only, WORM-backed identity ledger with three tools: append, lookup, and regex-based email scanning." cites: [] references: - id: 1 text: "Fowler, M. 'Event Sourcing.' martinfowler.com, 2005." url: "https://martinfowler.com/eaaDev/EventSourcing.html" - id: 2 text: "Aho, A. V. & Corasick, M. J. 'Efficient String Matching: An Aid to Bibliographic Search.' Communications of the ACM, 18(6):333–340, 1975." url: "https://dl.acm.org/doi/10.1145/360825.360855" references: [] --- **Correction (2026-08-02, verified against canonical `origin/main`):** two specific claims below don't match the real crate. (1) The real data model, per `service-people/src/acs.rs`'s own doc comment, is "ACS (Anchor-Claim-**Source**)" — a two-entity model (immutable `Anchor` + append-only `Claim`), not the three-entity "Anchor-Claim-Socket" described below; a corpus-wide search for "socket" anywhere in `service-people` returns zero hits, so the "Semantic Socket" concept and its Chart-of-Accounts mapping have no basis in the real schema. (2) The Infinite Net section claims `service-extraction` "runs Aho-Corasick over every incoming payload" — the real `service-extraction/README.md` states its mandate is "Parser Combinators and Regex," and `aho-corasick` appears in `Cargo.lock` only as a transitive dependency of the `regex` crate, never called directly; real identity extraction in `acs.rs` is explicitly "regex-only" per its own comment. **Flagged, not resolved.** `service-people` is the F2 surface in `os-console` and the platform's identity ledger. It exposes three tools over an MCP endpoint — appending a person record, looking one up, and scanning free text for email addresses — backed by an append-only store that never overwrites a conflicting identity. The full record schema (the `Person` type, its deterministic ID derivation, and the store's conflict behavior) is documented in [[identity-ledger-schema-design]]; this article covers the service surface and the automated extraction path. `service-people` maintains the [[totebox-os|Totebox]]'s deterministic identity ledger. It is the F2 surface in `os-console` and the source of truth for "who" appears in any payload across the Totebox. The data model is built around the Anchor-Claim-Socket (ACS) pattern: identity never overwrites state, claims accumulate over time, and the current picture of any person can always be recomputed from the history. This article covers the three-entity data model, the ACS pattern, and the Infinite Net — the mechanism through which identities enter the [[worm-ledger-design|WORM ledger]] from raw payloads without operator input. ## The three MCP tools ## The three-entity data model `service-people` organises identity into three distinct entity types: | Entity | Role | Storage rule | |---|---|---| | Target (the Anchor) | A unique person or organisation, anchored by a high-fidelity identifier (email hash, phone hash, professional network URN) | Minimal — a stable Sovereign-ID and the anchor only; volatile fields (job title, employer) are not stored here | | Claim (the Observation) | Every piece of data attached to a Target: `Target_UUID | Attribute | Value | Source | Timestamp` | Append-only — claims accumulate over time; no claim is ever deleted | | Semantic Socket (the Bridge) | A classification tag mapping the Target to a Chart-of-Accounts row | Recomputed deterministically from claims plus operator overrides | If an email contact's role is listed differently in two sources, both claims exist in the Totebox. The query layer ([[service-content]] and [[service-slm]]) decides which claim is current at query time. This prevents data overwrites and preserves the full evolution of every identity. ## The Anchor-Claim-Socket model | Tool | What it does | |---|---| | `identity.append` | Writes a new `Person` record to the ledger | | `identity.lookup` | Looks up a record by email or by ID | | `identity.scan_text` | Scans a block of text for email addresses and produces a record per address found | The three-entity design, abbreviated ACS, is event sourcing applied to identity: never overwrite state; always append observations; recompute the present from the history. [^1] All three are called over a single `POST /mcp` endpoint; the service also exposes `/healthz` and `/readyz`. There is no separate REST route per operation — the MCP protocol is the entire API surface. | Property | Why it matters | |---|---| | Claims are immutable | The audit trail captures the full history of how the system came to know a fact | | Sockets are reproducible | Any [[archetypes-and-chart-of-accounts|Chart-of-Accounts]] socket can be regenerated by replaying the claims | | Targets are stable | The Sovereign-ID never changes; volatile attributes never trigger a re-keying | ## Automated extraction is regex, and it is email-only today ## The Infinite Net `identity.scan_text` is implemented by an internal engine the source itself calls "ACS" — Anchor-Claim-Source, not a three-entity model with a "Semantic Socket" bridge. It matches email addresses with a single regular expression and, for each match, derives a stable ID (UUIDv5 of the lowercased address) and produces an anchor-and-claim pair recording where the address was seen. This is deliberately narrow: no phone numbers, names, or organisation strings are extracted, and no other matching strategy — Aho-Corasick or otherwise — runs anywhere in this path. Per its own source comment, the design goal is determinism: "ADR-07: zero AI — extraction is regex-only." Identity does not enter `service-people` only through manual operator input. [[service-extraction]] runs Aho-Corasick over every incoming payload — email body, PDF text, DOCX text — and pulls every name, email address, phone number, and organisation it finds. [^2] Each extracted entity receives a Sovereign-ID and enters the ledger in `Discovery` status. ## What has no basis in the current code Over time, [[service-slm]] cross-references discovered entities against the Gravity Vectors produced by [[service-content]]. If an entity accrues gravity — appearing in payloads aligned with Domains, Archetypes, and Themes — it is socketed to a Chart-of-Accounts row and elevated to active status. If it never accrues gravity (a promotional newsletter sender; a one-time signature), it ages out of the active index after 30 days, remaining in the [[worm-ledger-design|WORM record]] but invisible to active search. No "Chart-of-Accounts" socket, gravity score, or aging-out mechanism exists in `service-people`. An extracted identity is not classified, scored, or expired after any elapsed time by this crate — it is appended to the ledger and stays there. Cross-referencing against other services to promote or retire a record, if it happens at all, is not code this crate contains. ## The flat-file substrate The ledger is a directory of JSON flat files rather than a relational database — portable across infrastructure changes, auditable with standard filesystem tools, and natively compatible with local-model training pipelines that need a stable schema. No database migration is required when fields are added; existing records remain valid as the schema evolves. Records are written through `service-fs`'s append path rather than to disk directly, keeping the ledger's write-once guarantee — a portable, auditable store that does not require a database migration when the schema grows. ## See also - [[service-email]] — the email ingest service that feeds sender records into service-people via service-extraction - [[service-content]] — the Gravity Engine that produces the Gravity Vectors service-slm uses to socket entities - [[archetypes-and-chart-of-accounts]] — the Chart of Accounts that Semantic Sockets map to - [[totebox-os]] — the Totebox that hosts service-people and its WORM storage - [[identity-ledger-schema-design]] — the full `Person` record schema, ID derivation, and conflict-handling behavior - [[service-email]] — an ingest path that can feed text into `identity.scan_text` - [[service-fs]] — the append-only store `service-people` writes through - [[totebox-os]] — the platform this ledger's WORM storage belongs to