You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Examples in the curated opening: an exemplar item kind, one provenance projection, and the manual proof (integration under #193) #212
Scope revision, 27 September 2026. This replaces the body posted earlier today. The audit found that the earlier text restated constraints already owned by #181, #190, #196, #197 and #203, and named no schema, seam or wireframe. Three things move out: the bot nomination adapter goes to #197 (the paragraph to add there is under Handoffs); the cross-issue wording fixes go to #190, #198 and #201/#194; the discovery "candidate adapter" is withdrawn, because the seam it wanted already exists (#181 S3) and the open product decision it assumed is #193's to make. What stays is the work only this issue can do. A second audit of the earlier body (27 September) asked for four clarifications; two were already answered by this rewrite (the exemplar item kind; keeping bot persistence out), and two are taken below: Prerequisites and sequencing, and the one named discovery path under Discovery.
Purpose
An exemplar (#181 layer 2: a person, a work, a passage that someone cited as an example of a meaning, with a rationale and evidence) cannot be selected into a saved composition today, and nothing on the page tells a reader where an example came from beyond one sentence. This issue adds the one item kind the composition schema lacks, one provenance shape that every surface draws from, and proves the whole path by hand: a human nominates, a reviewer accepts, an operator composes and publishes, the page renders it with inference and providers offline, and the card says why it is there.
It fits the one model the site already has. Every "X is an example of Y" is an assertion_revisions row between two objects, told apart by predicate, method, actor kind and source: WordNet's instance_of under method: "source", a person's illustrates under "curated", later a persona's under "persona:<slug>@<v>" and, when #189 lands, votes on the same revisions. A composition is not a fourth kind of claim. It is a selection of eligible claims and content, with its own approval. This issue adds no predicate, no actor kind, no vote, no candidate store and no event log.
Verified starting point (origin/main @ c6bd882, devils_dictionary_v2, 27 September 2026)
Fact
Where
editorial_composition_items.item_kind IN ('content', 'sense_quotation', 'work'); assertion_revision_id is an optional annotation with ON DELETE SET NULL and no shape rule. No item kind can hold an entity subject.
Curation.Eligibility accepts a claim that is current, active and passes Claims.visible(:public). It does not require accepted.
curation/eligibility.ex:370-379
Claims.visible(:public) hides rejected/withdrawn, and hides an unaccepted nomination only when the subject is entity/person. The illustrates-wide gate is #190, unbuilt.
claims.ex:434-470
Claims.Contributions.propose/6 takes a user scope only and hardcodes method: "curated". No code creates a bot actor.
claims/contributions.ex:86-133
Examples.for_page/3 items already carry claim.{method, rationale, nominated_by, evidence, review_state, manifest} and sources[]; signals.featured_at is always nil.
examples.ex:385-460, 655-690
The seeder writes metadatamanifest, manifest_checksum, row, row_key, curator and the resolved sense external_key on the revision.
examples/seeder.ex:355-367
Published.current/1 returns %{composition, version, receipt, lead, highlights, withheld} and withholds without substituting. Nothing in the web layer calls it.
PR #210 (unmerged): Runtime.Packet is built from Bierce entries, definitions and sense quotations only. It carries no exemplar and no discovery result.
same branch, curation/runtime/packet.ex
Discovery: a result promotes to the register only through /connect, prefilled with subject, object (the sense), evidence_revision and evidence_locator for a corpus candidate that has an object_id and a sense_id; an Artsy card prefills subject alone. ConnectionLive reads those params. The metadata.from_result provenance #181 S3 described is not written today.
Providers that leave a durable identity record behind a result (identity_record/1): CineGraph, Commons, the Met, Open Library, PoetryDB, Wikiquote. The news, stock-photo, GIF and music providers do not, by design (README promise 6).
discovery/providers/*.ex
Live counts: instance_of current active 66,573; illustrates current active 5 (all test rows), 10 revisions in all; assertion_reviews 2; assertion_votes 0; no community source row; actors: import 11, user 2, unknown 1, bot 0; curation_configurations, curator_profiles, editorial_compositions all 0; discovery_results 1,729, of which 639 carry an object_id.
The dev database also carries the unmerged runtime migrations from PR #210, applied in the 13:11Z incident on #194 and awaiting the owner's rollback decision. Nothing here depends on them; all tests run on an isolated MIX_TEST_PARTITION.
Vocabulary
Three assertions that share a subject and must never be confused:
A provenance is the answer to "why is this on the page", assembled from those records and only those. It is a read projection with no table of its own.
What this issue owns
Owns
Does not own (and who does)
The exemplar item kind and its eligibility
Bot nominations, propose/6 bot scope, curation_nominations, no-reopen of rejected claims: #197, gated by #190
Examples.Provenance, drawn on the card, the chip, the person page and the opening
Read against the live editorial_composition_items. Nothing existing changes; the new kind is a fourth value of the existing column with its own shape rules. mix ecto.gen.migration add_exemplar_composition_items.
Change
Rule
item_kind CHECK gains 'exemplar'
in editorial_composition_items_shape
item_object_id
required for an exemplar at insert (the existing trigger already demands it). It is the claim's subject: an entity/* or content/* object.
assertion_revision_id
required for an exemplar at insert. New composite FK (assertion_revision_id, item_object_id) → assertion_revisions (id, subject_object_id) so the claim is about the object shown, the way content_revision_id is tied to content_id. Needs a unique index on assertion_revisions (id, subject_object_id), which is free because id is the key. ON DELETE SET NULL (assertion_revision_id); required_references already records it, so a deleted claim withholds the item (:claim_deleted).
content_revision_id
allowed for an exemplar only when the subject is a content object (a passage or quotation): pins the words shown, through the existing composite FK. NULL for an entity subject; entities have no revisions, and the label and image are read from the registry at read time under the existing retire/split check.
as today, exactly one; must agree with the claim's object (below)
role
highlight only. The lead stays a content definition (K10 unchanged).
selection_origin
manual today; panel_recommendation/human_override/human_added arrive with #197 for every kind, not here
No table for candidates, nominations or provenance. No change to assertions, assertion_revisions, assertion_reviews, predicates or predicate_endpoint_rules.
Eligibility of an exemplar item (Curation.Eligibility)
An exemplar item stands when all of these hold, else it is withheld with the named reason:
Check
Reason when it fails
the revision is current and active, predicate illustrates
:claim_not_current
its latest review is accepted (not merely visible)
:claim_not_accepted
it passes Claims.visible(:public) and Claims.Visibility rights redaction
:claim_not_visible
its object sense is the item's meaning_sense_revision_id's sense, or its object concept is refers_to by the item's meaning_lexeme_id
:meaning_mismatch
the review context's fingerprint still matches the endpoints (the card's changed since review)
:claim_context_changed (decision 2)
the subject object is active, and a content subject's revision is current
existing :object_deleted / :content_not_current
The fingerprint the reviewer accepts includes the claim revision id and the review-context fingerprint, so a re-worded claim or a moved sense needs a new composition review (#196 rule 4). This is stricter than the public gate on purpose: a highlight that leans on a claim waits for a reviewer even while the page's card does not. It does not depend on #190: accepted is required here regardless of what the public gate does.
Display identity
Within one arrangement, no two items may show the same thing: an exemplar item and a work item for the same object, or two exemplars of one object under two meanings. The key is the subject object id, plus the content revision's words for a content subject. Compositions.create_version/3 refuses with {:duplicate_display_identity, object_id} (check whether slice 1's arrangement rule already covers this before adding it).
The provenance projection
One function, Examples.Provenance.of/2, over an Examples item, a CompositionItem or an Opening.Highlight, for a viewer. It returns typed stages, with :unknown where the record is silent and :none where the record says nothing happened. It reads only through Claims.visible/2 and Claims.Visibility, so a hidden nomination has no stage at all, and no count, tombstone or label betrays it.
%Examples.Provenance{id: "ex:<assertion_id>"|"inst:<family>"|"sel:<composition_item_id>",source: [%{slug,name,tier,assertion_id,record_url|nil}]|:none,# every source, kept apart; never merged into onenomination: %{by: %{kind: :user|:bot, label, actor_id},origin: :form|:manifest|:agent|:unknown,manifest: %{slug,checksum,row}|nil, rationale,meaning: %{sense_key,gloss,sense_revision_id},evidence: [%{role,url|nil,attribution|nil,locator|nil}], at}|:none,agent: %{profile: %{slug,version},model: %{digest,config},run_id,proposal_id,note}|:none|:unknown,# :none for human work; filled by #197review: %{state,by: %{label}|nil, decided_at | nil,context_changed?: boolean}|:none,selection: %{kind: :ranked,signals: %{...}}# the examples section: Rank.order/1, nothing else|%{kind: :composed,composition_id,version,position,selection_origin,selected_by: %{kind,label}, note | nil}|:none,publication: %{receipt_id,authority_kind,actor: %{label},committed_at,superseded_at|nil,withdrawn_at|nil}|:none}
Exemplar card in #examples, disclosure open (the card and its copy exist; the disclosure is new):
┌─────────────────────────────────────────────────────────────────────┐
│ [thumb] Jeff Bezos · person │
│ cited as an example of sense 1 · a person who lacks… │
│ "Owns the Washington Post and, in 2025, …" │
│ evidence · The Guardian, 3 March 2025 ↗ │
│ · nominated by holden · accepted │
│ ▸ Why this example is here │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Nominated by holden, from manifest first-v1 row 3, │ │
│ │ on 25 Sep 2026, under sense 1 of coward │ │
│ │ Model none involved │ │
│ │ Reviewed accepted by <reviewer> on 26 Sep 2026 │ │
│ │ Shown here ranked by 1 supporting citation │ │
│ │ Opening selected by holden (v2), published 27 Sep │ │
│ │ ↗ How this was curated │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Instance chip: no new UI. The chip's title already carries the reason sentence; its provenance link is the existing /connections/:id for each contributing assertion, one per source, never merged:
[ Korean War ] title: "WordNet and Wikidata name it under a sense of war."
↳ /connections/812 (wordnet) ↳ /connections/40211 (wikidata)
Opening highlight for an exemplar (PR #202's tile, kind: :exemplar), reasons split by register:
┌──────────────────────────────┐
│ [image] │
│ Jeff Bezos │
│ as an example of coward, 1 │
│ ─ source ─ Wikidata · CC0 │
│ ─ cited ─ "Owns the…" holden│
│ ─ note ─ "…" selected by │
│ holden, reviewed │
│ ▸ Why this is here │
└──────────────────────────────┘
Person page, cited as group, gains one line per composition that features the claim:
Cited as an example of coward (sense 1) · by holden · accepted
featured in the opening of /define/coward since 27 Sep 2026
Contracts
C1 Separation. Creating, reviewing or publishing a composition version writes no assertions, assertion_revisions or assertion_reviews row. The existing slice-1 test asserts this; extend it to the exemplar kind.
C2 Accepted, not visible. An exemplar item is eligible only on an accepted latest review. Pending, disputed, rejected and withdrawn claims of every subject kind are withheld from Published.current/1 and never counted, whatever Claims.visible/2 says.
C3 No inheritance. A new claim revision, a moved sense or a changed review context withholds the item until a new composition review. Approval never transfers.
C4 Deletion. Deleting the claim revision nulls the reference and withholds the item for good (required_references, slice-1 R7). Deletion cannot make a withheld item eligible.
C7 Offline.Published.current/1 and the provenance projection make no provider call and no inference call. A test runs them with the discovery registry empty and Req stubbed to raise.
C8 Ordering untouched.Rank.order/1 and the instance chip order do not change. A composition selects; it does not reorder #examples.
C10 The bot boundary is closed, and tested closed.Contributions.propose/6 refuses any scope that is not an internal user ({:error, :unauthorized}), and a test asserts this for a bot actor scope. The agent stage of the projection is the input contract Persona panel pilot: five versioned editors, fixed quorum and ten-page evaluation #197's adapter must satisfy: profile and version, model digest and config, run and proposal ids, and a note. This issue defines that stage and reads it as :none or :unknown; it adds no code that accepts a bot nomination.
C9 Visibility everywhere. The disclosure, the person page line and the opening apply the same Claims.visible/2 and rights redaction as the card. A hidden adverse nomination leaves no trace in any of them.
Discovery, restated in one table (no adapter)
Seam
What exists
This issue
Shelf → register
/connect prefilled from a corpus candidate card (subject, sense, evidence revision, locator) on a result with an object_id (639 of 1,729 on dev)
unchanged, plus: ConnectionLive writes metadata.from_result and provider on the revision when the prefill came from a shelf, so the projection can say found on the Quotes shelf under nomination.origin: :form
Result without an object_id
cannot be a subject; minting is #105 step 5, unbuilt
out of scope; #193's open decision on transient items stands
Refresh or expiry of a result
the claim and the composition item hold registry ids, never result ids
already true; a test proves a deleted discovery_results row changes nothing
Instances → shelves
never (PageEvidence reads refers_to only)
unchanged
The one supported path for the acceptance test. A quotation from a provider with identity_record/1 (PoetryDB, Wikiquote or the public-domain corpus) on a word's Quotes shelf → its card's connect link → ConnectionLive with subject, sense, evidence_revision and evidence_locator prefilled → propose/6 → a reviewer accepts → Build 1's exemplar item with content_revision_id pinning the words → published → Published.current/1. The records reused: the result's object_id (the content object), its source_record_revision_id (the evidence), the sense revision (the meaning). Nothing is copied from discovery_results, and the result row may be deleted by retention at any point after the claim exists without changing anything. A Met artwork follows the existing work item kind and needs no claim. Results with no registry object (Guardian, Bing, Pexels, Unsplash, Openverse, GIPHY, Spotify) are not offered the link today and are refused by Compositions.create_version/3 with {:ineligible, :no_registry_object}; minting them is #105 step 5, not this issue. There is no "deferred" state: an item is eligible or it is not, with the reason.
There is no "candidate boundary" here. When #197 builds a packet, its exemplar candidates come from Examples.exemplars/3 filtered by the eligibility above; that is one function call, not a new object.
Prerequisites and sequencing
What must be on main before each build starts, and what this issue may deliver itself in a coordinated PR when the owner of a seam has not started it. Closure does not wait for any umbrella issue to finish.
the migration, Eligibility, Compositions, the proof test
nothing
2
nothing beyond c6bd882
Examples.Provenance, the card disclosure, the person-page line
nothing
3
PR #202 (accepted, unmerged) for the Opening structs
Opening.Highlightkind: :exemplar; an OpeningReader over Published.current/1 if #156 Phase 2 has not started, with #156 keeping ownership of the view model; a dev-only gate to render it, like #202's ?opening=fixture
#202's merge only. Not #194's binding, not #198, not the whole of #156
Nothing here waits for #190, #197, #209 or the PR #210 audit. Every test runs on an isolated MIX_TEST_PARTITION; no build writes to the shared dev database. The #209 storage move gates heavy runs, and there are none here.
This issue closes when Builds 1 and 2 are merged and Build 3 is merged or, if #202 is still unmerged at that point, delivered as a PR stacked on it with its record-backed test green. "Rendered on a real page" means the dev-gated published reader on a page whose composition was published through Publications; the public binding is #194's.
Builds
Build 1: the item kind and the manual proof. The migration, Eligibility, Compositions.create_version/3 accepting %{kind: :exemplar, assertion_revision_id:, meaning:}, Published.current/1 returning it, and one integration test on an isolated partition: propose/6 (user) → Claims.review accept → provision → version → operator review → publish → current/1 shows it → each of rejected, withdrawn, superseded, deleted, context-changed, meaning-mismatched and unaccepted withholds it with its reason → no claim row written. No UI.
Build 2: the provenance projection and the disclosure.Examples.Provenance.of/2; the card disclosure; the person page line; the five legacy test rows render :unknown honestly; leakage tests with a fictional adverse person and a pending non-person work (the #84 fixtures) across card, count, person page and disclosure.
Build 3: the opening mapping.Opening.Highlight gains kind: :exemplar and reads the same projection; lands with #156 Phase 2 once PR #202 merges. Its struct change and a record-backed unit test can ship first behind the existing dev-only gate.
Acceptance
Build 1: a human-nominated, accepted exemplar is published in a saved composition and read back by Published.current/1 with inference and providers unavailable; every withhold reason above has a test; mix precommit on an isolated partition.
Build 1: the migration rolls back and re-applies; existing content, sense_quotation and work items are untouched.
Up → down → up on a test partition: the down leaves the schema identical to the working database's, and the up is identical to the first. The down refuses while an exemplar is stored. Applied to devils_dictionary_v2 on 7 October; the schema diff is exactly the four objects, and the database holds 0 composition items.
Build 2: card, person page and (when Build 3 lands) opening show the same stages for one claim; a legacy claim says unknown rather than inventing a nominator; no fabricated model, run or timestamp anywhere.
Build 2: pending, disputed, rejected and withdrawn nominations of every subject kind are absent from every surface and count for the public, present and marked for contributors.
Discovery-to-curation proof on the named path: with the discovery result deleted by retention and Req stubbed to raise, the published exemplar still reads, the projection names the shelf it was found on, and no second registry object, evidence row or claim exists for the same quotation.
Accepted-only for highlights while the public gate is person-only (recommended: yes; C2). The alternative, "visible is enough", would let a pending nomination of a work into the opening.
Bot or assessor nominations (#197, #101), the illustrates-wide gate (#190), votes and tallies (#189), runs, ballots and selection-v1 (#196/#197/#203), refresh (#198), the page binding (#194), minting subjects from shelf results (#105 step 5), personal or domain panels (#201), and any change to instance ordering. Do not reopen #181 or seed its draft sample claims to complete this issue.
Done means: an accepted exemplar can be a highlight in a real saved composition, is withheld the moment its claim stops being accepted, and every surface that shows an example answers "why is this here" from the same records, saying unknown where the record is silent.
Purpose
An exemplar (#181 layer 2: a person, a work, a passage that someone cited as an example of a meaning, with a rationale and evidence) cannot be selected into a saved composition today, and nothing on the page tells a reader where an example came from beyond one sentence. This issue adds the one item kind the composition schema lacks, one provenance shape that every surface draws from, and proves the whole path by hand: a human nominates, a reviewer accepts, an operator composes and publishes, the page renders it with inference and providers offline, and the card says why it is there.
It fits the one model the site already has. Every "X is an example of Y" is an
assertion_revisionsrow between twoobjects, told apart by predicate,method, actor kind and source: WordNet'sinstance_ofundermethod: "source", a person'sillustratesunder"curated", later a persona's under"persona:<slug>@<v>"and, when #189 lands, votes on the same revisions. A composition is not a fourth kind of claim. It is a selection of eligible claims and content, with its own approval. This issue adds no predicate, no actor kind, no vote, no candidate store and no event log.Verified starting point (
origin/main@c6bd882,devils_dictionary_v2, 27 September 2026)editorial_composition_items.item_kind IN ('content', 'sense_quotation', 'work');assertion_revision_idis an optional annotation withON DELETE SET NULLand no shape rule. No item kind can hold an entity subject.20260926233642_create_curation_foundation.exslines 407–476Curation.Eligibilityaccepts a claim that is current, active and passesClaims.visible(:public). It does not requireaccepted.curation/eligibility.ex:370-379Claims.visible(:public)hidesrejected/withdrawn, and hides an unaccepted nomination only when the subject isentity/person. Theillustrates-wide gate is #190, unbuilt.claims.ex:434-470Claims.Contributions.propose/6takes a user scope only and hardcodesmethod: "curated". No code creates abotactor.claims/contributions.ex:86-133Examples.for_page/3items already carryclaim.{method, rationale, nominated_by, evidence, review_state, manifest}andsources[];signals.featured_atis alwaysnil.examples.ex:385-460, 655-690metadatamanifest,manifest_checksum,row,row_key,curatorand the resolved senseexternal_keyon the revision.examples/seeder.ex:355-367Published.current/1returns%{composition, version, receipt, lead, highlights, withheld}and withholds without substituting. Nothing in the web layer calls it.curation/published.ex:39-59Curation.OpeningwithHighlight{kind: :artwork | :quotation},Reason{kind: :policy | :source_match | :editorial, author},Review{state, selected_by, reviewed_by}.codex/consolidation-2026-09-27Runtime.Packetis built from Bierce entries, definitions and sense quotations only. It carries no exemplar and no discovery result.curation/runtime/packet.ex/connect, prefilled withsubject,object(the sense),evidence_revisionandevidence_locatorfor a corpus candidate that has anobject_idand asense_id; an Artsy card prefillssubjectalone.ConnectionLivereads those params. Themetadata.from_resultprovenance #181 S3 described is not written today.components/culture.ex:1617-1633,artwork.ex:105,live/connection_live.ex:172-206identity_record/1): CineGraph, Commons, the Met, Open Library, PoetryDB, Wikiquote. The news, stock-photo, GIF and music providers do not, by design (README promise 6).discovery/providers/*.exLive counts:
instance_ofcurrent active 66,573;illustratescurrent active 5 (all test rows), 10 revisions in all;assertion_reviews2;assertion_votes0; nocommunitysource row; actors: import 11, user 2, unknown 1, bot 0;curation_configurations,curator_profiles,editorial_compositionsall 0;discovery_results1,729, of which 639 carry anobject_id.The dev database also carries the unmerged runtime migrations from PR #210, applied in the 13:11Z incident on #194 and awaiting the owner's rollback decision. Nothing here depends on them; all tests run on an isolated
MIX_TEST_PARTITION.Vocabulary
Three assertions that share a subject and must never be confused:
instance_of, no rationale, no actor. Chip.illustrates, rationale, evidence, its own review. Card.A provenance is the answer to "why is this on the page", assembled from those records and only those. It is a read projection with no table of its own.
What this issue owns
exemplaritem kind and its eligibilitypropose/6bot scope,curation_nominations, no-reopen of rejected claims: #197, gated by #190Examples.Provenance, drawn on the card, the chip, the person page and the openingillustratesgate: #190selection-v1: #196/#197/#203Opening.HighlightSchema: one additive migration
Read against the live
editorial_composition_items. Nothing existing changes; the new kind is a fourth value of the existing column with its own shape rules.mix ecto.gen.migration add_exemplar_composition_items.item_kindCHECK gains'exemplar'editorial_composition_items_shapeitem_object_identity/*orcontent/*object.assertion_revision_id(assertion_revision_id, item_object_id) → assertion_revisions (id, subject_object_id)so the claim is about the object shown, the waycontent_revision_idis tied tocontent_id. Needs a unique index onassertion_revisions (id, subject_object_id), which is free becauseidis the key.ON DELETE SET NULL (assertion_revision_id);required_referencesalready records it, so a deleted claim withholds the item (:claim_deleted).content_revision_idcontentobject (a passage or quotation): pins the words shown, through the existing composite FK.NULLfor an entity subject; entities have no revisions, and the label and image are read from the registry at read time under the existing retire/split check.sense_revision_id,locator,words_sha256, catalog columns,source_record_revision_idNULLfor an exemplar (CHECK)meaning_sense_revision_id/meaning_lexeme_idrolehighlightonly. The lead stays acontentdefinition (K10 unchanged).selection_originmanualtoday;panel_recommendation/human_override/human_addedarrive with #197 for every kind, not hereNo table for candidates, nominations or provenance. No change to
assertions,assertion_revisions,assertion_reviews,predicatesorpredicate_endpoint_rules.Eligibility of an exemplar item (
Curation.Eligibility)An exemplar item stands when all of these hold, else it is withheld with the named reason:
illustrates:claim_not_currentaccepted(not merely visible):claim_not_acceptedClaims.visible(:public)andClaims.Visibilityrights redaction:claim_not_visiblemeaning_sense_revision_id's sense, or its object concept isrefers_toby the item'smeaning_lexeme_id:meaning_mismatchfingerprintstill matches the endpoints (the card's changed since review):claim_context_changed(decision 2)active, and a content subject's revision is current:object_deleted/:content_not_currentThe fingerprint the reviewer accepts includes the claim revision id and the review-context fingerprint, so a re-worded claim or a moved sense needs a new composition review (#196 rule 4). This is stricter than the public gate on purpose: a highlight that leans on a claim waits for a reviewer even while the page's card does not. It does not depend on #190:
acceptedis required here regardless of what the public gate does.Display identity
Within one arrangement, no two items may show the same thing: an exemplar item and a
workitem for the same object, or two exemplars of one object under two meanings. The key is the subject object id, plus the content revision's words for a content subject.Compositions.create_version/3refuses with{:duplicate_display_identity, object_id}(check whether slice 1's arrangement rule already covers this before adding it).The provenance projection
One function,
Examples.Provenance.of/2, over anExamplesitem, aCompositionItemor anOpening.Highlight, for a viewer. It returns typed stages, with:unknownwhere the record is silent and:nonewhere the record says nothing happened. It reads only throughClaims.visible/2andClaims.Visibility, so a hidden nomination has no stage at all, and no count, tombstone or label betrays it.:nonemeans:unknownmeansassertions.source_id,origin_key,source_records.urlassertions.{origin_actor_id, submitted_by_actor_id},assertion_revisions.{rationale, metadata, method, inserted_at},assertion_evidencemethodprefix;curation_nominationsand its run when #197 landsmethod: "curated"method: "persona:…"before #197's records existassertion_reviewslatest,review_contexts.fingerprintvs current endpointsRank.order/1signals, oreditorial_composition_items+ version authoreditorial_composition_publicationsreceipt for the item's versionRules the projection must keep:
:heldreplays leavenomination.atalone.committed_aton a receipt is.label, neveruser_id, email or IP. Never a rationale, evidence URL or title of a claim the viewer may not see.Wireframes
Exemplar card in
#examples, disclosure open (the card and its copy exist; the disclosure is new):Instance chip: no new UI. The chip's title already carries the reason sentence; its provenance link is the existing
/connections/:idfor each contributing assertion, one per source, never merged:Opening highlight for an exemplar (PR #202's tile,
kind: :exemplar), reasons split by register:Person page, cited as group, gains one line per composition that features the claim:
Contracts
assertions,assertion_revisionsorassertion_reviewsrow. The existing slice-1 test asserts this; extend it to the exemplar kind.acceptedlatest review. Pending, disputed, rejected and withdrawn claims of every subject kind are withheld fromPublished.current/1and never counted, whateverClaims.visible/2says.required_references, slice-1 R7). Deletion cannot make a withheld item eligible.nominationandselectionas separate stages with separate actors and times. Nothing rewrites the nomination.Published.current/1and the provenance projection make no provider call and no inference call. A test runs them with the discovery registry empty andReqstubbed to raise.Rank.order/1and the instance chip order do not change. A composition selects; it does not reorder#examples.Contributions.propose/6refuses any scope that is not an internal user ({:error, :unauthorized}), and a test asserts this for abotactor scope. Theagentstage of the projection is the input contract Persona panel pilot: five versioned editors, fixed quorum and ten-page evaluation #197's adapter must satisfy: profile and version, model digest and config, run and proposal ids, and a note. This issue defines that stage and reads it as:noneor:unknown; it adds no code that accepts a bot nomination.Claims.visible/2and rights redaction as the card. A hidden adverse nomination leaves no trace in any of them.Discovery, restated in one table (no adapter)
/connectprefilled from a corpus candidate card (subject, sense, evidence revision, locator) on a result with anobject_id(639 of 1,729 on dev)ConnectionLivewritesmetadata.from_resultandprovideron the revision when the prefill came from a shelf, so the projection can say found on the Quotes shelf undernomination.origin: :formobject_iddiscovery_resultsrow changes nothingPageEvidencereadsrefers_toonly)The one supported path for the acceptance test. A quotation from a provider with
identity_record/1(PoetryDB, Wikiquote or the public-domain corpus) on a word's Quotes shelf → its card's connect link →ConnectionLivewith subject, sense,evidence_revisionandevidence_locatorprefilled →propose/6→ a reviewer accepts → Build 1's exemplar item withcontent_revision_idpinning the words → published →Published.current/1. The records reused: the result'sobject_id(thecontentobject), itssource_record_revision_id(the evidence), the sense revision (the meaning). Nothing is copied fromdiscovery_results, and the result row may be deleted by retention at any point after the claim exists without changing anything. A Met artwork follows the existingworkitem kind and needs no claim. Results with no registry object (Guardian, Bing, Pexels, Unsplash, Openverse, GIPHY, Spotify) are not offered the link today and are refused byCompositions.create_version/3with{:ineligible, :no_registry_object}; minting them is #105 step 5, not this issue. There is no "deferred" state: an item is eligible or it is not, with the reason.There is no "candidate boundary" here. When #197 builds a packet, its exemplar candidates come from
Examples.exemplars/3filtered by the eligibility above; that is one function call, not a new object.Prerequisites and sequencing
What must be on
mainbefore each build starts, and what this issue may deliver itself in a coordinated PR when the owner of a seam has not started it. Closure does not wait for any umbrella issue to finish.mainfirstc6bd882(#206 merged)Eligibility,Compositions, the proof testc6bd882Examples.Provenance, the card disclosure, the person-page lineOpeningstructsOpening.Highlightkind: :exemplar; anOpeningReaderoverPublished.current/1if #156 Phase 2 has not started, with #156 keeping ownership of the view model; a dev-only gate to render it, like #202's?opening=fixtureNothing here waits for #190, #197, #209 or the PR #210 audit. Every test runs on an isolated
MIX_TEST_PARTITION; no build writes to the shared dev database. The#209storage move gates heavy runs, and there are none here.This issue closes when Builds 1 and 2 are merged and Build 3 is merged or, if #202 is still unmerged at that point, delivered as a PR stacked on it with its record-backed test green. "Rendered on a real page" means the dev-gated published reader on a page whose composition was published through
Publications; the public binding is #194's.Builds
Build 1: the item kind and the manual proof. The migration,
Eligibility,Compositions.create_version/3accepting%{kind: :exemplar, assertion_revision_id:, meaning:},Published.current/1returning it, and one integration test on an isolated partition:propose/6(user) →Claims.reviewaccept →provision→ version → operator review → publish →current/1shows it → each of rejected, withdrawn, superseded, deleted, context-changed, meaning-mismatched and unaccepted withholds it with its reason → no claim row written. No UI.Build 2: the provenance projection and the disclosure.
Examples.Provenance.of/2; the card disclosure; the person page line; the five legacy test rows render:unknownhonestly; leakage tests with a fictional adverse person and a pending non-person work (the #84 fixtures) across card, count, person page and disclosure.Build 3: the opening mapping.
Opening.Highlightgainskind: :exemplarand reads the same projection; lands with #156 Phase 2 once PR #202 merges. Its struct change and a record-backed unit test can ship first behind the existing dev-only gate.Acceptance
Published.current/1with inference and providers unavailable; every withhold reason above has a test;mix precommiton an isolated partition.6286ced.exemplar_items_test.exs: 29 tests. Precommit onmainafter the merge: 19 doctests, 2,621 tests, 0 failures.content,sense_quotationandworkitems are untouched.devils_dictionary_v2on 7 October; the schema diff is exactly the four objects, and the database holds 0 composition items.1ffd4b9) and Map an accepted exemplar into the curated opening (#212 build 3) #235 (merged3fe1cd1). The opening's Source, Nominated, Model and Reviewed rows are asserted equal, as text, to the card's for the same claim.Reqstubbed to raise, the published exemplar still reads, the projection names the shelf it was found on, and no second registry object, evidence row or claim exists for the same quotation.exemplar_provenance_live_test.exs): the result is purged, every provider is off, the shelf is named, and nothing is duplicated.propose/6with abotactor scope is{:error, :unauthorized}, asserted by a test that Persona panel pilot: five versioned editors, fixed quorum and ten-page evaluation #197 will replace when it opens the path.nomination.atunchanged: Examples.Provenance and 'Why this example is here' (#212, Build 2) #223'sprovenance_test.exs.docs/design/issue-212/: Build 2's 20 captures and Build 3's 8. The page-height cost of both is on Word page height and shelf templates: fold the prose, one template per content type, the world above the fold — measured on /define/love, phased #111.docs/curation/naming the functions each surface calls, and the exact seam Persona panel pilot: five versioned editors, fixed quorum and ten-page evaluation #197's packet will use.docs/curation/exemplar-items.md, with the opening's rows added by Map an accepted exemplar into the curated opening (#212 build 3) #235.Decisions owed by the owner
#examplesthe card stays up with a label (Examples backbone: the record's instances (WordNet, Wikidata P31) as the pre-adjudicated layer under the cited exemplars (#105), one read model, one section, two registers — so /define/war names its 43 wars now and /define/coward can carry an attributed example later #181 R3). In a composition, recommended: withhold (:claim_context_changed), because the operator accepted a specific claim text.selectionand costs one query./connections/:idper source (recommended, no new UI), or a disclosure like the card's.Handoffs
Contributions.propose/6with the bot scope Examples backbone: the record's instances (WordNet, Wikidata P31) as the pre-adjudicated layer under the cited exemplars (#105), one read model, one section, two registers — so /define/war names its 43 wars now and /define/coward can carry an attributed example later #181 R4 specified (%{actor: %Actor{actor_kind: :bot}},methodwhitelisted topersona:<slug>@<v>,metadatakept whole, returns:created | :held | :endorsed). Acuration_nominationsrow links the run, candidate and participant to the resultingassertion_revision_id. A rejected or withdrawn claim is never re-proposed by a bot; only a human reopens it. The bot actor'sbot_source_idis the profile's source. Gate every illustrates nomination until accepted before bots or the public can nominate (#181 decision 6, deferred) #190 lands first."docs/curation/persistence-slice-1.md.Examples.Provenanceis the examples-specific lineage its history projection consumes; it adds no second projection.Out of scope
Bot or assessor nominations (#197, #101), the
illustrates-wide gate (#190), votes and tallies (#189), runs, ballots andselection-v1(#196/#197/#203), refresh (#198), the page binding (#194), minting subjects from shelf results (#105 step 5), personal or domain panels (#201), and any change to instance ordering. Do not reopen #181 or seed its draft sample claims to complete this issue.Done means: an accepted exemplar can be a highlight in a real saved composition, is withheld the moment its claim stops being accepted, and every surface that shows an example answers "why is this here" from the same records, saying unknown where the record is silent.