Recipe for resolving names into identities

When to use it

Use it to turn the names in documents into identities a house can be asked about: who is mentioned where. It comes after recipe-assign-topics. A mistake here costs one surplus identity; joining identities is the riskier recipe-merge-name-forms.

Use this recipe on documents that arrive with structure (Markdown, or HTML from a web capture). Documents that arrive as raw text or from PDF need their outline first, from the list of open work (list_work): an outline creates a new version of the document, and work done on the old version will be offered again.

What you need first

Documents with text, and the author door. The three kinds exist in every house as built-in aspects: Person, Ort (place), Organisation. A fresh house already holds one place, Universe.

Fetch the context

Work document by document; what one document made known is not judged again in the next. Skip digests, as working-by-recipe says.

list_documents {"limit": 200}
export_document {"doc_id": "<document ID>", "max_chars": 30000}

Read on with offset while the answer says truncated. A name finder is planned and not yet available in a house, so you find the names while reading, with this prompt:

You sweep text for proper names. Report EVERY proper name that occurs in the passage: persons, places, organizations (institutions, companies, churches, monasteries, associations, noble houses), and anything else that is named. Include abbreviations, initials, nicknames and pet forms, and foreign or transliterated spellings, in any language or script. Report the surface form verbatim, exactly as it stands in the text, one entry per distinct spelling; keep multi-word names together (Eva Hassmann, Solmser Hof). Do not resolve, merge or normalize forms. Do not skip a name because it looks like a common word - Baker, Fisher, Weber can be surnames. Calendar words alone (weekdays, months, holidays) and generic nouns are not names. Missing a real name is the one failure that matters; a doubtful entry is fine - mark it unsure. Answer with a JSON array only, no commentary: [{"surface":"...","kind":"person|place|organization|other|unsure"}]

The kind of this first answer is only a hint; the judgment below decides. Take each form without a leading article and without the full stop that ends a sentence; keep titles and salutations. Keep, per form, the paragraphs it stands in, word for word. Then ask what the house knows:

store_text {"content": "Elena Marsh"}
get_links {"id": "<stored.id>", "direction": "in", "limit": 100}

store_text writes nothing new for a text that exists; stored.id is the wording's ID. Read the incoming edges:

Build the input as numbered lines, up to 200 forms per judgment, each with one example paragraph cut at 220 characters:

1. «Elena Marsh» — Elena Marsh for the Harbour Bridge Trust, Mr Okafor and Mrs Okafor for Okafor Steel Ltd.
2. «Lindholm» — Mr Okafor offered 48,000 for the set, delivered to the yard in Lindholm.

Judge

You decide, for each numbered wording from the documents of this memory, what kind of thing it names. The wordings were collected by a name detector and include noise. Answer per entry with exactly one kind:
- person: a human being (given name, surname, full name, nickname, pet form, "Mrs Dr. X", "Mr Y" - the wording is what it is, keep the judgement about the person)
- place: a settlement, region, country, street, building as a location, landscape
- organization: an institution, company, practice, club, church, school, band, hotel, restaurant, authority, noble house as an institution
- other: named but none of the three - an animal, a work (book, film, piece of music), an event, a product, a ship
- inflection: not a name but a grammatical form of one - a genitive or possessive ("Hella's car", German "Hellas Auto") or a plural/family form ("the Frankes"). Decide this by the ending and the sentence, and prefer it whenever the wording is a name plus an ending that the sentence uses grammatically.
- noise: not a proper name at all - a common noun, an adjective, a verb, a sentence beginning that only looks capitalised, a date or weekday, a fragment, a number, a single letter, or gibberish
- unsure: a real decision is needed and the example does not settle it
Judge by the example sentence, not by the wording alone: capitalisation proves little (German capitalises every noun, English every sentence beginning), so the sentence is what tells a name from a word. Be strict with noise and generous with unsure - a wrong 'noise' silently loses a person, an 'unsure' only asks a human.
Three rules that decided wrongly before:
- A country, region, city, village or district is always place, never organization - even where the sentence means its team, government or people.
- A bare generic noun is noise, however concrete: clubhouse, golf course, theatre, practice, station, board, train. Only a proper name built on one is a name: "Solmser Hof", "Cafe Riese", "Hotel Adler".
- A word for a family member or role is noise, not person: mother, father, dad, grandma, aunt, uncle, boss, doctor. "Aunt Ursel" is a person, "aunt" alone is not.
Answer with a JSON array only, one entry per input number, no commentary: [{"n":1,"kind":"person"},{"n":2,"kind":"noise"}]

The answer form

[{"n": 1, "kind": "person"}, {"n": 2, "kind": "noise"}]

Check your own verdict

Apply

For person, place and organization, create the identity and assert its mentions:

create_person {"name": "Elena Marsh"}
assert_mentions {"identity_id": "<identity.id>", "surface_id": "<stored.id of the form>",
                 "quotes": ["<paragraph>", "<paragraph>"]}

Use create_place or create_organization for the other two kinds. Name the identity exactly as the form stands: the known-test finds it by that name. Creating never searches, so each call is a new identity. At most 200 quotes per call. In the answer, asserted counts new mentions, already_stated repeated ones, problems the quotes that matched nothing. For a known form, call only assert_mentions with the existing identity.

Every other verdict creates no identity and is recorded at the form, so that it is not judged again:

raise_conjecture {"subject_id": "<stored.id of the form>", "note": "Name form, judged by recipe-resolve-names."}
resolve_conjecture {"conjecture_id": "<conjecture.id>", "answer": "noise: a common noun"}
resolve_conjecture {"conjecture_id": "<conjecture.id>", "needs_user_resolution": true}

Always the same note. For other, inflection and noise, answer with the kind and a few words. For unsure, escalate with the third call instead; list_conjectures with status NeedsUserResolution is then the owner's list.

An inflection still mentions someone. If its base name ("Elena" for "Elenas") is known as exactly one identity, call assert_mentions at that identity with the inflected wording as surface_id. Otherwise leave it.

Say who judged

One note per document, as working-by-recipe shows: the recipe and what you created.

What this recipe does not do

Origin

Atlantis, Intelligence/World/Sweep/NameModel.cs (finding, commit 3dde232), FormClassifier.cs (judging, commit d242e49) and Resolver.cs (known-test, apply), read at main 966157b. Adapted: the prompts named a German family archive and used German examples; rules and kinds are unchanged. Different from the route: there a sweep program finds the forms and raises the conjectures, the known-test does not look at the aspect, and an inflection gets its mention only at the merge.

Go deeper