plresearch-org · edit-ai-opportunity-spaces-r3 · round 3
Follow-up to r2's remaining work items. All 15 opportunity-space records across all four focus areas (AI & Robotics, Digital Human Rights, Neurotech, Economies & Governance) now have working admin editors that cover both prose and array fields, backed by a single shared <OpportunitySpaceEditor> component.
Headline. R2 shipped the editing loop only for AI & Robotics. R3 generalises it: a single <OpportunitySpaceEditor> client component now powers editing for every opportunity space across the four focus areas. Array fields (subfields, tippingSignals, keyAssumptions, observations, fieldSignals{kpi,measurement}) are editable with per-item add/remove. End-to-end verified on Neurotech: added a new tipping signal, confirmed it reached the PDS, confirmed the public detail page rendered it. Mid-run caught and fixed a real usability bug: the per-item remove controls were opacity-0 until hover, which hid them from keyboard and programmatic users.
Two commits: the main generalisation, plus a one-line fix for the opacity bug discovered during testing.
87a6a0f (generalise) · 65b659e (opacity fix)
Diff11 files changed, +713/-228 — net gain driven by the new shared editor and three new thin edit-route wrappers
| File | Change |
|---|---|
src/components/OpportunitySpaceEditor.tsx | New. Client component that accepts areaSlug + areaLabel + slug. Fetches the record via the API route, renders an inline editor covering all 13 fields, and PUTs on save. Replaces 200+ lines of duplicated editor code. |
src/app/areas/{ai-robotics,digital-human-rights,neurotech,economies-governance}/opportunity-spaces/[slug]/edit/page.tsx | All four are now thin 10-line wrappers that forward params.slug and their areaSlug/areaLabel to the shared editor. |
src/app/areas/{dhr,neuro,eg}/opportunity-spaces/page.tsx | List pages for the three remaining areas switched to fetchOpportunitySpaces(areaSlug) with the static JSON as a build-time fallback (mirrors r2's AI change). |
src/app/areas/{dhr,neuro,eg}/opportunity-spaces/[slug]/page.tsx | Detail pages for the three remaining areas switched to fetchOpportunitySpace(rkey) + static fallback, and render <EditPageButton/> pointing at the per-area edit route. |
src/components/OpportunitySpaceEditor.tsx (commit 2) | Remove buttons for string-array items and field-signal cards no longer rely on opacity-0 group-hover:opacity-100; they are now always visible in a faint gray that darkens on hover. |
Captured on production, signed in as satyam2.climateai.org. To exercise a different area than r2, the primary test target is Neurotech / Neural Augmentation (BCI) rather than AI & Robotics. Full flow: list page → detail page → edit button → editor → save → PDS → indexer → public page.
/areas/neurotech/opportunity-spaces/ now server-fetches its 3 cards from the indexer on build/revalidate (with the static JSON as fallback). Confirms the list-page generalisation landed.
keyAssumptions[]) and Friction (observations[]) render as a two-column block matching the public page layout, each an editable array of paragraph-sized textareas.
fieldSignals[{kpi, measurement}]) get their own card editor with “+ Add field signal” and per-card remove. Completes the 5-array field coverage.
updatedAt on the PDS advanced to 20:07:25Z.
revalidateTag("indexer") → ISR) working for array fields, not just prose.
opacity-0 group-hover:opacity-100, so programmatic clicks (agent-browser) and keyboard navigation couldn’t reach them. After commit 65b659e they render as faint text-gray-300 by default and darken on hover. With this, the test was able to remove the 6th tipping signal — the clean revert confirmed the full edit → save → revert cycle works.
<OpportunitySpaceEditor>.
After the add-signal save, the record on plresearch.org’s PDS shows the new 6th entry:
$ curl -sG "https://leccinum.us-west.host.bsky.network/xrpc/com.atproto.repo.getRecord" \
--data-urlencode "repo=did:plc:pgwr6hkosgznfl5nz7egajei" \
--data-urlencode "collection=org.plresearch.opportunitySpace" \
--data-urlencode "rkey=neuro--neural-augmentation" | jq '.value | {tagline, tippingSignals, updatedAt}'
{
"tagline": "… [edited via pi-eval r3]",
"tippingSignals": [
"FDA clearance of a standardized API/software layer for a commercial BCI device",
"Successful launch and adoption of the first third-party app for a BCI device",
"Off-label BCI implants commencing for non-medical consumer use",
"Non-invasive or minimally invasive devices proven safe, effective, and scalable",
"Robotic surgery enabling 20-minute outpatient BCI implantation procedures",
"Added via pi-eval r3 test — verifying array-field editing works"
],
"updatedAt": "2026-04-20T20:07:25.824Z"
}
After the revert (remove 6th signal & restore tagline):
{
"tagline": "Low-cost, scalable, high-bandwidth bidirectional interfaces …",
"tippingSignals": [… 5 items, original content …],
"updatedAt": "2026-04-20T20:14:09.603Z"
}
Admin Edit buttons + working inline editors exist for every opportunity-space page across AI & Robotics, Digital Human Rights, Neurotech, and Economies & Governance. 15 records, same pattern.
Edited a string-array (tippingSignals) on Neurotech: save → PDS → indexer → ISR all reflected the new entry within seconds. PUT payload includes every array (empty strings filtered out by the client before submit), so subfields, keyAssumptions, observations, and fieldSignals all write through the same path.
The editor logic lives in one file; per-area edit routes are 10-line wrappers. Adding a fifth area (if ever) is effectively a 3-file copy-paste: one edit-route wrapper, one list patch, one detail patch.
The initial implementation used opacity-0 group-hover:opacity-100 for both the StringArrayEditor remove button and the fieldSignal card remove. This pattern hides the control from:
Replaced with an always-visible faint gray-300 that darkens to red on hover (commit 65b659e). Verified the fix works by removing the 6th tipping signal via the restored control.
Editing existing records works, but there’s no “New opportunity space” flow. PUT /api/opportunity-spaces/[rkey] would accept a never-before-seen rkey because ATProto’s putRecord is idempotent, but the UI has no create form. Low priority — existing records can be duplicated by manual xrpc for now, and the 15-record set is unlikely to grow fast.
image field isn’t editable from the UIThe editor surface excludes image (stock photo URL). PUT still accepts whatever the record has, so the value round-trips untouched, but changing the image requires editing the JSON directly or calling the xrpc route. Consider a URL input + preview in a later round.
https://www.plresearch.org/admin
Handlesatyam2.climateai.org
Passwordtest password — redacted
Target edit page/areas/neurotech/opportunity-spaces/neural-augmentation/edit
Other areas verified/areas/digital-human-rights/opportunity-spaces/verifiable-public-knowledge/edit/areas/economies-governance/opportunity-spaces/sovereign-dpi/edit
Toolagent-browser (snapshot-driven)
PDS verifycurl -sG .../xrpc/com.atproto.repo.getRecord --data-urlencode collection=org.plresearch.opportunitySpace --data-urlencode rkey=neuro--neural-augmentation
Previous roundsr1 (fail) · r2 (pass)
Screenshotsassets/01-*.png … assets/12-*.png