feat(OPE-29): wire captureRisk integer 1-5 and captureRiskReasoning from XLSX #11

Open
brandon wants to merge 4 commits from feature/OPE-29-schema-hardening into main
Collaborator

Replaces AI-invented low/medium/high string enum with real 1-5 integer
sourced from the master XLSX. Adds captureRiskReasoning freetext field.

Schema: captureRisk → z.number().int().min(1).max(5).nullable()
Pipeline: reads Capture Risk + Capture Risk Assessment columns; removes
captureRisk from ENRICHMENT_FIELDS so XLSX value wins on merge; fixes
pre-existing OUT_DIR bug (was writing to non-existent products/website/
path); exact-match-first in get() helper eliminates column prefix shadowing
CSS: replaces 3 risk tokens with 5 distinct numeric vars (--color-risk-1
through --color-risk-5): green → yellow → orange → orange-red → red
i18n: numeric string keys 1-5 in badge.captureRisk + badge.captureRiskLabel
(en + pt-BR); tooltips updated to reference 5-tier scale
UI: all display sites (MatrixTable, ProtocolCard, ComparisonView, both
[id].astro) updated — color dots, filter, sort (null-safe), labels
Data: 162 protocols regenerated with integer captureRisk (1→23, 2→93,
3→41, 4→5) and captureRiskReasoning freetext where authored

Unblocks OPE-16 (4.5 capture-risk reasoning display) and OPE-17 (4.6
inline challenge button).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Summary

Data origin attestation

  • This PR touches authored data, taxonomy, or schema
  • Fields / values changed:
  • Source of each change:
  • No AI-derived values enter canonical fields silently (any enrichment is marked provisional)
  • Reviewed by the data authority (Brandon, @Enli10ment), or queued for his review
Replaces AI-invented low/medium/high string enum with real 1-5 integer sourced from the master XLSX. Adds captureRiskReasoning freetext field. Schema: captureRisk → z.number().int().min(1).max(5).nullable() Pipeline: reads Capture Risk + Capture Risk Assessment columns; removes captureRisk from ENRICHMENT_FIELDS so XLSX value wins on merge; fixes pre-existing OUT_DIR bug (was writing to non-existent products/website/ path); exact-match-first in get() helper eliminates column prefix shadowing CSS: replaces 3 risk tokens with 5 distinct numeric vars (--color-risk-1 through --color-risk-5): green → yellow → orange → orange-red → red i18n: numeric string keys 1-5 in badge.captureRisk + badge.captureRiskLabel (en + pt-BR); tooltips updated to reference 5-tier scale UI: all display sites (MatrixTable, ProtocolCard, ComparisonView, both [id].astro) updated — color dots, filter, sort (null-safe), labels Data: 162 protocols regenerated with integer captureRisk (1→23, 2→93, 3→41, 4→5) and captureRiskReasoning freetext where authored Unblocks OPE-16 (4.5 capture-risk reasoning display) and OPE-17 (4.6 inline challenge button). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> ## Summary <!-- What does this PR do? --> ## Data origin attestation <!-- Complete this section if the PR touches: src/data/ or src/lib/schemas.ts (authored matrix data or the schema). --> - [ ] This PR touches authored data, taxonomy, or schema - **Fields / values changed:** - **Source of each change:** <!-- xlsx cell · Brandon's email (date) · workshop disposition · deterministic computation from xlsx --> - [ ] No AI-derived values enter canonical fields silently (any enrichment is marked provisional) - [ ] Reviewed by the data authority (Brandon, @Enli10ment), or queued for his review <!-- Multilateral data process: docs/governance.md (workspace repo) -->
Replaces AI-invented low/medium/high string enum with real 1-5 integer
sourced from the master XLSX. Adds captureRiskReasoning freetext field.

Schema: captureRisk → z.number().int().min(1).max(5).nullable()
Pipeline: reads Capture Risk + Capture Risk Assessment columns; removes
  captureRisk from ENRICHMENT_FIELDS so XLSX value wins on merge; fixes
  pre-existing OUT_DIR bug (was writing to non-existent products/website/
  path); exact-match-first in get() helper eliminates column prefix shadowing
CSS: replaces 3 risk tokens with 5 distinct numeric vars (--color-risk-1
  through --color-risk-5): green → yellow → orange → orange-red → red
i18n: numeric string keys 1-5 in badge.captureRisk + badge.captureRiskLabel
  (en + pt-BR); tooltips updated to reference 5-tier scale
UI: all display sites (MatrixTable, ProtocolCard, ComparisonView, both
  [id].astro) updated — color dots, filter, sort (null-safe), labels
Data: 162 protocols regenerated with integer captureRisk (1→23, 2→93,
  3→41, 4→5) and captureRiskReasoning freetext where authored

Unblocks OPE-16 (4.5 capture-risk reasoning display) and OPE-17 (4.6
inline challenge button).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Updates ENTITY_SHEETS in convert-xlsx.py so the SCS tab writes
'Smart Contract Standard' to protocols.json instead of the generic
'Standards/Coordination Systems'. The canonical name in entity-types.json
was already correct; this aligns the pipeline output to match it.

Also adds image.remotePatterns: [] to astro.config.mjs to resolve
an Astro 5.18.0 + Zod v4 startup crash (config.image was undefined
before the explicit declaration).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Protocol.entityType now carries the entity-type ID (e.g. "p2p-protocol")
instead of the XLSX display name ("P2P Protocols"), eliminating the
two-place hardcoded display-name mapping this was drifting from
(convert-xlsx.py's unused id parameter, protocols/[id].astro's
ENTITY_TYPE_DISPLAY_TO_ID map). Display everywhere now resolves through
entity-types.json's fullName via a shared entityTypeMap lookup.

