simocracy-v2 · interview-template-picker-show-all

Sim profile interview picker — show all community templates

@daviddao

A user reported that an interview template authored on the Flourishing Floor gathering by another user never appeared in the picker on a Sim profile page — only the facilitator's Default Constitution showed up. After patching fetchInterviewTemplates to also resolve every suggestedInterviewTemplates ref attached to any gathering (plus the viewer's own PDS), the “Flourishing Interview” template now lists under a new From the community section.

Date: 2026-05-05 · pass · Account: satyam2.climateai.org · Build: local next dev at http://127.0.0.1:3000


Headline result

2
Templates now visible (was 1)
+1
Community template surfaced Flourishing Interview
12
Questions loaded from the new template
0
Regressions

Headline. The Sim profile Interview picker now shows community-authored interview templates that have been attached to any gathering, not just the facilitator's curated default. Confirmed end-to-end with a fresh login as satyam2.climateai.org: the picker lists both Default Constitution (Curated) and Flourishing Interview under a new From the community (1) group, and selecting the new template loads its 12 questions cleanly.

Why it was broken

The picker fetches templates via fetchInterviewTemplates(), which queries the Hyperindexer for org.simocracy.interviewTemplate records. The Simocracy indexer doesn't currently ingest that collection — a direct probe returns 0 records:

$ curl -sX POST 'https://simocracy-indexer-production.up.railway.app/graphql' \
    -H 'Content-Type: application/json' \
    -d '{"query":"query F($collection:String!,$first:Int){records(collection:$collection,first:$first){edges{node{uri}}}}",\
         "variables":{"collection":"org.simocracy.interviewTemplate","first":100}}' \
  | jq '.data.records.edges | length'
0

The existing PDS fallback only fired when the indexer returned zero rows, and it only crawled the facilitator's PDS — so any template authored by another user (e.g. the one attached to the Flourishing Floor gathering by did:plc:4a4ekfv5ks66ogf52xh5u5mg) was completely invisible to the picker.

What changed

RepoGainForest/simocracy-v2 Fileslib/indexer.ts, components/sim/interview-modal.tsx BehaviourfetchInterviewTemplates() now unions 4 sources, deduped by AT-URI: (1) Hyperindexer, (2) facilitator PDS, (3) every gathering's suggestedInterviewTemplates resolved from the owner's PDS, (4) viewer's own PDS. UIRemoved the “Show all (n) / Hide” collapse on the picker's From the community group so non-curated templates render immediately.

Walkthrough

Interview intro modal
01Click INTERVIEW on a Sim profile (Nyaori Katalog) → intro modal explains the 3-step flow.
Picker before fix
02 — beforeOld picker: only the facilitator's Default Constitution appears under Curated. The Flourishing Floor template is missing entirely.
Picker after fix
03 — afterNew picker: a From the community (1) group surfaces Flourishing Interview alongside the curated default.
Community template selected
04Selecting Flourishing Interview highlights it and enables Start →.
Question 1 of 12 loaded
05Starting the interview loads Question 1 of 12 from the community template — the values prompt from the Flourishing Floor brief.

Verification against the PDS

The Flourishing Floor gathering record (indexed) lists exactly one suggestedInterviewTemplates ref:

$ curl -sX POST 'https://simocracy-indexer-production.up.railway.app/graphql' \
    -H 'Content-Type: application/json' \
    -d '{"query":"query F($collection:String!,$first:Int){records(collection:$collection,first:$first){edges{node{value}}}}",\
         "variables":{"collection":"org.simocracy.gathering","first":100}}' \
  | jq '[.data.records.edges[].node.value | select(.name|test("Flourish";"i"))
          | {name, suggested: (.suggestedInterviewTemplates // [])}]'
[
  {
    "name": "Flourishing Floor Digital Twin Experiment",
    "suggested": [
      {
        "cid": "bafyreibm4mpvr6bpawu5lavrv7knlgi64wtkd5wk36dt4hdlo77bd7u2lu",
        "uri": "at://did:plc:4a4ekfv5ks66ogf52xh5u5mg/org.simocracy.interviewTemplate/3mk6xvrl6lc22"
      }
    ]
  }
]

Resolving that AT-URI from the owner's PDS confirms the template the picker now surfaces:

$ curl -s "$(curl -s https://plc.directory/did:plc:4a4ekfv5ks66ogf52xh5u5mg | jq -r '.service[0].serviceEndpoint')\
/xrpc/com.atproto.repo.getRecord" \
  --data-urlencode "repo=did:plc:4a4ekfv5ks66ogf52xh5u5mg" \
  --data-urlencode "collection=org.simocracy.interviewTemplate" \
  --data-urlencode "rkey=3mk6xvrl6lc22" -G \
  | jq '{name: .value.name, qs: (.value.questions | length)}'
{
  "name": "Flourishing Interview",
  "qs": 12
}

Findings

Picker now lists community-authored templates

Confirmed visually (screenshot 03) and via the rendered modal contents that Flourishing Interview shows up under a new From the community (1) group on the Sim profile picker, in addition to the curated default.

Selecting the new template loads its questions

Clicking Flourishing InterviewStart → renders Question 1 of 12 with the correct prompt body (“VALUES: In a shared system…”), which matches the questions field on the PDS record.

No regression on curated default

The facilitator's Default Constitution (28 questions) still appears under Curated with its star badge, and remains the auto-selected default.

Indexer still doesn't ingest org.simocracy.interviewTemplate

The fix works around the indexing gap by enumerating every gathering's suggestedInterviewTemplates refs and resolving them per-PDS. If a community template is ever authored without being attached to a gathering, it will still be invisible. Long-term: add the collection to the Hyperindexer config.

Reproducing

Buildcd simocracy-v2 && npm run dev (Next 16, Turbopack) Loginhandle satyam2.climateai.org via the OAuth dialog URLhttp://127.0.0.1:3000/sims/did:plc:cpoagodpqrgs4t7thi5z37uf/3mjv35oolh22e (Nyaori Katalog) StepsINTERVIEW → Begin Interview → picker shows both groups Videowalkthrough.webm (450 KB) Screenshotsassets/01-intro.png04-question-loaded.png Driveragent-browser (CDP) for clicks + record