From 333a810480ef9856301999f3fb93510b59321763 Mon Sep 17 00:00:00 2001 From: ProfessorPolymorphic <116023536+ProfessorPolymorphic@users.noreply.github.com> Date: Sun, 3 May 2026 14:32:20 -0700 Subject: [PATCH] =?UTF-8?q?Bump=20data-governance=20submodule=20+=20rename?= =?UTF-8?q?=20InterventionStatus=20=E2=86=92=20ProjectStatus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Picks up the upstream rename from ui-insight/data-governance#14 and threads the new vocabulary group identifier through every consumer. This is slice 2 of epic #189 (rename "intervention" → "project"); upstream PR slice was #190. Changes: - vendor/data-governance pointer: f6afe34 → 902b73a (the upstream rename PR's merge commit). - lib/governance/vocabularies.ts: regenerated via npm run build:governance. Auto-generated; do not hand-edit. - TypeScript type and guard renames across consumers: InterventionStatus → ProjectStatus isInterventionStatus() → isProjectStatus() Touched: lib/portfolio.ts (definitions), lib/portfolio-verification.ts, lib/lifecycle-display.ts, lib/governance/types.ts (comment), app/portfolio/page.tsx, app/admin/registry/new/page.tsx (comment), components/PortfolioCard.tsx, components/PortfolioFilters.tsx. Verified: - npm run build:governance — clean; emits ProjectStatus. - npm run build — clean (no type errors, all 80+ static paths prerendered). - npm run verify:portfolio — passes. - grep -rn "InterventionStatus" — zero matches outside vendor and build artifacts. - scripts/governance-drift.py / governance-pr-summary.ts / governance-freshness.ts carry no string references to the renamed group; CI logic is unaffected. Out of scope for this slice (handled in the remaining slices): - Component file rename InterventionDetail.tsx → ProjectDetail.tsx and the broader Intervention type rename — slice #192. - User-facing JSX copy ("intervention" prose) and docs (CLAUDE.md, REFACTOR.md, ADR 0001, etc.) — slice #193. Closes #191. Refs #189. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/admin/registry/new/page.tsx | 2 +- app/portfolio/page.tsx | 12 ++++++------ components/PortfolioCard.tsx | 4 ++-- components/PortfolioFilters.tsx | 6 +++--- lib/governance/types.ts | 2 +- lib/governance/vocabularies.ts | 32 ++++++++++++++++---------------- lib/lifecycle-display.ts | 12 ++++++------ lib/portfolio-verification.ts | 6 +++--- lib/portfolio.ts | 6 +++--- vendor/data-governance | 2 +- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/app/admin/registry/new/page.tsx b/app/admin/registry/new/page.tsx index f3f9935..873a1a3 100644 --- a/app/admin/registry/new/page.tsx +++ b/app/admin/registry/new/page.tsx @@ -4,7 +4,7 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; -// Lifecycle taxonomy from ADR 0001 — see lib/portfolio.ts InterventionStatus. +// Lifecycle taxonomy from ADR 0001 — see lib/portfolio.ts ProjectStatus. const STATUS_OPTIONS = [ "idea", "approved", "building", "prototype", "piloting", "production", "maintained", "sunsetting", "archived", "tracked", diff --git a/app/portfolio/page.tsx b/app/portfolio/page.tsx index 1b360dd..c857feb 100644 --- a/app/portfolio/page.tsx +++ b/app/portfolio/page.tsx @@ -15,10 +15,10 @@ import { import { PUBLIC_STAGE_ORDER, STAGE_OPERATIONAL_ROLLUP, - isInterventionStatus, + isProjectStatus, publicStageFromStatus, } from "@/lib/lifecycle-display"; -import type { InterventionStatus, PublicStage } from "@/lib/portfolio"; +import type { ProjectStatus, PublicStage } from "@/lib/portfolio"; export const dynamic = "force-dynamic"; @@ -82,8 +82,8 @@ export default async function PortfolioPage({ ? (params.stage!.trim() as PublicStage) : null; const rawStatus = params.status?.trim(); - const selectedStatus: InterventionStatus | null = - rawStatus && isInterventionStatus(rawStatus) ? rawStatus : null; + const selectedStatus: ProjectStatus | null = + rawStatus && isProjectStatus(rawStatus) ? rawStatus : null; const selectedCategory: WorkCategory | null = isWorkCategory( params.category?.trim() ) @@ -98,7 +98,7 @@ export default async function PortfolioPage({ // available to filter by even after they've applied something. const homeUnitCounts = new Map(); const stageCounts = new Map(); - const operationalCounts = new Map(); + const operationalCounts = new Map(); const categoryCounts = new Map(); for (const app of allApps) { for (const unit of app.homeUnits) { @@ -106,7 +106,7 @@ export default async function PortfolioPage({ } const stage = publicStageFromStatus(app.status); stageCounts.set(stage, (stageCounts.get(stage) ?? 0) + 1); - if (isInterventionStatus(app.status)) { + if (isProjectStatus(app.status)) { operationalCounts.set( app.status, (operationalCounts.get(app.status) ?? 0) + 1 diff --git a/components/PortfolioCard.tsx b/components/PortfolioCard.tsx index 13141a8..e1a4d96 100644 --- a/components/PortfolioCard.tsx +++ b/components/PortfolioCard.tsx @@ -7,7 +7,7 @@ import { OPERATIONAL_LABEL, PUBLIC_STAGE_CHIP, PUBLIC_STAGE_LABEL, - isInterventionStatus, + isProjectStatus, publicStageFromStatus, } from "@/lib/lifecycle-display"; @@ -85,7 +85,7 @@ export default function PortfolioCard({ // doesn't apply to externally-owned interventions, so the primary // stage chip carries the whole signal. (See ADR 0001.) const showOperationalChip = - isInterventionStatus(app.status) && app.status !== "tracked"; + isProjectStatus(app.status) && app.status !== "tracked"; return (
diff --git a/components/PortfolioFilters.tsx b/components/PortfolioFilters.tsx index 9bac2f7..5095dcb 100644 --- a/components/PortfolioFilters.tsx +++ b/components/PortfolioFilters.tsx @@ -8,7 +8,7 @@ import { STAGE_OPERATIONAL_ROLLUP, publicStageFromStatus, } from "@/lib/lifecycle-display"; -import type { InterventionStatus, PublicStage } from "@/lib/portfolio"; +import type { ProjectStatus, PublicStage } from "@/lib/portfolio"; // Pure URL-state filter chip group. The portfolio page builds the option // lists from the unfiltered data and passes them in; clicking a pill @@ -27,7 +27,7 @@ interface StageFilterOption { } interface OperationalFilterOption { - status: InterventionStatus; + status: ProjectStatus; count: number; } @@ -42,7 +42,7 @@ export interface PortfolioFiltersProps { selected: { unit: string | null; stage: PublicStage | null; - status: InterventionStatus | null; + status: ProjectStatus | null; category: string | null; blockers: boolean; sort: "default" | "name" | "blockers"; diff --git a/lib/governance/types.ts b/lib/governance/types.ts index ef1e08b..ba66b00 100644 --- a/lib/governance/types.ts +++ b/lib/governance/types.ts @@ -52,7 +52,7 @@ export interface VocabularyValue { displayOrder?: number; description?: string; // Per-value verification rule (ADR 0001, iids-portfolio domain). - // Currently populated only for InterventionStatus and PublicStage; + // Currently populated only for ProjectStatus and PublicStage; // other domains/groups leave it unset. The catalog records what the // rule *is* — implementation lives in lib/portfolio-verification.ts. verificationRule?: string; diff --git a/lib/governance/vocabularies.ts b/lib/governance/vocabularies.ts index 6a8a443..9501128 100644 --- a/lib/governance/vocabularies.ts +++ b/lib/governance/vocabularies.ts @@ -565,8 +565,8 @@ export const vocabularyGroups: VocabularyGroup[] = [ { "domain": "iids-portfolio", "application": "IIDS Portfolio", - "group": "InterventionStatus", - "description": "Operational ladder for an intervention — the day-to-day status IIDS tracks. Source of truth: lib/portfolio.ts. Each value's Verification_Rule is enforced by lib/portfolio-verification.ts on every PR.", + "group": "ProjectStatus", + "description": "Operational ladder for a project — the day-to-day status IIDS tracks. Source of truth: lib/portfolio.ts. Each value's Verification_Rule is enforced by lib/portfolio-verification.ts on every PR.", "values": [ { "code": "idea", @@ -622,7 +622,7 @@ export const vocabularyGroups: VocabularyGroup[] = [ "label": "Sunsetting", "displayOrder": 8, "description": "Being wound down with a planned successor.", - "verificationRule": "sunsetDate (ISO) set; replacedBy populated — successor intervention slug or the literal 'manual-process'." + "verificationRule": "sunsetDate (ISO) set; replacedBy populated — successor project slug or the literal 'manual-process'." }, { "code": "archived", @@ -635,7 +635,7 @@ export const vocabularyGroups: VocabularyGroup[] = [ "code": "tracked", "label": "Tracked", "displayOrder": 10, - "description": "Externally-owned intervention IIDS observes but does not build.", + "description": "Externally-owned project IIDS observes but does not build.", "verificationRule": "trackingOnly:true; bypasses the operational ladder." } ] @@ -644,42 +644,42 @@ export const vocabularyGroups: VocabularyGroup[] = [ "domain": "iids-portfolio", "application": "IIDS Portfolio", "group": "PublicStage", - "description": "Stakeholder-facing rollup. Computed deterministically from InterventionStatus by lib/portfolio.ts:computePublicStage. The public surfaces (/portfolio cards primary chip, landing stat strip, /explore tile breakdowns) render this axis; operational status is only shown as a secondary detail on cards.", + "description": "Stakeholder-facing rollup. Computed deterministically from ProjectStatus by lib/portfolio.ts:computePublicStage. The public surfaces (/portfolio cards primary chip, landing stat strip, /explore tile breakdowns) render this axis; operational status is only shown as a secondary detail on cards.", "values": [ { "code": "exploring", "label": "Exploring", "displayOrder": 1, "description": "Thinking about it / committed to build.", - "verificationRule": "Rolls up from InterventionStatus values: idea, approved." + "verificationRule": "Rolls up from ProjectStatus values: idea, approved." }, { "code": "building", "label": "Building", "displayOrder": 2, "description": "Code exists; not yet for real users.", - "verificationRule": "Rolls up from InterventionStatus values: building, prototype." + "verificationRule": "Rolls up from ProjectStatus values: building, prototype." }, { "code": "live", "label": "Live", "displayOrder": 3, "description": "In use today.", - "verificationRule": "Rolls up from InterventionStatus values: piloting, production, maintained." + "verificationRule": "Rolls up from ProjectStatus values: piloting, production, maintained." }, { "code": "retired", "label": "Retired", "displayOrder": 4, "description": "Done or winding down.", - "verificationRule": "Rolls up from InterventionStatus values: sunsetting, archived." + "verificationRule": "Rolls up from ProjectStatus values: sunsetting, archived." }, { "code": "tracked", "label": "Tracked", "displayOrder": 5, "description": "Not built by IIDS.", - "verificationRule": "Rolls up from InterventionStatus value: tracked. Bypasses the operational ladder." + "verificationRule": "Rolls up from ProjectStatus value: tracked. Bypasses the operational ladder." } ] }, @@ -687,13 +687,13 @@ export const vocabularyGroups: VocabularyGroup[] = [ "domain": "iids-portfolio", "application": "IIDS Portfolio", "group": "ProductionScope", - "description": "Granularity of production reach. Required on InterventionStatus values production and maintained.", + "description": "Granularity of production reach. Required on ProjectStatus values production and maintained.", "values": [ { "code": "home-unit", "label": "Home Unit", "displayOrder": 1, - "description": "Accessible to all users in the intervention's home unit." + "description": "Accessible to all users in the project's home unit." }, { "code": "institution-wide", @@ -713,7 +713,7 @@ export const vocabularyGroups: VocabularyGroup[] = [ "domain": "iids-portfolio", "application": "IIDS Portfolio", "group": "Visibility", - "description": "Public-site disclosure level for an intervention's record.", + "description": "Public-site disclosure level for a project's record.", "values": [ { "code": "Public", @@ -739,7 +739,7 @@ export const vocabularyGroups: VocabularyGroup[] = [ "domain": "iids-portfolio", "application": "IIDS Portfolio", "group": "AI4RARelationship", - "description": "How an intervention relates to the AI4RA partnership (UI + Southern Utah University NSF GRANTED).", + "description": "How a project relates to the AI4RA partnership (UI + Southern Utah University NSF GRANTED).", "values": [ { "code": "Core", @@ -777,7 +777,7 @@ export const vocabularyGroups: VocabularyGroup[] = [ "domain": "iids-portfolio", "application": "IIDS Portfolio", "group": "WorkCategory", - "description": "By-problem axis for browsing the portfolio. Audience-facing labels written in a Dean's vocabulary (not technical jargon). Source of truth: lib/work-categories.ts. One intervention can sit in 2-3 categories.", + "description": "By-problem axis for browsing the portfolio. Audience-facing labels written in a Dean's vocabulary (not technical jargon). Source of truth: lib/work-categories.ts. One project can sit in 2-3 categories.", "values": [ { "code": "documents", @@ -825,7 +825,7 @@ export const vocabularyGroups: VocabularyGroup[] = [ "code": "ai-infrastructure", "label": "AI infrastructure", "displayOrder": 8, - "description": "LLM gateways, GPU stacks, agent platforms — the plumbing other interventions run on, not a problem on its own." + "description": "LLM gateways, GPU stacks, agent platforms — the plumbing other projects run on, not a problem on its own." } ] }, diff --git a/lib/lifecycle-display.ts b/lib/lifecycle-display.ts index 74e40b2..05f2a96 100644 --- a/lib/lifecycle-display.ts +++ b/lib/lifecycle-display.ts @@ -14,7 +14,7 @@ import { computePublicStage, - type InterventionStatus, + type ProjectStatus, type PublicStage, } from "./portfolio"; @@ -47,7 +47,7 @@ export const PUBLIC_STAGE_ORDER: PublicStage[] = [ "tracked", ]; -export const OPERATIONAL_LABEL: Record = { +export const OPERATIONAL_LABEL: Record = { idea: "Idea", approved: "Approved", building: "Building", @@ -63,7 +63,7 @@ export const OPERATIONAL_LABEL: Record = { // Inverse of computePublicStage — for the filter drill-in. // Lists the 1-N operational states that roll up into each public stage, // in approximate ladder order. -export const STAGE_OPERATIONAL_ROLLUP: Record = { +export const STAGE_OPERATIONAL_ROLLUP: Record = { exploring: ["idea", "approved"], building: ["building", "prototype"], live: ["piloting", "production", "maintained"], @@ -76,11 +76,11 @@ export const STAGE_OPERATIONAL_ROLLUP: Record // canonical 10-value union (drift, legacy data, etc.), bucket it as // `exploring` so the UI never crashes. export function publicStageFromStatus(status: string): PublicStage { - if (isInterventionStatus(status)) return computePublicStage(status); + if (isProjectStatus(status)) return computePublicStage(status); return "exploring"; } -const STATUSES: ReadonlyArray = [ +const STATUSES: ReadonlyArray = [ "idea", "approved", "building", @@ -93,7 +93,7 @@ const STATUSES: ReadonlyArray = [ "tracked", ]; -export function isInterventionStatus(s: string): s is InterventionStatus { +export function isProjectStatus(s: string): s is ProjectStatus { return (STATUSES as readonly string[]).includes(s); } diff --git a/lib/portfolio-verification.ts b/lib/portfolio-verification.ts index 11defd3..db9b95c 100644 --- a/lib/portfolio-verification.ts +++ b/lib/portfolio-verification.ts @@ -16,12 +16,12 @@ // (see ADR — "skip gracefully"). // ============================================================ -import type { Intervention, InterventionStatus } from "./portfolio"; +import type { Intervention, ProjectStatus } from "./portfolio"; import { portfolioMeta } from "./portfolio-meta"; export interface VerificationProblem { slug: string; - claimedStatus: InterventionStatus; + claimedStatus: ProjectStatus; problem: string; rule: string; severity: "error" | "warning"; @@ -311,7 +311,7 @@ const verifyUniversal: Verifier = (i) => { return problems; }; -const verifiers: Record = { +const verifiers: Record = { idea: verifyIdea, approved: verifyApproved, building: verifyBuilding, diff --git a/lib/portfolio.ts b/lib/portfolio.ts index 8517046..f581784 100644 --- a/lib/portfolio.ts +++ b/lib/portfolio.ts @@ -20,7 +20,7 @@ export type Visibility = // Operational ladder — see docs/adr/0001-product-lifecycle-taxonomy.md. // 9 lifecycle states + 1 meta state (`tracked`). Verification rules for // each are spec'd in the ADR; the verifier itself lands in a follow-up PR. -export type InterventionStatus = +export type ProjectStatus = | "idea" | "approved" | "building" @@ -78,7 +78,7 @@ export interface Intervention { buildParticipants: string[]; // Status - status: InterventionStatus; + status: ProjectStatus; visibility: Visibility; institutionalReviewStatus?: InstitutionalReviewStatus; @@ -541,7 +541,7 @@ export const interventions: Intervention[] = [ // ============================================================ // Operational status → public stage rollup. See ADR 0001. -export function computePublicStage(status: InterventionStatus): PublicStage { +export function computePublicStage(status: ProjectStatus): PublicStage { switch (status) { case "idea": case "approved": diff --git a/vendor/data-governance b/vendor/data-governance index f6afe34..902b73a 160000 --- a/vendor/data-governance +++ b/vendor/data-governance @@ -1 +1 @@ -Subproject commit f6afe345927f5ab2386a4f92598ff36048f70635 +Subproject commit 902b73aaacd7a0b2be180997c862cae3f0072633