Schema: entityType: z.string() -> z.enum([13 canonical IDs])
Pipeline: extract_sheet() writes entity_type_id instead of
  entity_type_name (the id was already being passed in, just unused)
Data: 162 protocols.json entries migrated from display-name to ID
  (pipeline unrunnable in dev environment; deterministic scripted
  key-transform used instead, verified exact-count per ID)
UI: MatrixTable, ComparisonView, ProtocolCard, both protocols/[id].astro
  pages (en + pt-BR) all resolve display via entityTypeMap.get(id).fullName;
  entityTypes prop threaded through NavigatorSection -> ProtocolResults
  -> ProtocolCard and 8 Astro page call sites (4 pages x en/pt-BR)
Tests: updated 2 Playwright assertions for the resulting display-text
  change (e.g. "P2P Protocols" -> "P2P Protocol", now matching the
  canonical fullName instead of the old XLSX tab name)

10 of 13 entity-type labels change sitewide as an intended effect of
this refactor (full before/after table in the story doc) -- fixes a
pre-existing badge/heading display inconsistency on the detail page
as a side effect.

Verified zero regressions via a baseline-worktree comparison against
the pre-story commit (45 failures baseline vs 47 after, net +2 being
browser-timing flakes in code this change didn't touch). Code-reviewed
(3-layer adversarial); 1 patch applied (entity filter dropdown sort
order), 2 items deferred to deferred-work.md (DD Pro/DM Pro enum gap
already being addressed via OPE-28/OPE-32; URL filter back-compat,
same class as the existing capture-risk deferred item).

Story: _bmad-output/implementation-artifacts/3-5-entitytype-id-refactor.md

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Author
Collaborator

Data origin attestation

  • This PR touches authored data, taxonomy, or schema
  • Fields / values changed: entityType on all 162 entries in src/data/protocols.json (display-name string → canonical entity-type ID); entityType schema type in src/lib/schemas.ts (z.string()z.enum([...13 IDs]))
  • Source of each change: deterministic computation from already-authored entity-types.json / the XLSX Entity Type Defs sheet — no new values invented
  • No AI-derived values enter canonical fields silently
  • Reviewed by the data authority (Brandon, @Enli10ment), or queued for his review
## Data origin attestation - [x] This PR touches authored data, taxonomy, or schema - **Fields / values changed:** `entityType` on all 162 entries in `src/data/protocols.json` (display-name string → canonical entity-type ID); `entityType` schema type in `src/lib/schemas.ts` (`z.string()` → `z.enum([...13 IDs])`) - **Source of each change:** deterministic computation from already-authored `entity-types.json` / the XLSX `Entity Type Defs` sheet — no new values invented - [x] No AI-derived values enter canonical fields silently - [ ] Reviewed by the data authority (Brandon, @Enli10ment), or queued for his review
Closes deferred item W1 from Story 3.5 code review. Adds
'decentralized-data-protocol' and 'decentralized-monetary-protocol' to
ENTITY_TYPE_IDS in src/lib/schemas.ts so the Zod enum matches all 15
IDs already defined in src/data/entity-types.json. No UI consumer
changes needed — all display surfaces already resolve labels through the
entityTypeMap lookup pattern established in Story 3.5.

Prevents build failure when Zach's DWeb integration branch (185
protocols: 162 + 10 DD Pro + 13 DM Pro) converges with this branch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This pull request has changes conflicting with the target branch.
  • _bmad-output/implementation-artifacts/deferred-work.md
  • _bmad-output/implementation-artifacts/sprint-status.yaml
  • docs/capture-risk-methodology.md
  • research/protocols/OpenHaven-for-P2P-Convergence.xlsx
  • scripts/convert-xlsx.py
  • src/components/islands/ComparisonView.tsx
  • src/components/islands/MatrixTable.tsx
  • src/components/islands/NavigatorSection.tsx
  • src/components/islands/ProtocolCard.tsx
  • src/components/islands/ProtocolResults.tsx
  • src/data/attribute-defs.json
  • src/data/protocols.json
  • src/i18n/en.ts
  • src/i18n/pt-BR.ts
  • src/lib/schemas.ts
  • src/pages/prototype/domains/[slug].astro
  • src/pages/prototype/index.astro
  • src/pages/prototype/matrix.astro
  • src/pages/prototype/navigator.astro
  • src/pages/prototype/protocols/[id].astro
  • src/pages/pt-BR/prototype/domains/[slug].astro
  • src/pages/pt-BR/prototype/index.astro
  • src/pages/pt-BR/prototype/matrix.astro
  • src/pages/pt-BR/prototype/navigator.astro
  • src/pages/pt-BR/prototype/protocols/[id].astro
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feature/OPE-29-schema-hardening:feature/OPE-29-schema-hardening
git switch feature/OPE-29-schema-hardening

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff feature/OPE-29-schema-hardening
git switch feature/OPE-29-schema-hardening
git rebase main
git switch main
git merge --ff-only feature/OPE-29-schema-hardening
git switch feature/OPE-29-schema-hardening
git rebase main
git switch main
git merge --no-ff feature/OPE-29-schema-hardening
git switch main
git merge --squash feature/OPE-29-schema-hardening
git switch main
git merge --ff-only feature/OPE-29-schema-hardening
git switch main
git merge feature/OPE-29-schema-hardening
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
openhaven/openhaven.net!11
No description provided.