Research, evidence, and social handoff

Let external apps ask for content, require proof, commit public-safe state, and read it back.

LoreOS Core can help a Social Presence or Lore Creators app decide whether a desired post fits a character’s current state. It does not write captions, publish posts, or pretend a character visited somewhere without evidence.

The boundary is:

Social app proposes a content goal
-> LoreOS checks fit and evidence requirements
-> human/operator evidence can be submitted
-> review and commit materialize public-safe character state
-> Social app reads the public slice
-> Social app writes captions/posts using only claim-safe facts

What LoreOS does

  • Accepts content intents from an external app.
  • Returns deterministic fit feedback and missing evidence requirements.
  • Creates mission candidates for a human/operator to verify.
  • Stores research, field, brand, receipt, or published-post evidence.
  • Gates evidence before it becomes character state.
  • Exposes a public slice for downstream social planning.

What the Social app does

  • Chooses the channel, format, creative angle, cadence, and publish workflow.
  • Collects field evidence from the human operator.
  • Generates captions, reels, stories, thumbnails, and approvals.
  • Handles brand disclosures, usage rights, payouts, and Instagram publishing.

Key boundary

Research is not lived memory. A mission is not a visit. A published post is not proof of a visit. First-person experience claims need first-hand or receipt-backed evidence.

Public API flow

This is the externally supported flow. Use your own character slug from the Quickstart.

$export LOREOS_BASE="${LOREOS_BASE:-https://api.loreos.app}"
$export LOREOS_KEY="ck_..."
$export CHARACTER_SLUG="yura"

1. Submit a content intent

$INTENT_JSON="$(curl -sS -X POST "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/content-intents" \
> -H "Authorization: Bearer $LOREOS_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "intent_type": "instagram_post",
> "title": "Cafe A visit post",
> "desired_outcome": "Publish a grounded first-hand cafe post.",
> "target_audience": "local cafe fans",
> "content_brief": "Show a verified cafe visit through the character point of view.",
> "target_entities": [{"type": "place", "name": "Cafe A"}],
> "required_claims": [{"claim": "The character visited Cafe A"}],
> "evidence_requirements": [{"claim_basis": "first_hand_visit"}]
> }')"
$INTENT_ID="$(printf '%s' "$INTENT_JSON" | jq -r '.data.content_intent.id')"

2. Check fit before evidence exists

$curl -sS -X POST "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/content-intents/$INTENT_ID/fit" \
> -H "Authorization: Bearer $LOREOS_KEY" \
> -H "Content-Type: application/json" \
> -d '{"create_mission_hint": true}' | jq '.data.fit_result'

Expected shape:

1{
2 "fit_status": "needs_evidence",
3 "needs": ["verified_evidence_for_required_claims", "field_or_receipt_evidence"],
4 "mission_recommendation": {
5 "mission_type": "field_verification"
6 }
7}

3. Create an operator mission

$MISSION_JSON="$(curl -sS -X POST "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/mission-candidates" \
> -H "Authorization: Bearer $LOREOS_KEY" \
> -H "Content-Type: application/json" \
> -d "{
> \"mission_type\": \"field_verification\",
> \"title\": \"Verify Cafe A\",
> \"reason\": \"First-hand evidence is required before a visit claim.\",
> \"source_content_intent_id\": \"$INTENT_ID\",
> \"target\": {\"type\": \"place\", \"name\": \"Cafe A\"},
> \"required_evidence\": [{\"claim_basis\": \"first_hand_visit\"}]
> }")"
$MISSION_ID="$(printf '%s' "$MISSION_JSON" | jq -r '.data.mission_candidate.id')"

4. Submit verified field evidence

In production, this should come from the human/operator evidence form: photos, notes, receipt or location proof when available, and structured observations. The example below shows the API shape.

$EVIDENCE_JSON="$(curl -sS -X POST "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/evidence" \
> -H "Authorization: Bearer $LOREOS_KEY" \
> -H "Content-Type: application/json" \
> -d "{
> \"evidence_kind\": \"field_evidence\",
> \"claim_basis\": \"first_hand_visit\",
> \"verification_status\": \"verified\",
> \"confidence\": 0.93,
> \"title\": \"Cafe A field visit\",
> \"summary\": \"The operator visited Cafe A and verified it as a quiet lunch spot.\",
> \"source_provider\": \"operator\",
> \"extracted_claims\": [{\"claim\": \"Cafe A was visited first-hand\"}],
> \"content\": {
> \"target_type\": \"place\",
> \"source_mission_id\": \"$MISSION_ID\",
> \"structured_observations\": {\"crowd_level\": \"quiet\"}
> },
> \"public_eligible\": true,
> \"usable_in_chat\": true,
> \"usable_in_social\": true
> }")"
$EVIDENCE_ID="$(printf '%s' "$EVIDENCE_JSON" | jq -r '.data.evidence.id')"

5. Re-check fit

$curl -sS -X POST "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/content-intents/$INTENT_ID/fit" \
> -H "Authorization: Bearer $LOREOS_KEY" \
> -H "Content-Type: application/json" \
> -d "{\"candidate_evidence_ids\": [\"$EVIDENCE_ID\"]}" | jq '.data.fit_result.fit_status'

Expected: "story_fit_possible".

6. Move evidence through state review

$CANDIDATE_JSON="$(curl -sS -X POST "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/evidence/$EVIDENCE_ID/state-candidate" \
> -H "Authorization: Bearer $LOREOS_KEY" \
> -H "Content-Type: application/json" \
> -d '{"state_candidate_type": "public_memory_candidate"}')"
$CANDIDATE_ID="$(printf '%s' "$CANDIDATE_JSON" | jq -r '.data.research_candidate.id')"
$
$curl -sS -X PATCH "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/research/candidates/$CANDIDATE_ID/review" \
> -H "Authorization: Bearer $LOREOS_KEY" \
> -H "Content-Type: application/json" \
> -d '{"status": "accepted_for_review", "reviewer_ref": "agent:public-doc"}' >/dev/null
$
$REVIEW_JSON="$(curl -sS -X POST "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/state-reviews" \
> -H "Authorization: Bearer $LOREOS_KEY" \
> -H "Content-Type: application/json" \
> -d "{
> \"target\": \"public_memory_candidate\",
> \"candidate_ids\": [\"$CANDIDATE_ID\"],
> \"reviewer_ref\": \"agent:public-doc\"
> }")"
$REVIEW_ID="$(printf '%s' "$REVIEW_JSON" | jq -r '.data.state_review.id')"
$printf '%s' "$REVIEW_JSON" | jq '.data.state_review.review_status'

Expected: "ready_for_commit_review".

7. Commit and read the public slice

$curl -sS -X POST "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/state-reviews/$REVIEW_ID/commit" \
> -H "Authorization: Bearer $LOREOS_KEY" \
> -H "Content-Type: application/json" \
> -d '{"confirm": true, "idempotency_key": "public-doc-cafe-a"}' | jq '.data.state_commit.commit_status'
$
$curl -sS "$LOREOS_BASE/v1/characters/$CHARACTER_SLUG/public-slice?target_type=place" \
> -H "Authorization: Bearer $LOREOS_KEY" | jq '.data.public_slice'

The public slice contains only public/social-eligible committed facts. It excludes raw provider dumps, private Story Room plans, branch forecasts, and runtime-only context.

How to use the public slice

A Social Presence app can use public_slice.facts as the source material for post planning. It should still enforce:

  • first-person experience claims require claim_basis such as first_hand_visit or receipt_verified;
  • sponsored or brand-provided claims require disclosure;
  • “place exists” is not the same as “the character visited”;
  • published-post evidence does not prove the underlying visit.

LoreOS gives the state and constraints. Your app still owns the post concept, caption, approval, publishing, and performance loop.