{
  "schema_version": 1,
  "generated_at": "2026-06-25T08:30:51.070Z",
  "total": 157,
  "counts": {
    "registered-and-built": 30,
    "registered-missing-dist": 33,
    "ready-to-retire": 10,
    "retired": 13,
    "lift-in-flight": 2,
    "lift-pending": 67,
    "keep-local": 2
  },
  "entries": [
    {
      "name": "tokens",
      "tier": "token",
      "tag": null,
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/tokens/src/tokens.json",
      "dist": "packages/tokens/src/tokens.css",
      "package": "@gyrum-labs/tokens",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "action-button",
      "tier": "atom",
      "tag": "gy-action-button",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/action-button/action-button.ts",
      "dist": "packages/components/dist/atoms/action-button/action-button.js",
      "package": "@gyrum-labs/components/atoms/action-button/action-button.js",
      "svelte_adapter": "@gyrum-labs/svelte/action-button",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "badge",
      "tier": "atom",
      "tag": "gy-badge",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/badge/badge.ts",
      "dist": "packages/components/dist/atoms/badge/badge.js",
      "package": "@gyrum-labs/components/atoms/badge/badge.js",
      "svelte_adapter": "@gyrum-labs/svelte/badge",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "button",
      "tier": "atom",
      "tag": "gy-button",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/button/button.ts",
      "dist": "packages/components/dist/atoms/button/button.js",
      "package": "@gyrum-labs/components/atoms/button/button.js",
      "svelte_adapter": "@gyrum-labs/svelte/button",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "dot",
      "tier": "atom",
      "tag": "gy-dot",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/dot/dot.ts",
      "dist": "packages/components/dist/atoms/dot/dot.js",
      "package": "@gyrum-labs/components/atoms/dot/dot.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "empty-state",
      "tier": "atom",
      "tag": "gy-empty-state",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/empty-state/empty-state.ts",
      "dist": "packages/components/dist/atoms/empty-state/empty-state.js",
      "package": "@gyrum-labs/components/atoms/empty-state/empty-state.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "form",
      "tier": "atom",
      "tag": "gy-form",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/form/form.ts",
      "dist": "packages/components/dist/atoms/form/form.js",
      "package": "@gyrum-labs/components/atoms/form/form.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "form-field",
      "tier": "atom",
      "tag": "gy-form-field",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/form-field/form-field.ts",
      "dist": "packages/components/dist/atoms/form-field/form-field.js",
      "package": "@gyrum-labs/components/atoms/form-field/form-field.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "image-drop",
      "tier": "atom",
      "tag": "gy-image-drop",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/image-drop/image-drop.ts",
      "dist": "packages/components/dist/atoms/image-drop/image-drop.js",
      "package": "@gyrum-labs/components/image-drop/image-drop.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyImageDrop.svelte",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "page-empty-state",
      "tier": "atom",
      "tag": "gy-page-empty-state",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/page-empty-state/page-empty-state.ts",
      "dist": "packages/components/dist/atoms/page-empty-state/page-empty-state.js",
      "package": "@gyrum-labs/components/atoms/page-empty-state/page-empty-state.js",
      "svelte_adapter": "@gyrum-labs/svelte/page-empty-state",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "page-hero",
      "tier": "atom",
      "tag": "gy-page-hero",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/page-hero/page-hero.ts",
      "dist": "packages/components/dist/atoms/page-hero/page-hero.js",
      "package": "@gyrum-labs/components/atoms/page-hero/page-hero.js",
      "svelte_adapter": "@gyrum-labs/svelte/page-hero",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "section-h",
      "tier": "atom",
      "tag": "gy-section-h",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/section-h/section-h.ts",
      "dist": "packages/components/dist/atoms/section-h/section-h.js",
      "package": "@gyrum-labs/components/atoms/section-h/section-h.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "select",
      "tier": "atom",
      "tag": "gy-select",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/select/select.ts",
      "dist": "packages/components/dist/atoms/select/select.js",
      "package": "@gyrum-labs/components/atoms/select/select.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "sparkline",
      "tier": "atom",
      "tag": "gy-sparkline",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/sparkline/sparkline.ts",
      "dist": "packages/components/dist/atoms/sparkline/sparkline.js",
      "package": "@gyrum-labs/components/atoms/sparkline/sparkline.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "spinner",
      "tier": "atom",
      "tag": "gy-spinner",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/spinner/spinner.ts",
      "dist": "packages/components/dist/atoms/spinner/spinner.js",
      "package": "@gyrum-labs/components/atoms/spinner/spinner.js",
      "svelte_adapter": "@gyrum-labs/svelte/spinner",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "breadcrumbs",
      "tier": "atom",
      "tag": "gy-breadcrumbs",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/breadcrumbs/GyBreadcrumbs.svelte",
      "dist": "packages/svelte/src/atoms/breadcrumbs/GyBreadcrumbs.svelte",
      "package": "@gyrum-labs/svelte/atoms/breadcrumbs/GyBreadcrumbs.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/breadcrumbs/GyBreadcrumbs.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "build-shortcut-card",
      "tier": "atom",
      "tag": "gy-build-shortcut-card",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/build-shortcut-card/GyBuildShortcutCard.svelte",
      "dist": "packages/svelte/src/atoms/build-shortcut-card/GyBuildShortcutCard.svelte",
      "package": "@gyrum-labs/svelte/atoms/build-shortcut-card/GyBuildShortcutCard.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/build-shortcut-card/GyBuildShortcutCard.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "cluster",
      "tier": "atom",
      "tag": "gy-cluster",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/cluster/cluster.ts",
      "dist": "packages/components/dist/atoms/cluster/cluster.js",
      "package": "@gyrum-labs/components/atoms/cluster/cluster.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyCluster.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "data-table",
      "tier": "atom",
      "tag": "gy-data-table",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/data-table/GyDataTable.svelte",
      "dist": "packages/svelte/src/atoms/data-table/GyDataTable.svelte",
      "package": "@gyrum-labs/svelte/atoms/data-table/GyDataTable.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/data-table/GyDataTable.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "disclosure",
      "tier": "atom",
      "tag": "gy-disclosure",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/disclosure/disclosure.ts",
      "dist": "packages/components/dist/atoms/disclosure/disclosure.js",
      "package": "@gyrum-labs/components/atoms/disclosure/disclosure.js",
      "svelte_adapter": null,
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "docs-status-banner",
      "tier": "atom",
      "tag": "gy-docs-status-banner",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/docs-status-banner/GyDocsStatusBanner.svelte",
      "dist": "packages/svelte/src/atoms/docs-status-banner/GyDocsStatusBanner.svelte",
      "package": "@gyrum-labs/svelte/atoms/docs-status-banner/GyDocsStatusBanner.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/docs-status-banner/GyDocsStatusBanner.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "draggable-clickable-node",
      "tier": "atom",
      "tag": null,
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/draggable-clickable-node/draggable-clickable-node.ts",
      "dist": "packages/svelte/src/atoms/draggable-clickable-node/draggable-clickable-node.ts",
      "package": "@gyrum-labs/svelte/atoms/draggable-clickable-node/draggable-clickable-node",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/draggable-clickable-node/draggable-clickable-node",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "duration-budget",
      "tier": "atom",
      "tag": "gy-duration-budget",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/duration-budget/GyDurationBudget.svelte",
      "dist": "packages/svelte/src/atoms/duration-budget/GyDurationBudget.svelte",
      "package": "@gyrum-labs/svelte/atoms/duration-budget/GyDurationBudget.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/duration-budget/GyDurationBudget.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "fleet-drift-badge",
      "tier": "atom",
      "tag": "gy-fleet-drift-badge",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/fleet-drift-badge/GyFleetDriftBadge.svelte",
      "dist": "packages/svelte/src/atoms/fleet-drift-badge/GyFleetDriftBadge.svelte",
      "package": "@gyrum-labs/svelte/atoms/fleet-drift-badge/GyFleetDriftBadge.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/fleet-drift-badge/GyFleetDriftBadge.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "fleet-version",
      "tier": "atom",
      "tag": "gy-fleet-version",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/fleet-version/GyFleetVersion.svelte",
      "dist": "packages/svelte/src/atoms/fleet-version/GyFleetVersion.svelte",
      "package": "@gyrum-labs/svelte/atoms/fleet-version/GyFleetVersion.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/fleet-version/GyFleetVersion.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "grid",
      "tier": "atom",
      "tag": "gy-grid",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/grid/grid.ts",
      "dist": "packages/components/dist/atoms/grid/grid.js",
      "package": "@gyrum-labs/components/atoms/grid/grid.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyGrid.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "install-card",
      "tier": "atom",
      "tag": "gy-install-card",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/install-card/GyInstallCard.svelte",
      "dist": "packages/svelte/src/atoms/install-card/GyInstallCard.svelte",
      "package": "@gyrum-labs/svelte/atoms/install-card/GyInstallCard.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/install-card/GyInstallCard.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "page-stub",
      "tier": "atom",
      "tag": "gy-page-stub",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/page-stub/GyPageStub.svelte",
      "dist": "packages/svelte/src/atoms/page-stub/GyPageStub.svelte",
      "package": "@gyrum-labs/svelte/atoms/page-stub/GyPageStub.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/page-stub/GyPageStub.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "release-status-badge",
      "tier": "atom",
      "tag": "gy-release-status-badge",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/release-status-badge/GyReleaseStatusBadge.svelte",
      "dist": "packages/svelte/src/atoms/release-status-badge/GyReleaseStatusBadge.svelte",
      "package": "@gyrum-labs/svelte/atoms/release-status-badge/GyReleaseStatusBadge.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/release-status-badge/GyReleaseStatusBadge.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "stack",
      "tier": "atom",
      "tag": "gy-stack",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/stack/stack.ts",
      "dist": "packages/components/dist/atoms/stack/stack.js",
      "package": "@gyrum-labs/components/atoms/stack/stack.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyStack.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "value",
      "tier": "atom",
      "tag": "gy-value",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/atoms/value/value.ts",
      "dist": "packages/components/dist/atoms/value/value.js",
      "package": "@gyrum-labs/components/value/value.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyValue.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "version-badge",
      "tier": "atom",
      "tag": "gy-version-badge",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/atoms/version-badge/GyVersionBadge.svelte",
      "dist": "packages/svelte/src/atoms/version-badge/GyVersionBadge.svelte",
      "package": "@gyrum-labs/svelte/atoms/version-badge/GyVersionBadge.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/atoms/version-badge/GyVersionBadge.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "version-badge",
      "tier": "atom",
      "tag": "gy-version-badge",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/VersionBadge.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#2278",
      "blocker": null
    },
    {
      "name": "page-empty-state",
      "tier": "atom",
      "tag": "gy-page-empty-state",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/EmptyState.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2419",
      "blocker": null
    },
    {
      "name": "page-hero",
      "tier": "atom",
      "tag": "gy-page-hero",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/PageHero.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2397",
      "blocker": null
    },
    {
      "name": "spinner",
      "tier": "atom",
      "tag": "gy-spinner",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/Spinner.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2499",
      "blocker": null
    },
    {
      "name": "anomaly",
      "tier": "molecule",
      "tag": "gy-anomaly",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/anomaly/anomaly.ts",
      "dist": "packages/components/dist/molecules/anomaly/anomaly.js",
      "package": "@gyrum-labs/components/molecules/anomaly/anomaly.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "cost-bar",
      "tier": "molecule",
      "tag": "gy-cost-bar",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/cost-bar/cost-bar.ts",
      "dist": "packages/components/dist/molecules/cost-bar/cost-bar.js",
      "package": "@gyrum-labs/components/molecules/cost-bar/cost-bar.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "handoff",
      "tier": "molecule",
      "tag": "gy-handoff",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/handoff/handoff.ts",
      "dist": "packages/components/dist/molecules/handoff/handoff.js",
      "package": "@gyrum-labs/components/molecules/handoff/handoff.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "hero",
      "tier": "molecule",
      "tag": "gy-hero",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/hero/hero.ts",
      "dist": "packages/components/dist/molecules/hero/hero.js",
      "package": "@gyrum-labs/components/molecules/hero/hero.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "list-row",
      "tier": "molecule",
      "tag": "gy-list-row",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/list-row/list-row.ts",
      "dist": "packages/components/dist/molecules/list-row/list-row.js",
      "package": "@gyrum-labs/components/molecules/list-row/list-row.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "risk-pyramid",
      "tier": "molecule",
      "tag": "gy-risk-pyramid",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/risk-pyramid/risk-pyramid.ts",
      "dist": "packages/components/dist/molecules/risk-pyramid/risk-pyramid.js",
      "package": "@gyrum-labs/components/molecules/risk-pyramid/risk-pyramid.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "timeline",
      "tier": "molecule",
      "tag": "gy-timeline",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/timeline/timeline.ts",
      "dist": "packages/components/dist/molecules/timeline/timeline.js",
      "package": "@gyrum-labs/components/molecules/timeline/timeline.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "todo",
      "tier": "molecule",
      "tag": "gy-todo",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/todo/todo.ts",
      "dist": "packages/components/dist/molecules/todo/todo.js",
      "package": "@gyrum-labs/components/molecules/todo/todo.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "trust-meter",
      "tier": "molecule",
      "tag": "gy-trust-meter",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/trust-meter/trust-meter.ts",
      "dist": "packages/components/dist/molecules/trust-meter/trust-meter.js",
      "package": "@gyrum-labs/components/molecules/trust-meter/trust-meter.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "dot-glyph",
      "tier": "molecule",
      "tag": "gy-dot-glyph",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/dot-glyph/dot-glyph.ts",
      "dist": "packages/components/dist/molecules/dot-glyph/dot-glyph.js",
      "package": "@gyrum-labs/components/dot-glyph/dot-glyph.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyDotGlyph.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "flag",
      "tier": "molecule",
      "tag": "gy-flag",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/flag/flag.ts",
      "dist": "packages/components/dist/molecules/flag/flag.js",
      "package": "@gyrum-labs/components/flag/flag.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyFlag.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "kpi-card",
      "tier": "molecule",
      "tag": "gy-kpi-card",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/kpi-card/kpi-card.ts",
      "dist": "packages/components/dist/molecules/kpi-card/kpi-card.js",
      "package": "@gyrum-labs/components/molecules/kpi-card/kpi-card.js",
      "svelte_adapter": null,
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "list-row-footer",
      "tier": "molecule",
      "tag": "gy-list-row-footer",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/list-row-footer/list-row-footer.ts",
      "dist": "packages/components/dist/molecules/list-row-footer/list-row-footer.js",
      "package": "@gyrum-labs/components/list-row-footer/list-row-footer.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyListRowFooter.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "list-stack",
      "tier": "molecule",
      "tag": "gy-list-stack",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/list-stack/list-stack.ts",
      "dist": "packages/components/dist/molecules/list-stack/list-stack.js",
      "package": "@gyrum-labs/components/molecules/list-stack/list-stack.js",
      "svelte_adapter": null,
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "panel",
      "tier": "molecule",
      "tag": "gy-panel",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/panel/panel.ts",
      "dist": "packages/components/dist/molecules/panel/panel.js",
      "package": "@gyrum-labs/components/molecules/panel/panel.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyPanel.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "section-header",
      "tier": "molecule",
      "tag": null,
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/molecules/section-header/GySectionHeader.svelte",
      "dist": "packages/svelte/src/molecules/section-header/GySectionHeader.svelte",
      "package": "@gyrum-labs/svelte/molecules/section-header/GySectionHeader.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/molecules/section-header/GySectionHeader.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "status-card",
      "tier": "molecule",
      "tag": "gy-status-card",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/status-card/status-card.ts",
      "dist": "packages/components/dist/molecules/status-card/status-card.js",
      "package": "@gyrum-labs/components/status-card/status-card.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyStatusCard.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "step-timeline",
      "tier": "molecule",
      "tag": "gy-step-timeline",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/molecules/step-timeline/step-timeline.ts",
      "dist": "packages/components/dist/molecules/step-timeline/step-timeline.js",
      "package": "@gyrum-labs/components/molecules/step-timeline/step-timeline.js",
      "svelte_adapter": null,
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "build-shortcut-card",
      "tier": "molecule",
      "tag": "gy-build-shortcut-card",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/BuildShortcutCard.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-in-flight",
      "tracking_ticket": "warp#2518",
      "blocker": "Moved into canon/ path per warp#2518 L2 extraction; promotion to @gyrum-labs/components/molecules/ waits on warp#2278 Phase 4."
    },
    {
      "name": "docs-status-banner",
      "tier": "molecule",
      "tag": "gy-docs-status-banner",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/DocsStatusBanner.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-in-flight",
      "tracking_ticket": "warp#2518",
      "blocker": "Moved into canon/ path per warp#2518 L2 extraction; promotion to @gyrum-labs/components/molecules/ waits on warp#2278 Phase 4."
    },
    {
      "name": "duration-budget",
      "tier": "molecule",
      "tag": "gy-duration-budget",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/DurationBudget.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-in-flight",
      "tracking_ticket": "warp#2528",
      "blocker": "Moved into canon/ path per warp#2528 (warp#2518 follow-up); promotion to @gyrum-labs/components/molecules/ waits on warp#2278 Phase 4."
    },
    {
      "name": "fleet-drift-badge",
      "tier": "molecule",
      "tag": "gy-fleet-drift-badge",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/FleetDriftBadge.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#2278",
      "blocker": null
    },
    {
      "name": "fleet-version",
      "tier": "molecule",
      "tag": "gy-fleet-version",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/FleetVersion.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#2278",
      "blocker": null
    },
    {
      "name": "install-card",
      "tier": "molecule",
      "tag": "gy-install-card",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/InstallCard.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-in-flight",
      "tracking_ticket": "warp#2518",
      "blocker": "Moved into canon/ path per warp#2518 L2 extraction; promotion to @gyrum-labs/components/molecules/ waits on warp#2278 Phase 4."
    },
    {
      "name": "page-stub",
      "tier": "molecule",
      "tag": "gy-page-stub",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/PageStub.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#2278",
      "blocker": null
    },
    {
      "name": "release-status-badge",
      "tier": "molecule",
      "tag": "gy-release-status-badge",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/ReleaseStatusBadge.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#2278",
      "blocker": null
    },
    {
      "name": "worker-card",
      "tier": "molecule",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/WorkerCard.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-in-flight",
      "lift_state": "lift-in-flight",
      "tracking_ticket": "warp#2518",
      "blocker": "Moved into canon/ path per warp#2518 L2 extraction; promotion to @gyrum-labs/components/molecules/ waits on warp#2278 Phase 4."
    },
    {
      "name": "trend-chart",
      "tier": "molecule",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/projects/TrendChart.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#6253",
      "blocker": "New local-first SVG line/area primitive authored on /projects/[slug] (warp#6253 — deploy-activity panel + drift-over-time trend, Child of warp#6250). The kit had no continuous line/area chart — gy-delta-chart is grouped bars, src/lib/infra/BarChart.svelte is horizontal categorical — so this lands local per the canon-tier rule \"if genuinely novel, register it in the same PR\" (warp#3100 Path-A: consumer-tier page authoring at-tier molecule, both in one PR). Pure SVG over a sibling trend-chart-data.ts geometry helper (layoutTrend / maxTrendValue / trendAxisLabels / toneToStroke / toneToSoftFill — all unit-tested); imports NO other component (only its data helper + types), tier-2 by composition. role=img + <title> text-alt + first/last axis labels + latest-value legend + a calm empty state; tokens-only (ADR-180 — no hex, no px font-size, stylelint-clean). Renders the drift-over-time trend (commits-behind vs time) below the Deploy-status line. target_repo stays ai-frontend — Phase-4 promotion to @gyrum-labs/components/ waits on a 2nd consumer materialising (warp#3100 local-until-second-consumer rule), at which point the published canon gets a dedicated visual-contract review."
    },
    {
      "name": "live-deploys-badge",
      "tier": "molecule",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/LiveDeploysBadge.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "keep-local",
      "lift_state": "keep-local",
      "tracking_ticket": null,
      "blocker": "Fetches /api/release-status via SvelteKit's bound fetch; auth-cookie aware. The fetch shouldn't live inside a framework-agnostic web component (forces it to know about cookie/store shape). Presentation shell could lift separately, leaving the fetch in a thin svelte wrapper."
    },
    {
      "name": "breadcrumbs",
      "tier": "molecule",
      "tag": "gy-breadcrumbs",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/Breadcrumbs.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#4104",
      "blocker": "Retired in warp#4104 (canon-treatment of shared chrome, parent warp#4102). The bespoke component was the byte-identical ancestor of the canon GyBreadcrumbs atom (ported to @gyrum-labs/svelte/atoms per warp#2639 / warp#3350, ADR-182). The +layout.svelte shell and the platform-preview reference page now import GyBreadcrumbs directly; the local Breadcrumbs.svelte + its unit test are deleted (the canon package owns the contract + tests). Path retained as a historical breadcrumb of the original source location."
    },
    {
      "name": "deploy-success-ring",
      "tier": "molecule",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/projects/DeploySuccessRing.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#7546",
      "blocker": "New local-first SVG donut authored on /projects/[slug] (warp#6253). Shows the window split of deploy fires into succeeded / failed / in-flight with the success-% in the centre. Built local rather than reusing src/lib/homes/FleetDonut.svelte — FleetDonut is grandfathered hex/px AND hard-typed to a down/up/never-shipped product-health bucket vocabulary with a fixed \"products\" centre label, so it does not fit a deploy success ring; this is the local, token-compliant (ADR-180) equivalent. Pure SVG over a sibling success-ring-data.ts geometry helper (ringBuckets / ringArcs / successPct — unit-tested); imports NO other component. role=img + <title> + legend text-alt + dashed empty ring. Path-A in-ticket authoring (warp#3100). RETIRED warp 7546 — the calm campaign replaced the loud donut with a quiet success stat; no remaining consumer."
    },
    {
      "name": "epic-card",
      "tier": "organism",
      "tag": "gy-epic-card",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/organisms/epic-card/epic-card.ts",
      "dist": "packages/components/dist/organisms/epic-card/epic-card.js",
      "package": "@gyrum-labs/components/epic-card/epic-card.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyEpicCard.svelte",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "overview",
      "tier": "organism",
      "tag": "gy-overview",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/organisms/overview/overview.ts",
      "dist": "packages/components/dist/organisms/overview/overview.js",
      "package": "@gyrum-labs/components/overview/overview.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyOverview.svelte",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "pulse-grid",
      "tier": "organism",
      "tag": "gy-pulse-grid",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/organisms/pulse-grid/pulse-grid.ts",
      "dist": "packages/components/dist/organisms/pulse-grid/pulse-grid.js",
      "package": "@gyrum-labs/components/organisms/pulse-grid/pulse-grid.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "runtime-band",
      "tier": "organism",
      "tag": "gy-runtime-band",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/organisms/runtime-band/runtime-band.ts",
      "dist": "packages/components/dist/organisms/runtime-band/runtime-band.js",
      "package": "@gyrum-labs/components/organisms/runtime-band/runtime-band.js",
      "svelte_adapter": null,
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "data-table-organism",
      "tier": "organism",
      "tag": "gy-data-table-organism",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/organisms/data-table-organism/data-table-organism.ts",
      "dist": "packages/components/dist/organisms/data-table-organism/data-table-organism.js",
      "package": "@gyrum-labs/components/data-table-organism/data-table-organism.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyDataTableOrganism.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "section",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/organisms/section/GySection.svelte",
      "dist": "packages/svelte/src/organisms/section/GySection.svelte",
      "package": "@gyrum-labs/svelte/organisms/section/GySection.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/organisms/section/GySection.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "domain-card",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/DomainCard.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#4145",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside InfraDomainsListTemplate (warp#4145 — wave-3 of the canon-treatment sweep; apply the collection-page canon to /infra/domains). Sister-shape to RepoCard (warp#3915) — same single-left-dot + inline-flag + row-footer-counts vocabulary, but the row entity is a DNS zone (InfraZone) rather than a repo. Composes GyListRow (whole-row anchor to the in-app entity-detail /infra/domains/{zone}) + GyDotGlyph (typographic lifecycle glyph) + GyFlag (inline status flag for non-active zones) + GyListRowFooter (record-count + service-count). The status→single-dot mapping is DOMAINS-specific: the coarse status bucket (active / other) from domains-filter-state.ts collapses onto the two-state dot glyph (filled/open) plus two-state tone (ok/warn) — active is ok+filled with no flag, other is warn+open with the raw status spelled out in an inline flag. The Cloudflare plan rides the right meta slot. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (template) authoring at-tier (organism), so organism + template + page refactor + manifest entry land in the same PR. Consumed by InfraDomainsListTemplate (/infra/domains). target_repo stays ai-frontend — Phase-4 promotion to @gyrum-labs/components/organisms/ waits on convergence of the collection-page row organisms (RepoCard / ProjectCard / DomainCard)."
    },
    {
      "name": "drilldowns-organism",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/DrilldownsOrganism.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3617",
      "blocker": "Phase 1.4 of the warp#2278 atomic-design substrate EPIC (warp#3617, fourth slice of warp#2280). A row stack for nested choice trees — chevron + label + optional caption + optional breadcrumb of already-drilled segments. Stateless: consumer owns selection, breadcrumb, fetching. Authored alongside the WizardTemplate aside-slot enhancement + first /projects/import consumer (Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier, so organism + template enhancement + page consumer + manifest entry land in the same PR). Future consumers: any wizard step that needs org → repo → branch (or similar nested choice). Phase-4 promotion needs the Lit port + Svelte adapter pair in gyrum-labs/gyrum-ui packages/components/src/organisms/drilldowns/ — same shape as the existing epic-card / activity-panel / ticket-panel organism promotions (warp#2501 / warp#2719)."
    },
    {
      "name": "fleet-dependency-graph",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/projects/FleetDependencyGraph.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#8524",
      "blocker": "Authored under warp#8524 (fleet project dependency graph in-product on the /projects index — \"which projects depend on which, across the whole registry, as one picture\"). Tier-3 organism: a thin SVG renderer over the d3-force sim in sibling fleet-graph-sim.ts (decomposed at the seam so the component stays under the size gate), with node/edge maths in the pure fleet-graph-data.ts (deriveFleetGraph, unit-tested). NOT a fork of the per-project DependencyGraph.svelte on /projects/[slug]: that draws ONE project's consumes/consumed_by neighbourhood; this folds the WHOLE registry into one node-per-project / directed-inter-project-edge graph, node colour on the EXISTING DeployState scale (deployStateLabel — no new status scale), alias slugs collapsed the byRepoRollup way, honest hasSignal=false -> calm \"dependency graph unavailable\" note rather than a fabricated graph. Composition: GyPanel surface + GyBadge + gy-dot Lit element + PanelIcon; click-a-node -> goto(/projects/<slug>). Tokens only — no hex, no px font-size (ADR-180). Consumed by ProjectsListTemplate behind a list|graph toggle (default list, graph opt-in). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (template) authoring at-tier (organism), so organism + sim helper + data derivation + template integration + manifest entry land in the same PR. target_repo stays ai-frontend — Phase-4 promotion to @gyrum-labs/components/ waits on a second consumer materialising (warp#3100 local-until-second-consumer rule), at which point the published canon gets a dedicated visual-contract review."
    },
    {
      "name": "operator-row",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/OperatorRow.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#4141",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside OperatorsListTemplate (warp#4141 — wave-2 of the canon-treatment sweep; apply /projects calm-first canon to /operators). Sister-shape to RepoCard (warp#3915) / ProjectCard (warp#3823) — same single-left-dot + inline-flag + row-footer-counts vocabulary, but the row entity is an operator (a reusable pipeline primitive) rather than a repo or project. Composes GyListRow (whole-row anchor to the in-app entity-detail /operators/{name}) + GyDotGlyph (typographic lifecycle glyph) + GyFlag (inline disambiguating flags) + GyListRowFooter (counts). Usage→single-dot mapping is OPERATOR-specific: operators have no explicit lifecycle field, so \"is this primitive actually wired into a pipeline?\" (usage > 0) is the single at-a-glance signal — used routes to a filled `ok` dot, unused to an open `unknown` dot plus an `unused` inline flag; a category pill is always shown so a row read in isolation still states its category; the model identifier is the right-meta slot. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (template) authoring at-tier (organism), so organism + template + page refactor + manifest entry land in the same PR. Consumed by OperatorsListTemplate (/operators). target_repo stays ai-frontend — Phase-4 promotion to @gyrum-labs/components/organisms/ waits on convergence of the list-row organisms (ProjectCard / RepoCard / OperatorRow) into one parameterised row."
    },
    {
      "name": "pipeline-conveyor",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/PipelineConveyor.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#2278",
      "blocker": null
    },
    {
      "name": "pipeline-conveyor-v2",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/PipelineConveyorV2.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#2278",
      "blocker": null
    },
    {
      "name": "pipeline-row",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PipelineRow.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#4140",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside PipelinesListTemplate (warp#4140 — wave-2 of the canon-treatment sweep; apply the /infra/repos collection-page canon to /pipelines). Sister-shape to RepoCard (warp#3915) and ProjectCard (warp#3823) — same single-left-dot + inline-flag + row-footer-counts vocabulary, but the row entity is a pipeline (a declarative orchestration programme) rather than a repo or project. Composes GyListRow (whole-row anchor into the in-app entity-detail /pipelines/{name}) + GyDotGlyph (typographic lifecycle glyph) + GyFlag (inline legacy flag) + GyListRowFooter (step-count + phase chips). Lifecycle → single-dot mapping is PIPELINES-specific and binary: declarative (runnable from pipeline.json) maps to filled/ok, legacy (display-only imperative runner not yet convertible) maps to half/warn with an inline `legacy · display-only` flag carrying the detail the half-dot alone cannot express. Data contract IDENTICAL to the pre-canon table — same PipelineSummary (name / stepCount / phases / legacy). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (template) authoring at-tier (organism), so organism + template + page refactor + manifest entry land in the same PR. Consumed by PipelinesListTemplate (/pipelines); target_repo stays ai-frontend — Phase-4 promotion to @gyrum-labs/components/organisms/ waits on the row organisms (ProjectCard / RepoCard / PipelineRow) converging into one parameterised list-row organism."
    },
    {
      "name": "project-activity-feed",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/projects/ProjectActivityFeed.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7804",
      "blocker": "Authored under warp#7804 (per-project Activity feed on /projects/[slug] — \"is work being actioned on THIS project right now?\"). Tier-3 organism joining three sources newest-first with status chips: playbook runs (the /operate recent-runs BFF /api/operate/recent-playbook-runs, warp#320, filtered by inputs.project_name per the warp#925 multi-tenant deploy-project shape), merged PRs (the /api/platform/[slug]/activity BFF, warp#344), and warp items (the /api/platform/[slug]/tickets BFF, warp#344) — no new endpoint; the registry entry repos[] drives both project-scoped BFFs server-side. NOT a fork of the canon activity-panel organism (3.1.1): GyActivityPanel chips by ITEM TYPE on a fixed type->variant map and carries no per-row STATUS chip, which is the warp#7804 acceptance (succeeded/failed/running/merged/in-progress tones on the shared StatusVariant palette) — extending the canon organism with a status-chip contract is the Phase-4 promotion question, deferred until a second consumer materialises (warp#3100 local-until-second-consumer rule). Composition: gy-list-row molecule rows + GyBadge status chip + GyButton retry; pure join/filter/sort logic in sibling project-activity-feed-data.ts (unit-tested). Fail-soft per ADR-133 — each source degrades independently to a quiet degraded line; hard error only when ALL three are down. In-flight-aware polling (60s base, 15s + fresh=1 cache-bypass while a run is in flight). Consumed by ProjectDetailTemplate (the warp#4508 merges-only panel folds in as one of the three sources). Tokens only — no hex, no px font-size (ADR-180). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (template) authoring at-tier (organism), so organism + template integration + manifest entry land in the same PR."
    },
    {
      "name": "project-card",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ProjectCard.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3823",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside ProjectsListTemplate (warp#3823 / warp#3046 — apply the /projects calm-first canon). The ORIGINAL list-row organism the later sister-shapes are all modeled on — RepoCard (warp#3915), OperatorRow (warp#4141), DomainCard (warp#4145), PipelineRow (warp#4140) each cite \"sister-shape to ProjectCard (warp#3823)\" — same single-left-dot + inline-flag + row-footer-counts vocabulary, with the row entity a project (deploy stack). Composes GyListRow (whole-row anchor into the in-app entity-detail /[project]) + GyDotGlyph (typographic lifecycle glyph tinted by deploy×lifecycle) + GyFlag (inline disambiguating flags — library / staging) + GyListRowFooter (counts + tagline) + GyValue (KPI tiles, warp#7179). Consumed by ProjectsListTemplate (/projects). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (template) authoring at-tier (organism), so organism + template + page refactor + manifest entry land in the same PR. target_repo stays ai-frontend — Phase-4 promotion to @gyrum-labs/components/organisms/ waits on convergence of the list-row organisms (ProjectCard / RepoCard / OperatorRow) into one parameterised row. (Manifest entry restored warp#7498 — the template existed in canon/ with no lift entry, the exact completeness gap this ticket adds a gate for.)"
    },
    {
      "name": "repo-card",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/RepoCard.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3915",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside ShipReposListTemplate (warp#3915 — apply /projects calm-first canon to /ship/repos). Sister-shape to ProjectCard (warp#3823) — same single-left-dot + inline-flag + row-footer-counts vocabulary, but the row entity is a repo (source artefact) rather than a project (deploy stack). Composes GyListRow (whole-row anchor to github.com) + GyDotGlyph (typographic lifecycle glyph) + GyFlag (inline disambiguating flags) + GyListRowFooter (counts + tagline). Deploy×lifecycle → single-dot mapping is REPOS-specific (different from /projects): repos have no direct lifecycle field, so the five-way RepoEnrichment.relevance enum from classifyRepo (api-infra.ts) collapses onto the three-state dot glyph (filled/half/open) plus four-state tone (ok/warn/bad/unknown). Library / archived / empty all route to `unknown` (neutral, no urgency); stale + other route to `warn`; deployed is `ok`. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (template) authoring at-tier (organism), so organism + template + page refactor + manifest entry land in the same PR. Now consumed by ShipReposListTemplate (/ship/repos) and InfraReposListTemplate (/infra/repos, warp#4101); an optional href prop (warp#4101) lets /infra/repos point rows at the in-app entity-detail while /ship/repos + /me keep the github.com default byte-identical. target_repo stays ai-frontend — Phase-4 promotion to @gyrum-labs/components/organisms/ waits on convergence of the two repos-list consumers."
    },
    {
      "name": "timeline-organism",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/TimelineOrganism.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3616",
      "blocker": "Phase 1.3 of the warp#2278 atomic-design substrate EPIC (warp#3616). Tier-3 organism wrapping the @gyrum-labs/svelte molecule GyTimeline with event-source state (entries / loading / error / calm-first-empty) plus optional cluster-by-day grouping and an active-window caption. The molecule (vendored at node_modules/@gyrum-labs/svelte/src/molecules/timeline/GyTimeline.svelte) owns row geometry + XSS-safe href + density variants; the organism owns the state envelope. First production consumer is the calm-first fleet dashboard at /dev/platform-preview/dashboards/calm-first — the page's recent-activity panel migrates from an inline gy-list-row loop to <TimelineOrganism> in the same PR. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer (dashboard) tier above organism tier, so organism + consumer refactor + manifest entry land in the same PR. Future consumers: /operate (incident timeline), /infra/deploys (deploy stream), /pm/audit (audit log), /[project] (per-project event feed). Phase-4 promotion needs the Lit port + Svelte adapter pair in gyrum-labs/gyrum-ui packages/components/src/organisms/timeline/ — same shape as the worldmap / ticket-panel / activity-panel organism lift trajectory."
    },
    {
      "name": "two-col-panels-organism",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/TwoColPanelsOrganism.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3615",
      "blocker": "Phase 1.2 of the warp#2278 atomic-design substrate EPIC (warp#3615). Generic two-column panel organism with configurable split (balanced / 70-30 / 30-70); responsive — two-col on desktop (>= --breakpoint-md), stacked on mobile. First consumer is DetailTemplate's body band — the template imports TwoColPanelsOrganism and composes it at split=70-30 to lay out left/right panels; the organism owns the responsive grid, the template owns the per-panel testid wrappers. This satisfies CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\": the organism (tier-3) is authored below the consumer template (tier-4), and the consumer template USES the organism in the same diff — no orphan canon. Future consumers include any non-detail two-panel layout (dashboard card pair, compare-side-by-side view, help-doc split). Phase-4 promotion needs the Lit port + Svelte adapter pair in gyrum-labs/gyrum-ui packages/components/src/organisms/two-col-panels/."
    },
    {
      "name": "worldmap",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/Worldmap.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#2744",
      "blocker": "Pure-SVG equal-earth world map with status-coloured pins, introduced in warp#2744 for /infra/servers (one pin per host). The component has no SvelteKit dependency so the Lit port is mechanical, but the d3-geo + topojson-client + world-atlas data dependency adds ~52KB gz to whichever bundle consumes it — promotion belongs to a follow-up that decides whether gyrum-ui should ship the topojson asset itself or expect consumers to provide one."
    },
    {
      "name": "activity-panel",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ActivityPanel.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2719",
      "blocker": null
    },
    {
      "name": "bugs-summary-card",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/homes/BugsSummaryCard.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2719",
      "blocker": null
    },
    {
      "name": "data-table-organism",
      "tier": "organism",
      "tag": "gy-data-table-organism",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/DataTableOrganism.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#3618",
      "blocker": "Sister of warp#3614 (CatalogTemplate, first slice of warp#2280) — carved out during Marcus' review of PR #722 because the original Phase 1.1 PR shipped DataTableOrganism alongside CatalogTemplate without a production consumer in-PR (orphan canon per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\"). Authored here alongside the /platform/[project]/deploys migration — the page consumed <DataTableOrganism> through column-def + cell-snippet + rowDetail-snippet props, replacing the bespoke `<table class=\"data-table\">` inline composition. Lifted cross-repo at warp#3661 (gyrum-ui#109 / @gyrum-labs/svelte@1.2.9) as `<gy-data-table-organism>` Lit element + `GyDataTableOrganism` Svelte adapter; the lifted shape is slot-driven (organism owns geometry, consumer owns the `<table>`), so each consumer migrated to author its own `<table>` inside the chips/thead/tbody/empty snippets. Consumer-side retirement at warp#3801 deleted the local source + types + tests; canon now sourced exclusively from gyrum-ui."
    },
    {
      "name": "epic-card",
      "tier": "organism",
      "tag": "gy-epic-card",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/EpicCard.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2501",
      "blocker": null
    },
    {
      "name": "recent-failures-panel",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/organisms/RecentFailuresPanel.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2719",
      "blocker": null
    },
    {
      "name": "ticket-panel",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/TicketPanel.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2502",
      "blocker": null
    },
    {
      "name": "version-pill",
      "tier": "organism",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/VersionPill.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2719",
      "blocker": null
    },
    {
      "name": "rail",
      "tier": "template",
      "tag": "gy-rail",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/templates/rail/rail.ts",
      "dist": "packages/components/dist/templates/rail/rail.js",
      "package": "@gyrum-labs/components/rail/rail.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyRail.svelte",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "catalog-template",
      "tier": "template",
      "tag": "gy-catalog-template",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/templates/catalog-template/catalog-template.ts",
      "dist": "packages/components/dist/templates/catalog-template/catalog-template.js",
      "package": "@gyrum-labs/components/catalog-template/catalog-template.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyCatalogTemplate.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "catalog-template",
      "tier": "template",
      "tag": "gy-catalog-template",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/CatalogTemplate.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "ready-to-retire",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3614",
      "blocker": "Phase 1.1 of the warp#2278 atomic-design substrate EPIC (warp#3614, first slice of warp#2280). Authored alongside ProjectsListTemplate's refactor — the registry template now composes <CatalogTemplate> and fills its five snippet slots (hero, kpiStrip, controls, body, footer); the outer page chrome (max-width + gutters + section gaps) lives in CatalogTemplate. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (template) authoring at-tier, so template + consumer refactor + manifest entry land in the same PR. Generic over the item shape; future consumers include /infra/servers, /platform/[project]/deploys, /tickets, /workers — every catalog page that today either DIYs the chrome or duplicates ProjectsListTemplate. Phase-4 promotion needs the Lit port + Svelte adapter pair in gyrum-labs/gyrum-ui packages/components/src/templates/catalog/ — same shape as the existing overview / wizard / rail tier-4 templates per warp#2435 / warp#2509 / warp#2475."
    },
    {
      "name": "wizard-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/WizardTemplate.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-in-flight",
      "lift_state": "lift-in-flight",
      "tracking_ticket": "warp#2509",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the unit + e2e suites (warp 2509). Phase 1.4 of warp#2280 (warp#3617) extended the slot surface with two optional bands (aside for per-step contextual help / sub-organisms; footer for help links / shortcut hints / draft-saved time) and documented the step-validation contract (consumer derives blockers via $derived; template stays a pure geometric shell) — first consumer of the new bands is /projects/import. /services/new continues to consume the four original bands unchanged. Phase-4 promotion needs the Lit port + Svelte adapter pair in gyrum-labs/gyrum-ui packages/components/src/templates/wizard/ — same shape as the existing overview / rail tier-4 templates per warp#2435 / warp#2475."
    },
    {
      "name": "build-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/BuildDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7449",
      "blocker": "Authored under warp#7449 (absorbed by warp#7749, R4e of the phoenix rebuild epic warp#7742-#7752). Verbatim hoist of the 1,413-line /[buildID] live build viewer (already token-clean: zero hex, zero px font-sizes) so the route composes EXACTLY ONE canon template. Content contract (audit row): live pipeline stages over SSE with Last-Event-ID resume, logs at the failure point, artifacts, and the retro section (retroFlags + retroFindings already integrated in-page — the kill wave 301 from /retro/[buildID] lands here). Route-local panel components (BuildControls / TranscriptPanel / FanoutPanel / RetroHighlights / FailureDiagnostic etc.) stay in the route dir as domain components, imported relatively — they are build-domain, not design primitives (ADR-006 boundary). Path-A in-ticket authoring (warp#3100). Guideline: ai-frontend-page@v1. Page-specific; Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "build-mvp-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/BuildMvpTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7774",
      "blocker": "Authored under warp#7774 (canon: /build de-hex + hoist — the last keeper page deferred from the phoenix rebuild R4 waves, epic warp#7742-#7752). Hoisted verbatim out of `src/routes/build/+page.svelte` (692 lines of page-tier assembly) so the route composes EXACTLY ONE canon template (canon-tier rule, warp#2278 / warp#3100 / ADR-006 / canon-tier-gate.sh); the route thins to load data + render the one template, with the loader payload typed via the Exclude<Awaited<ReturnType<typeof import(.../+page.js).load>>, void> idiom (InfraOverviewTemplate precedent). De-hex in the same diff (warp#7750 board-palette classification — every one of the 17 six-digit hexes was CHROME, no functional hue needed a board-palette entry): greys -> var(--bg-subtle)/var(--text-muted)/var(--text)/var(--bg); button-on-accent #fff -> var(--accent-fg); amber warn-banner + deploy-server chip -> var(--warn)/var(--warn-soft) with the ShipPullsTemplate color-mix soft-border idiom; red error -> var(--bad); indigo org-tag (#e0e7ff/#3730a3) -> var(--info-soft)/var(--info) (warp#6377 retired exactly that indigo); the five .badge.status-* hex pairs retired with the bespoke .badge class — status rides canon GyBadge variants (running->info, complete->success, failed->danger, pending->neutral, interrupted->warning). px font-sizes (13px/12px) -> var(--text-sm)/var(--text-xs); px radii -> var(--radius-sm|md|lg|xl). Region headings ride <gy-section-h> (caption slot carries the See-all link); the recent-builds + recent-deploys lists ride GyListStack with <a> children (never <li> — fixes the prior invalid ul>a>li nesting); the explore tiles ride GyPanel inside plain anchors with the hover affordance re-binding the --border token the panel consumes through the shadow boundary. The bespoke .card/.badge selectors are gone, so /build was DELETED from the .stylelintrc.json color-no-hex/px override list AND the warp#7211 selector ratchet allowlist (genuine shrink), and both route + template joined the hex/px no-drift MIGRATED arrays. Layout, copy, and behaviour otherwise unchanged — same hero, brief form, mode pickers, ?mode= deep-link contract (warp#569). Path-A in-ticket authoring per CLAUDE.md §warp#3100. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "changelog-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ChangelogTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#8413",
      "blocker": "Authored under warp#8413 (operator-facing /changelog). Tier-4 template rendering the committed per-PR changelog entries (.changelog/entries.jsonl, bundled at build time via a Vite ?raw import in $lib/changelog/entries) newest-first. Hoisted out of /changelog/+page.svelte so the route composes EXACTLY ONE canon template (canon-tier rule warp#2278 / warp#3100 / ADR-006); the route is a thin loader + the one template. Composition: GyPageBody frame + GyPageHero band + GyBadge category chips + a token-styled entry list (no bespoke list-row/hero classes — gyrum-validate-route passes). Tokens only — no hex, no px font-size, no px radius (ADR-180). Path-A in-ticket authoring per CLAUDE.md §warp#3100 — page-tier consumer, template authored in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "contract-hub-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ContractHubListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#8479",
      "blocker": "Authored in src/lib/components/canon/ alongside the docs-hub smoke spec (warp#8479, EPIC warp#8468 — the neutral docs/contract hub). Hoisted out of `/docs/contracts/+page.svelte` to satisfy the canon-tier rule \"a route composes exactly ONE canon template and assembles ZERO page-tier canon atoms\" (ai-frontend-page@v1; canon-tier-gate.sh) — the page would otherwise assemble `<GyPanel>` cards in a loop at the page tier (flat-by-construction). Sister-shape to docs-systems-list-template (warp#7250): GyPageHero (page header — owns the h1 + lede) + RouteBreadcrumb + a GyPanel grid (one card per contract-publishing project, two in-card links — OpenAPI contract + changelog — both dashboard-relative /docs/contracts/<slug>; the panel is a non-href <div> container because nested anchors are invalid HTML) + an empty state. Every link is dashboard-relative — the hub is the NEUTRAL operator surface, never a product SaaS subdomain (the whole point of warp#8479: supersede warp#8474 product deep-links). The in-dashboard OpenAPI renderer ContractView.svelte is a route-local docs primitive in src/lib/docs/ (outside the canon-scan tree, like MarkdownView), so it carries no manifest entry. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so template + page refactor + manifest entry land in the same PR. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second consumer (same decision as docs-systems-list-template)."
    },
    {
      "name": "conveyor-v2-demo-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ConveyorV2DemoTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7436",
      "blocker": "Authored under warp#7436 (GyPageBody consumer wave 2e — long-tail pages). Hoisted out of `/dev/conveyor-v2-demo/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page framed the live PipelineConveyorV2 demo inside a bespoke `section.wrap` page-width wrapper + a bare h1 + lede hero + a bespoke `.block` card box at the page tier. Composition: GyPageBody (width=standard; prior --page-max) -> hero band on GyPageHero (h1 + lede) -> body band carrying the live PipelineConveyorV2 inside a GyPanel (the canon card chrome replacing the bespoke .block border/radius/padding box). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. The conveyor-v2-demo-page testid (warp#2661 pages.spec) preserved verbatim on the spine root. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "dashboard-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/DashboardTemplate.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3616",
      "blocker": "Phase 1.3 of the warp#2278 atomic-design substrate EPIC (warp#3616, sibling of warp#3614 CatalogTemplate). Slot-based tier-4 dashboard shell with five primary snippets (hero, chartFeature, leftRail, rightRail, footer) PLUS a calm-first `empty` slot that takes over the body region when chartFeature + both rails are absent. The empty slot is the design pin: calm-first canon (warp ticket two-two-zero-six) makes \"no data\" a first-class quiet state, not a failure. Authored alongside the calm-first fleet dashboard migration at /dev/platform-preview/dashboards/calm-first — the page now composes <DashboardTemplate> + <TimelineOrganism> instead of the previous bespoke <div class=\"dashboard\"> wrapper, satisfying the canon-tier rule (warp#2278 / warp#3098 / canon-tier-gate.sh) \"page imports exactly one tier-4 template\". Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (template) authoring at-tier, so template + organism + consumer refactor + manifest entries land in the same PR. Future consumers include /operate (incident dashboard), /infra (host fleet view), /pm (board summary), /me — every dashboard page that today DIYs the chrome. Phase-4 promotion needs the Lit port + Svelte adapter pair in gyrum-labs/gyrum-ui packages/components/src/templates/dashboard/ — same shape as the CatalogTemplate lift trajectory."
    },
    {
      "name": "detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/DetailTemplate.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3615",
      "blocker": "Phase 1.2 of the warp#2278 atomic-design substrate EPIC (warp#3615, second slice of warp#2280). Sister of CatalogTemplate (warp#3614 / Phase 1.1) — same slot-based authoring discipline applied to the detail-page geometry: hero + KPI strip + two-column body (leftPanel + rightPanel) + meta-footer. Authored alongside /infra/servers/[name] migration — the page composes <DetailTemplate> and fills its five snippet slots; the outer page chrome (max-width + gutters + section gaps + responsive two-col body) lives in DetailTemplate. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so template + first-consumer + manifest entry land in the same PR. Future consumers include worker detail, ticket detail, deploy detail; ProjectDetailTemplate (warp#2739) refactor to compose DetailTemplate is the next consumer migration (sister follow-up ticket — kept separate to keep this PR under the 800-LOC budget and give the visual contract its own focused review). Phase-4 promotion needs the Lit port + Svelte adapter pair in gyrum-labs/gyrum-ui packages/components/src/templates/detail/."
    },
    {
      "name": "docs-systems-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/DocsSystemsListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7250",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the smoke spec (warp#7250 — apply the canon-tier one-template rule to the /docs portal landing page). Hoisted out of `/docs/+page.svelte` to satisfy the canon-tier rule \"a route composes exactly ONE canon template and assembles ZERO page-tier canon atoms\" (ai-frontend-page@v1; warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page assembled `<GyPanel>` atoms directly in a loop at the page tier (flat-by-construction). Composes GyPageHero (page header — owns the h1 + lede, not a bespoke <header>/<h1>) + DocsStatusBanner (freshness molecule) + a GyPanel systems grid (one nav card per fleet system, each a real <a href> into /docs/systems/<slug>) + an empty state + a maintenance aside. Sister-shape to InfraServersListTemplate (warp#7146) — hero over content, the simplest list-template shape with no collection-page primitives (filter chips, active-filter banner, per-row dots): the systems grid is a flat nav board, not a filterable catalog. The data-testids the smoke + docs.spec.ts depend on (systems-grid / system-tile / systems-empty / docs-status-banner) are preserved verbatim. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so template + page refactor + manifest entry land in the same PR. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second consumer materialising (same target_repo decision as infra-servers-list-template / operators-list-template / ship-repos-list-template)."
    },
    {
      "name": "executors-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ExecutorsListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7146",
      "blocker": "Authored under warp#7146 (C3 batch B2 of the on-design-by-construction EPIC warp#7143) — the template-rollout that makes the C1 canon-page-template gate (warp#7144) pass across src/routes/**. The list route /operate/executors was an R1-no-template violator: it hand-assembled GyPageHero + GyListStack + GyStatusCard + GyBadge + GyPageEmptyState directly at the PAGE tier (flat-by-construction). ExecutorsListTemplate lifts that chrome — a titled hero over a GyStatusCard list with a loud tone=bad offline tint, plus the registered/empty zero-state — so the page imports EXACTLY ONE canon template (the canon-tier rule warp#2278 / warp#3100 / ADR-006). The pure online/offline classifier (classifyExecutor) and the BFF fetch stay where they were (executor-health.ts + the page load); the template owns only the hero + list/empty/error chrome and computes the verdict against an injected `now` (stable single clock; deterministic in the unit test). The route smoke-spec selectors (executors-list/executors-empty/executors-error/executor-row-{label}/executor-badge-{label}/executor-lastjob-{label}) are preserved verbatim so the warp#974 / warp#5765 smoke keeps addressing the same hooks across the migration. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + this manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second cross-repo consumer materialising (same target_repo decision as the sibling detail/list templates)."
    },
    {
      "name": "experiment-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ExperimentDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7431",
      "blocker": "Authored under warp#7431 (GyPageBody consumer wave 2b — experiments + compare). Hoisted out of `/experiments/[number]/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the route hand-rolled a wrap/h1/header scaffold + a bespoke `.error` block at the page tier, the scaffold shape predating GyPageBody (warp#7313). Composition: GyPageBody (width=narrow, mirroring the route prior --page-max-narrow) -> hero band on GyPageHero (back-link + the exp-NNN title + the category GyBadge + needs-input note) -> body band carrying the description + steps sections, or the canon GyPageEmptyState on load failure. The warp#7338 cross-axis shrink is fixed by the .spine width:100% seam, the same documented fix the wave-1 templates carry. Tokens only (ADR-180). Path-A in-ticket authoring per CLAUDE.md \"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "experiments-catalogue-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ExperimentsCatalogueTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7431",
      "blocker": "Authored under warp#7431 (GyPageBody consumer wave 2b). Hoisted out of `/experiments/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#3100). The route hand-rolled a wrap/h1/lede scaffold + two quick-link cards on the legacy `.gy-card --interactive` CSS facade + a bespoke `.error` card, all predating GyPageBody (warp#7313). Composition: GyPageBody (width=standard) -> hero band on GyPageHero (the \"Experiment catalogue\" title + lede with the back-to-Experiment-mode link) -> body bands carrying the two quick-link nav cards (now canon GyPanel href cards, replacing the .gy-card facade), then either the load-error empty state on GyPageEmptyState or the category-grouped catalogue on the shared ExperimentsTable (warp#208, kept so its empty-state copy + row shape cannot drift across callers). The warp#7338 cross-axis shrink is fixed by the .spine width:100% seam. Tokens only (ADR-180). tests/e2e/experiments-canon.spec.ts updates the quick-link assertion from the retired .gy-card facade to the canon GyPanel class + href. Path-A in-ticket authoring (warp#3100): consumer-tier authoring at-tier. Guideline: ai-frontend-page@v1. Page-specific; target_repo stays ai-frontend — Phase-4 waits on a second consumer."
    },
    {
      "name": "home-overview-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/HomeOverviewTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3470",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the unit suite (warp#3470). Hoisted out of `/+page.svelte` (the calm-first `/` home dashboard) to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / canon-tier-gate.sh) — the page composed nine canon primitives (OverviewTemplate + GyPageHero + GyButton + GyBadge + GyListRow + KpiStrip + EpicCard + GyBugsSummaryCard + several Lit web-components) inline before, and the warp#3433 rebrand PR (V65) shipped with --skip-canon-tier \"blocked-by:warp#3470\" as the Path B sister-ticket obligation per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\". Sister-shape to projects-list-template (warp#3046) and ticket-new-form-template (warp#3436). Page-specific composition (no cross-repo consumers); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion is not on the roadmap unless a second consumer materialises."
    },
    {
      "name": "incidents-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/IncidentsTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7434",
      "blocker": "Authored under warp#7434 (GyPageBody consumer wave 2d). Hoisted out of `/incidents/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page hand-rolled a `section.wrap` width wrapper + a bespoke `<header>` hero at the page tier. Composition: GyPageBody (width=standard; mirrors the route prior --page-max) -> hero band on GyPageHero (h1 + lede) -> filters band carrying the status + date-range chip toolbar + refresh -> body band carrying the connect-CTA / incident groups / empty / error / loading states -> footer band carrying the loaded-N-groups footnote. All token model (localStorage warp.token), filter $state, the URL-persistence $effect, and the memoised $derived filter chain move into the template verbatim; the route thins to render the one template (the page self-loads client-side, ssr=false). The route .error block hard-coded #fef2f2 / #fecaca / #991b1b maps to the canon --bad-soft / --bad soft pair (same map wave-2a applied), removing the route from the warp#7211 hex/px allowlist (a true shrink). The .chip selector relocates from the route warp#7211 canon-primitive ratchet allowlist line to this template (net-neutral). Tokens only — no hex, no px font-size (ADR-180). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "infra-domains-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/InfraDomainsListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#4145",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the smoke spec (warp#4145 — wave-3 of the canon-treatment sweep, parent warp#4102; apply the collection-page canon to /infra/domains). Hoisted out of `/infra/domains/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page composed a bespoke 6-column HTML table + ~85-line bespoke style block inline before. Composes CatalogTemplate (page chrome) + GyPageHeroRow + GyFilterChipStrip (status chips with counts) + active-filter banner + GyListStack of DomainCard rows + GyPageEmptyState, plus a footer slot preserving the 123 Reg DNS-only legacy note. Sister-shape to InfraReposListTemplate (warp#4101) and FindingsListTemplate (warp#3914) — same collection-page canon (filter chips with counts, single-prop-render, active-filter banner, single left dot per row, inline disambiguating flag, canon-only composition); the row entity is a DNS zone (InfraZone) and the single filter dimension is status (active / other). Rows drill to the in-app entity-detail (/infra/domains/{zone}) via DomainCard. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so template + page refactor + manifest entry land in the same PR. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on the collection-page templates converging into one parameterised list template (same target_repo decision as infra-repos-list-template / ship-repos-list-template)."
    },
    {
      "name": "infra-drift-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/InfraDriftListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#4146",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the smoke spec (warp#4146 — wave-3 of the canon-treatment sweep, warp#4102; apply the collection-page canon to /infra/drift). Hoisted out of `/infra/drift/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page composed a bespoke section.wrap hero + a .summary button-row filter + a bespoke ul.changes list + ~195-line style block + local filter $state inline before. Composes CatalogTemplate (page chrome) + GyPageHeroRow + GyFilterChipStrip (kind chips with counts) + active-filter banner + GyListStack of change rows (single left dot per row + GyBadge field pills) + GyPageEmptyState. Sister-shape to FindingsListTemplate (warp#3914) — the closest collection-page canon match: single-axis filter, dot-per-row list, no sort. The ONE difference vs /infra/findings is the entity + filter axis — drift rows are DriftChange (added / removed / changed deploy-drift between two snapshots) rather than Finding (current-state severity against one snapshot); kind → dot tone maps added → ok, removed → bad, changed → warn. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so template + page refactor + manifest entry land in the same PR. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second deploy-drift collection consumer materialising (same target_repo decision as findings-list-template / infra-repos-list-template)."
    },
    {
      "name": "infra-network-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/InfraNetworkTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7146",
      "blocker": "Authored under warp#7146 (C3 batch B3 of the on-design-by-construction EPIC warp#7143). The trust-surface route /infra/network was an R1-no-template violator: it composed GyPageHero + GyBadge directly at the PAGE tier around a bespoke band layout (flat-by-construction). InfraNetworkTemplate lifts that chrome — a hero (title + lede + exposure legend) over the reachability-stacked band layout (public -> private -> operator, with leak alarms) plus the error state — so the page imports EXACTLY ONE canon template (the canon-tier rule warp#2278 / warp#3100 / ADR-006). This is a specialised data-viz detail surface (same shape as the PmVizDetailTemplate single-viz precedent from warp#7146 B1), so the template renders the hero + band layout directly rather than via the generic list/detail shells. The infra-snapshot fetch + the buildTrustBands(buildExposureNodes(...)) projection stay in the consuming page; the template owns the hero + band rendering and maps each exposure class to its canon GyBadge variant (the leak alarm reserved for danger). The route smoke-spec selectors (exposure-legend/trust-surface/band-{tier}/count-{tier}/error-banner) are preserved verbatim so the warp#974 smoke (infra-network.spec) keeps addressing the same hooks. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + this manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second cross-repo consumer materialising."
    },
    {
      "name": "infra-overview-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/InfraOverviewTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7748",
      "blocker": "Authored under warp#7748 (R4d of the phoenix rebuild, epic warp#7742-#7752). Verbatim hoist of the 444-line /infra overview (already canon-atom rich: gy-hero / gy-section-h / gy-list-row / gy-dot / KpiCardSpark) so the route composes EXACTLY ONE canon template (warp#2278 / warp#3100 / ADR-006). Content contract (audit Infra row): the do-I-need-to-care page — drift count, unreachable hosts, expiring certs, findings — every red row linking its evidence. Path-A in-ticket authoring. Guideline: ai-frontend-page@v1. Page-specific; Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "infra-servers-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/InfraServersListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7146",
      "blocker": "Authored under warp#7146 (C3 batch B3 of the on-design-by-construction EPIC warp#7143). The SRE host-index route /infra/servers was an R1-no-template violator: it composed a GyDataTableOrganism + GyPageHero + GyBadge + GyEmptyState directly at the PAGE tier (flat-by-construction). InfraServersListTemplate lifts that chrome — a titled hero over the canon GyDataTableOrganism (status dot · name · type · DC · services · projects · drift · synced) plus the empty/error states — so the page imports EXACTLY ONE canon template (the canon-tier rule warp#2278 / warp#3100 / ADR-006). The inventory query-API fetch + the calm-on-hiccup error contract stay in the page load; the template owns the hero + table/empty/error chrome and derives the status-dot tone / drift-badge variant against an injected `now` (stable single clock; deterministic in the unit test). The columns work (warp#7134 / warp#6785 #815) is preserved verbatim — TYPE/DC/SERVICES/PROJECTS map the real query-contract type/datacenter/services/project fields, no tier->TYPE / group->DC workaround; the host alias stays in <code> (a true slug per the value rule). The route smoke-spec selectors (hero-subtitle/error-banner/server-table/server-row-{alias}/server-synced-{alias}/empty-state) are preserved verbatim so the warp#974 smoke (infra-servers-index.spec) keeps addressing the same hooks. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + this manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second cross-repo consumer materialising."
    },
    {
      "name": "infra-services-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/InfraServicesListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7766",
      "blocker": "Authored under warp#7766 (the /infra/services GyDataTable + template conversion deferred from R4d warp#7748 — the R4d verbatim hoist was REVERTED in ai-frontend PR #904 because it carried the bespoke 8-column sortable table into a new canon file, the shape the warp#7190 table ratchet exists to refuse). Hoisted out of `/infra/services/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3100); the route thins to load data + render the one template. GyDataTable conversion mirrors the warp#7433 ShipPullsTemplate precedent (ADR-182): the canon atom owns the table chrome + token styling; the rich cells (status dot, DomainLink, repo link + foreign-org GyBadge, server pill, image SHA, age, lag GyBadge, action link) ride the per-column snippet map (warp#6393); the services-table testid is forwarded onto the atom and the verbatim service-row testid rides rowTestid. Sort state stays template-owned via the atom controlled sortBy/sortDir + onsort (5 sortable columns — domain/repo/server/age/lag — with the page established age/lag-start-descending defaults preserved); ServiceDrawer interaction rides the atom row-click contract (warp#7291) with cell links stopPropagation as before. Filter/sort/count rules extracted to $lib/infra/services-list-data.ts with unit tests (the ship-pulls-data shape). Composition: .page layout-glue spine (the accepted R4d sibling InfraOverviewTemplate shape) -> gy-hero -> KPI band (4 KpiCardSpark) -> gy-section-h + filter toolbar + GyDataTable -> drill-row nav. Removes /infra/services/+page.svelte from the warp#7190 border-collapse ratchet (DELETED, not relocated — a genuine shrink), the warp#7211-sibling hex/px override allowlist, and the page-max/motion token vitest gate lists. Tokens only — no hex, no px font-size, no px border-radius (ADR-180). Path-A in-ticket authoring per CLAUDE.md §warp#3100. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "infra-wireguard-wizard-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/InfraWireguardWizardTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7146",
      "blocker": "Authored under warp#7146 (C3 batch B3 of the on-design-by-construction EPIC warp#7143). The WireGuard opt-in confirm + client-config route /infra/servers/install/wireguard was an R1-no-template violator: it composed GyPageHero + GyPanel + GyButton + GySpread directly at the PAGE tier (flat-by-construction). InfraWireguardWizardTemplate lifts that chrome — a hero over the no-server / confirm / config panel states — so the page imports EXACTLY ONE canon template (the canon-tier rule warp#2278 / warp#3100 / ADR-006). This is the form page-type per the ai-frontend-page@v1 map (a guided multi-step confirm flow). The phase state machine (confirm -> loading -> done), the BFF config fetch, the QR derivation, the download action, and the hydration marker all stay in the consuming page; the template owns the hero + the panel states and renders what it is handed. <code> is kept for the server name, the internal tier literal, the gyrum-wg-config command, and the AllowedIPs/endpoint config directives — all true slugs/commands per the value rule. The route smoke-spec selectors (wg-server-name/wg-no-server/wg-confirm-card/wg-effects/wg-dev-note/wg-safety-note/wg-error/wg-cancel/wg-confirm/wg-config-card/wg-stub-banner/wg-qr/wg-download/wg-summary) are preserved verbatim so the warp#974 smoke (wireguard-install.spec) keeps addressing the same hooks. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + this manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second cross-repo consumer materialising."
    },
    {
      "name": "infra-zone-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/InfraZoneDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7429",
      "blocker": "Authored under warp#7429 (GyPageBody consumer wave 2a). Consumer of the GyPageBody spine (warp#7313). Hoisted out of `/infra/domains/[zone]/+page.svelte` per the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3100). Composition: GyPageBody (width=wide — full DNS-record table) -> hero band on GyPageHero (back-to-domains crumb + h1 zone name + lede) -> filters band carrying the name/content search + type select + count -> body band carrying the DNS-record table (record type/proxied chips already on the canon GyBadge) or the loader-error GyEmptyState. The table moves into the template token-only. The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Removes `/infra/domains/[zone]/+page.svelte` from both the warp#7211-sibling hex/px override allowlist and the warp#7190 bespoke-table ratchet allowlist (both only shrink). Path-A in-ticket authoring per warp#3100. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "operate-queue-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/OperateQueueTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7747",
      "blocker": "Authored under warp#7747 (R4c of the phoenix rebuild, epic warp#7742-#7752). Verbatim hoist of the /operate/queue queue-agent console (550 lines, already canon-atom-consuming: gy-hero / gy-badge / gy-section-h / KpiCardSpark / GyPageEmptyState) so the route composes EXACTLY ONE canon template (canon-tier rule, warp#2278 / warp#3100 / ADR-006). Operator-pinned product surface (2026-06-10): CLI changes route through this queue and execute via the queue-agent-runner; executing-runner + queued-by columns land when the daemon exposes them — the action tree, pause/budget/halt controls, and attention notes are the audit surface today. All queue-agent-* testids carried verbatim. Path-A in-ticket authoring per CLAUDE.md (warp#3100). Guideline: ai-frontend-page@v1. Page-specific; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "operate-runners-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/OperateRunnersTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7434",
      "blocker": "Authored under warp#7434 (GyPageBody consumer wave 2d). Hoisted out of `/operate/runners/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page hand-rolled a `section.wrap` width wrapper + a bespoke `header.page-head` at the page tier. Composition: GyPageBody (width=standard; mirrors the route prior --page-max) -> hero band on GyPageHero (section-h title + the \"N in action\" live-count GyBadge + lede) -> KPI band carrying StatusTiles (the \"is the fleet OK?\" 4-tile strip — KEPT in the GyPageBody KPI band because /operate is a MAIN status page and KPI-sparkline tiles stay on main/overview surfaces per the operator standing rule) -> body band carrying the per-host card grid (or empty state), the manifest-error aside, the footnote, the Timeline, the FilterChips row, and RecentJobs. All derived state (activeCount, byHost grouping, lastJobByRunner, the FilterChips state + filteredJobs) moves into the template verbatim; the route thins to load data + render the one template. The page is already canon-token-clean (warp#2106 / warp#2135 redesign) so no hex/px mapping is needed. The data-testid operate-runners-page stays on the spine root (the spec scopes the header lookup under it). Tokens only — no hex, no px font-size (ADR-180). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "operator-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/OperatorDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7434",
      "blocker": "Authored under warp#7434 (GyPageBody consumer wave 2d — pm + operate-family pages). Hoisted out of `/operators/[name]/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the operator-detail page hand-rolled a `section.wrap` width wrapper + a bespoke `<header>` at the page tier. Composition: GyPageBody (width=narrow; mirrors the route prior --page-max-narrow) -> hero band on GyPageHero (← Operators back-link + h1 + category/model/usage meta) -> body band carrying the description / parameters / used-by sections (and the load-error state). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. The used-by `<table>` (border-collapse) relocates from the route warp#7190 ratchet allowlist line to this template (net-neutral). Tokens only — no hex, no px font-size (ADR-180). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "operators-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/OperatorsListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#4141",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the smoke spec (warp#4141 — wave-2 of the canon-treatment sweep; apply the /projects calm-first collection-page canon to /operators). Hoisted out of `/operators/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page composed a hand-rolled <header> + per-category <table> with a ~100-line bespoke style block (table-layout / name-cell / col-model / col-params / num columns) inline before. Composes CatalogTemplate (page chrome) + GyPageHeroRow + GyFilterChipStrip (one chip per category with counts) + active-filter banner + GyListStack of OperatorRow rows + GyPageEmptyState. Sister-shape to InfraReposListTemplate (warp#4101) / ShipReposListTemplate (warp#3915) / ProjectsListTemplate (warp#3823) — same 7-pattern collection-page canon (filter chips with counts, calm-first CTA, single-prop-render V141, active-filter banner with inline clear, single left dot per row, inline disambiguating flags, canon-only composition); the ONE difference is the filter dimension is DATA-DRIVEN — operator categories are not a fixed enum, so the chip strip renders one chip per distinct category present in the loaded list rather than a hardcoded chip set. Rows drill into the in-app entity-detail (/operators/{name}). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so template + page refactor + manifest entry land in the same PR. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on the collection-page templates converging into one parameterised list template (same target_repo decision as infra-repos-list-template / ship-repos-list-template / project-detail-template)."
    },
    {
      "name": "pentest-catalog-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PentestCatalogTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7434",
      "blocker": "Authored under warp#7434 (GyPageBody consumer wave 2d). Hoisted out of `/platform/pentest/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page hand-rolled a `section.wrap` width wrapper + a bespoke `header.hero` at the page tier. /platform/pentest is the operator visual benchmark (calm-first), so the hoist keeps the calm tabular-catalog register intact. Composition: GyPageBody (width=standard; mirrors the route prior --page-max) -> hero band on GyPageHero (h1 + lede + ring-meta + source-pill provenance line) -> body band carrying the canon GyDataTable of homogeneous domain rows (or empty state) -> footer band carrying the pentest-site-fire note. The polled-rows $state + ensurePolling/stopPolling/refresh + onMount/$effect move into the template verbatim; the route thins to load data + render the one template. GyDataTable conversion (warp#7434, operator decision 2026-06-07): the relocated bespoke `<table class=\"gy-table\">` is replaced by the canon GyDataTable atom (ADR-182) with per-column rich-cell snippets (warp#6393) carrying the domain/project links, freshness GyBadge / live scanning-pill, the findings c/h breakdown, and the Fire-scan / View-live CTA; the pentest-domain-table testid moves onto the atom data-testid and pentest-row-<project> rides rowTestid. This removes the template from the warp#7190 border-collapse ratchet (40->38 shrink); the .cta / .scanning-pill selectors keep it on the warp#7211 canon-primitive ratchet. The page is already canon-token-clean. Tokens only — no hex, no px font-size (ADR-180). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "pentest-domain-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PentestDomainTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7434",
      "blocker": "Authored under warp#7434 (GyPageBody consumer wave 2d). Hoisted out of `/platform/pentest/[domain]/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page hand-rolled a `section.wrap` width wrapper + a bespoke `header.hero` at the page tier. Composition: GyPageBody (width=standard; mirrors the route prior --page-max) -> hero band on GyPageHero (breadcrumb + h1 + lede + the Fire-scan / Running… CTA) -> body band carrying the live-running banner, the runs-error note, the page-intro, the findings section (FindingsList or empty/error), and the run-history section (a canon GyDataTable or empty). The polled runningRuns/completedRuns $state + the fireHref/isRunning $derived + ensurePolling/stopPolling/refresh + onMount/$effect move into the template verbatim; the route thins to load data + render the one template. GyDataTable conversion (warp#7434, operator decision 2026-06-07): the two relocated bespoke `<table class=\"gy-table\">` run-history tables (stored-runs + completed-runs fallback) are replaced by the canon GyDataTable atom (ADR-182) with per-column rich-cell snippets (warp#6393) carrying the `<code>`-wrapped run ids / file slugs, the C/H/M/L/I severity breakdown, and the run link; the pentest-stored-runs testid moves onto the atom data-testid and pentest-stored-run-row rides rowTestid. This removes the template from the warp#7190 border-collapse ratchet (40->38 shrink); the .cta selector keeps it on the warp#7211 canon-primitive ratchet. The page is already canon-token-clean. Tokens only — no hex, no px font-size (ADR-180). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "pipeline-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PipelineDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7436",
      "blocker": "Authored under warp#7436 (GyPageBody consumer wave 2e — long-tail pages). Hoisted out of `/pipelines/[name]/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page framed a bespoke header hero (back-link + h1 + step count) + the per-phase step list inside a bespoke `section.wrap` page-width wrapper at the page tier. Composition: GyPageBody (width=standard; prior --page-max) -> hero band on GyPageHero (back-link + h1 + step count) -> body band carrying the per-phase step groups, or the load-error state. Step model/operator/server flags render via the canon GyBadge atom (unchanged). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "pipelines-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PipelinesListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#4140",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the smoke spec (warp#4140 — wave-2 of the canon-treatment sweep; apply the /infra/repos collection-page canon to /pipelines). Hoisted out of `/pipelines/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page rendered a hand-rolled header + a 4-column sortable HTML table + status badges + ~100-line bespoke style block inline before. Composes CatalogTemplate (page chrome) + GyPageHeroRow + GyFilterChipStrip × 2 (Status: declarative/legacy with counts; Phase: DYNAMIC chips derived from the phases the registry currently declares) + active-filter banner + GyListStack of PipelineRow rows + GyPageEmptyState. Sister-shape to InfraReposListTemplate (warp#4101) and ShipReposListTemplate (warp#3915) — same collection-page canon (filter chips with counts, single-prop-render, active-filter banner, single left dot per row, inline disambiguating flag, canon-only composition, NO KPI strip — collection not dashboard); rows drill into the in-app entity-detail (/pipelines/{name}) like /infra/repos. Differences: data is SYNCHRONOUS + already-shaped (PipelineSummary[]) so there is no async snapshot or classifyRepos enrichment, and the Phase strip is dynamic rather than a fixed enum. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so template + row organism + page refactor + manifest entry land in the same PR. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on the collection-page templates converging into one parameterised list template (same target_repo decision as infra-repos-list-template / ship-repos-list-template)."
    },
    {
      "name": "platform-overview-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PlatformOverviewTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7375",
      "blocker": "Authored under warp#7375 (GyPageBody consumer wave 1). First consumer of the GyPageBody band-rhythm spine (warp#7313, @gyrum-labs/svelte@1.8.9) alongside project-import-template. Hoisted out of `/platform/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the bare `/platform` index assembled a bespoke `section.hero` + a `span.dot` separator + `.card`/`.cta-link` route-local CSS at the page tier, the canon-reinvention shapes validate-route flags (hero + dot) and the bespoke selectors the warp#7211 ratchet allowlisted. Composition: GyPageBody (width=standard; owns the page-width frame + band rhythm, replacing the per-section max-width + margin:0 auto + gutter wrappers) -> hero band on GyPageHero -> body band carrying a GyPanel href-card grid (lifecycle via the canon gy-badge variant), the empty state, or the backend-down state. The warp#7338 cross-axis shrink (platform filled 67% of the .content flex column) is fixed by the spine wrapper width:100% seam, the same documented fix CatalogTemplate carries. Removes `/platform/+page.svelte` from the warp#7211 canon-primitive ratchet allowlist (the list only shrinks). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second consumer materialising. Blocked-by warp#7377 (@gyrum-labs/styles unpublished + raw-.ts export) until the GyPageBody-carrying svelte release installs + typechecks clean."
    },
    {
      "name": "platform-project-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PlatformProjectDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3996",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the smoke spec (warp#3996, Child A of warp#3993 entity-detail EPIC). Hoisted out of `/platform/[project]/+page.svelte` — the operator-surfaced /platform/warp audit reference; previous shape was 759 LOC of bespoke `.hero`/`.kpi-row`/`.panels` chrome plus a local `KpiCardSpark` molecule rendering identity (SHA) as a KPI tile. The template applies all 7 entity-detail patterns from `dark-factory:/tmp/entity-detail-pattern-proposal.md`: (1) GyPageHero + GyPageHeroRow carrying eyebrow + h1 (entity name ONCE) + state-line lede with inline lifecycle dot + secondary Deploy CTA; (2) ONE GyKpiStrip with four `<gy-kpi-card href>` tiles — last deploy / live / outages / open PRs — every tile a metric, identity (SHA) lifted to the hero lede; (3) single-prop-render — entity name in the hero h1 only; (4) Activity + linked-tickets panels wrapped in `<gy-panel>` inside a `<gy-grid min=\"20rem\">` 2-col composition; (5) NO collection-page primitives (filter chips, active-filter banner, per-row dots) — lifecycle is on the entity in the hero, not per-row; (6) NO duplicate breadcrumb — the global app shell owns the trail (warp#931 / warp#3991); (7) canon composition only — Wave A atoms (gy-stack, gy-grid) + Wave D molecules (gy-kpi-card, gy-panel) + Wave F (gy-kpi-strip, gy-page-hero-row). Reference implementation for the entity-detail EPIC family (/projects/[slug] warp#3999, /tickets/[id] warp#4000, /playbooks/[id] warp#4001) — they consume this template directly via the same Path-A in-ticket authoring shape once their tickets dispatch. Sister-shape to project-detail-template (warp#2739, /projects/[slug] sibling) and the dashboard pattern reference impl on /me (warp#3912). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Page-specific composition; target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second consumer (likely /platform/[project]/deploys after warp#3998 ships)."
    },
    {
      "name": "playbook-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PlaybookDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#4001",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the unit suite + e2e smoke spec (warp#4001, Child D of warp#3993 entity-detail EPIC; largest at 1769 LOC). Hoisted the identity + KPI + structural shell out of `/playbooks/[id]/+page.svelte` to apply the entity-detail canon-treatment, mirroring the reference impl PlatformProjectDetailTemplate (warp#3996, Child A). Applies the entity-detail patterns: (1) GyPageHero + GyPageHeroRow carrying eyebrow (PLAYBOOK · kind) + h1 (playbook title ONCE) + state-line lede with inline lifecycle dot + id/owner/status-chip identity + right-aligned Run CTA slotted by the page (confirm/pause lifecycle stays in the consumer — Run fires a playbook, a money/destructive action); (2) ONE GyKpiStrip with four `<gy-kpi-card>` metric tiles — runs count / success rate / last duration / steps count — every tile a metric, identity (id/kind/owner/status) lifted to the hero; (3) single-prop-render — playbook title in the hero h1 only (V141 gate); (4) Recent fires + Steps panels wrapped in `<gy-panel>` inside a `<gy-grid min=\"20rem\">` 2-col composition, each panel body a consumer snippet so the stateful list components (RunsList, steps list) stay in the page tier; (5) NO collection-page primitives (filter chips, active-filter banner, per-row dots). The page's stateful behaviour (run lifecycle, live/historical run views, inputs form, drift probe, YAML pane, disclosure cards) remains in the consumer and is passed via snippets. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. The remaining disclosure-section cleanup (folding Guide/Inputs/YAML/Raw-response into the entity-detail rhythm) is tracked as the Phase B follow-up warp#4086. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second consumer. Sister-shape to platform-project-detail-template (warp#3996), project-detail-template (warp#2739), and home-overview-template (warp#3470)."
    },
    {
      "name": "playbook-health-history-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PlaybookHealthHistoryTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7433",
      "blocker": "Authored under warp#7433 (GyPageBody consumer wave 2c). Hoisted out of `/playbooks/[id]/health-history/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3100). Composition: GyPageBody (width=standard) -> hero band on GyPageHero (breadcrumbs + h1 Health history · id + per-tone counter) -> body band carrying the loading / error states, then the filter card, the timeline card, and the recent-runs card, plus the run-details side panel. The three section containers are the canon GyPanel variant=elevated (was a bespoke .card class — replaced). The status / range filter buttons are page-specific toggle chips (.chip) with no canon filter-chip primitive yet — they move verbatim from the route (warp#7211 ratchet allowlist follows the file; relocation, not growth). The timeline, runs table, and side panel stay their existing child components; the page-runs API mocks in the e2e spec key on the URL so they survive the hoist. The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Tokens only — no hex, no px font-size (ADR-180). Path-A in-ticket authoring per CLAUDE.md §warp#3100. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "playbooks-catalog-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PlaybooksCatalogTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7433",
      "blocker": "Authored under warp#7433 (GyPageBody consumer wave 2c). Hoisted out of `/playbooks/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3100). Composition: GyPageBody (width=wide; the multi-section catalogue earns the wider frame, mirroring the route prior 1080→1480 --page-max breakpoint) -> hero band on GyPageHero (h1 + count badge + keyboard hint + lede) -> filters band carrying the search / persona / status / sort controls + tag chips -> body band carrying the loading / backend-down / filtered-empty states or the favourites + per-kind card sections. The backend-down + no-playbooks states are the canon GyPageEmptyState. The persona/status filter buttons are page-specific toggle chips (.chip) with no canon filter-chip primitive yet — they move verbatim from the route into this template (warp#7211 ratchet allowlist follows the file; relocation, not growth). The catalogue fetches in onMount (SSR cannot reach the ai-research backend). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Tokens only — no hex, no px font-size (ADR-180). Path-A in-ticket authoring per CLAUDE.md §warp#3100. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "pm-board-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PmBoardTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#8675",
      "blocker": "Authored under warp#8675 (the IA rebuild's last off-canon keeper page). Hoisted VERBATIM out of `/pm/+page.svelte` (700+ lines of page-tier board assembly) to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page hand-rolled a `section.wrap` width wrapper holding a GyPageHero hero + the whole dashboard at the page tier. Composition: GyPageBody (width=wide; mirrors the route prior --page-max-wide measure) -> breadcrumb band on RouteBreadcrumb -> hero band on GyPageHero (eyebrow + inbox-icon h1 + the live one-line summary + the Refresh action) -> default body band carrying the PmLifecycle / PmFlowTimeline / PmPortfolioLanes panels, the connect-CTA / empty-with-token nudge, the GyKpiStrip KPI band, the PmInFlight centerpiece, the PmSection attention/state grid, the by-repo GyListStack rollup, and the PmFilters Browse-the-full-queue disclosure; the EpicRequirementsDrawer renders after GyPageBody as an overlay. The whole board script — the token model, the filter $state, the kind-filter persistence $effect, every memoised $derived, and the epic write affordances (decompose / patch-requirements) — moves into the template verbatim; the route thins to set the title + render the one template, with the loader (`+page.ts`) unchanged so its payload threads straight in. The reused $lib/pm/* children (EpicCard, EpicRequirementsDrawer, grouping.ts, campaign.ts, PmInFlight, PmFilters, PmLifecycle, PmFlowTimeline, PmSection, PmPortfolioLanes, pm-sections.ts) are unchanged. The board-palette.css import relocates with the board markup into the template (net-neutral). Every data-testid the pm-campaigns.spec.ts regression net depends on is preserved verbatim; pm-spine rides the spine root. The page was already canon-token-clean (the home-overview calm-first register) so no hex/px mapping is needed. Tokens only — no hex, no px font-size (ADR-180). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "pm-viz-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/PmVizDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7146",
      "blocker": "Authored under warp#7146 (C3 of the on-design-by-construction EPIC warp#7143) — the template-rollout that makes the C1 canon-page-template gate (warp#7144) pass across src/routes/**. The two PM-SaaS single-viz routes /pm/[slug]/heatmap and /pm/[slug]/cluster/[number] were R1-no-template violators: each hand-assembled a bespoke <header> + <section> at the PAGE tier with no canon template (flat-by-construction). PmVizDetailTemplate lifts the shared chrome — a titled hero over a single full-width visualisation with a fail-soft loading/inline-error state machine — so each page imports EXACTLY ONE canon template (the canon-tier rule warp#2278 / warp#3100 / ADR-006). It composes the generic DetailTemplate (hero + single body panel via TwoColPanelsOrganism), so the page-width + section-gap geometry is owned by the canon shell; this template adds only the hero (title + optional subtitle + optional in-hero back-link) and the loading|ready|error state the two routes share. The domain visualisations (HeatmapGrid / ClusterGraph) are domain components, not design primitives, so they stay in $lib/components/ and render via the `viz` snippet only in the ready state. Per-consumer loadingTestId / errorTestId preserve each route's warp#974 smoke-spec selectors (heatmap-loading/heatmap-error, cluster-loading/cluster-error) across the migration. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + both page refactors + this manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second cross-repo consumer materialising (same target_repo decision as the sibling detail templates)."
    },
    {
      "name": "project-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ProjectDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3999",
      "blocker": "Re-treated to the entity-detail canon pattern (warp#3999, Child B of the warp#3993 entity-detail EPIC) — mirrors the two merged reference routes platform-project-detail-template (warp#3996, /platform/[project], v8.1.0) and ticket-detail-template (warp#4000, /tickets/[id], v8.1.3). Applies all 7 entity-detail patterns from `dark-factory:/tmp/entity-detail-pattern-proposal.md`: (1) GyPageHero + GyPageHeroRow carrying eyebrow `PROJECT` + h1 (project.name ONCE) + state-line lede with inline gy-dot-glyph lifecycle dot + identity (slug · lifecycle · class · service-count) + secondary \"View prod\" CTA when runtime.prod_url is set; (2) ONE GyKpiStrip with four metric tiles — services / repos / consumes / consumed-by counts — identity (slug, lifecycle, class) lifted to the hero lede, never a KPI tile; (3) single-prop-render — project.name in the hero h1 only; (4) Services-&-Repos + Dependencies panels wrapped in `<gy-panel>` inside a `<gy-grid min=\"20rem\">` 2-col composition — services/repos rows + consumes/consumed-by/resources rows; (5) NO collection-page primitives (filter chips, active-filter banner, per-row dots) — the retired hero badge-facts strip is replaced by the lede sentence; (6) NO duplicate breadcrumb — the global app shell owns the trail, the old back-to-projects crumb removed; (7) canon composition only — Wave A atoms (gy-stack, gy-grid) + Wave D molecules (gy-kpi-card, gy-panel, gy-dot-glyph) + Wave F (gy-kpi-strip, gy-page-hero-row). Data layer (`+page.ts` registry fetch + find-by-slug) UNTOUCHED — shape-only refactor; data contract IDENTICAL. The prior shape (warp#2739) composed GyPageHero + KpiCard strip + gy-badge + gy-list-row + bespoke breadcrumb / edges / meta-footer chrome. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template re-treatment + page delegation + manifest entry land in the same PR. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second consumer materialising (same target_repo decision as platform-project-detail-template / ticket-detail-template)."
    },
    {
      "name": "project-import-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ProjectImportTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7375",
      "blocker": "Authored under warp#7375 (GyPageBody consumer wave 1). Second consumer of the GyPageBody band-rhythm spine (warp#7313, @gyrum-labs/svelte@1.8.9) alongside platform-overview-template. Hoisted out of `/projects/import/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page framed the canon WizardTemplate inside a bespoke `div.page` width wrapper + a bespoke `pagehead-row` hero at the page tier, the canon-reinvention hero shape validate-route flags. Composition: GyPageBody (width=wide; mirrors the route prior --page-max-wide) -> hero band on GyPageHero (title + back-to-index link + lede; the WizardTemplate own hero band is left unused) -> body band carrying the WizardTemplate with its stepIndicator / stepBody / aside / footerActions / footer bands. All wizard state + the step-validation $derived contract + the DrilldownsOrganism source-picker + the cancel-confirm overlay move into the template verbatim; the route thins to load data + render the one template. The warp#7338 cross-axis shrink (import filled 57% of the .content flex column) is fixed by the spine wrapper width:100% seam. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second consumer materialising. Blocked-by warp#7377 (@gyrum-labs/styles unpublished + raw-.ts export) until the GyPageBody-carrying svelte release installs + typechecks clean."
    },
    {
      "name": "projects-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ProjectsListTemplate.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3046",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the unit suite (warp#3046). Hoisted out of `/projects/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / canon-tier-gate.sh) — the page composed atoms + molecules + organisms inline before. Phase-4 promotion needs the Lit port + Svelte adapter pair in gyrum-labs/gyrum-ui packages/components/src/templates/projects-list/ — same shape as the existing wizard / overview / rail tier-4 templates per warp#2435 / warp#2475 / warp#2509."
    },
    {
      "name": "retro-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/RetroTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7436",
      "blocker": "Authored under warp#7436 (GyPageBody consumer wave 2e — long-tail pages). Hoisted out of `/retro/[buildID]/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page framed a bespoke sticky `header.page-head` hero + findings sections inside a bespoke `section.wrap` page-width wrapper at the page tier. Composition: GyPageBody (width=narrow; the page is text-heavy, prior content measure 68ch) -> hero band on GyPageHero (back-link + h1 + section/finding summary) -> body band carrying the loading / error / empty states or the findings sections list. The sticky-header positioning the bespoke .page-head carried is intentionally dropped — a scaffold layout nicety; the calm-first GyPageBody band rhythm (warp#7313) is a quiet vertical spine with no sticky chrome. The template owns the client-side markdown fetch (self-contained live reader; the route thins to passing buildID). The bespoke .count-badge selector was renamed to .count-flag (off the banned .badge pattern). data-retro-section preserved verbatim per the parseRetro contract. The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "run-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/RunDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7146",
      "blocker": "Authored under warp#7146 (C3 batch B2 of the on-design-by-construction EPIC warp#7143). The single-run entity-detail route /operate/runs/[runId] was an R1-no-template violator: it hand-assembled GyPageHero + GyBadge + GySpread + GyPanel at the PAGE tier (flat-by-construction). RunDetailTemplate lifts that chrome — a hero (short run id + status badge with a live indicator) over a full-width terminal panel, plus the not-found state — so the page imports EXACTLY ONE canon template (the canon-tier rule warp#2278 / warp#3100 / ADR-006). This is the entity-detail shape (one run record) per the ai-frontend-page@v1 map, modelled on the ServerDetailTemplate (warp#7140) exemplar: a hero band over a single full-width body, NOT the two-column generic DetailTemplate (the run terminal is one surface with no sidebar). The SSE event-stream lifecycle (open / teardown / status), the live/terminal status derivation, and the route param stay in the consuming page (an EventSource stream is inherently a browser-side concern and SSR nodes may not reach the executor at :9400); the page hands the template the resolved events + headerStatus + isLive + notFound. The route smoke-spec selectors (run-detail-status/run-detail-not-found/run-detail-terminal/run-detail-tailing) are preserved verbatim so the warp#974 / warp#4117 smoke keeps addressing the same hooks. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + this manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second cross-repo consumer materialising."
    },
    {
      "name": "runs-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/RunsListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7146",
      "blocker": "Authored under warp#7146 (C3 batch B2 of the on-design-by-construction EPIC warp#7143). The cross-playbook run-viewer list route /operate/runs was an R1-no-template violator: it hand-assembled GyPageHero + GyPanel rows + GyBadge + GyStack at the PAGE tier (flat-by-construction). RunsListTemplate lifts that chrome — a titled hero over a run-row stack with loading / error-with-retry / empty / list states — so the page imports EXACTLY ONE canon template (the canon-tier rule warp#2278 / warp#3100 / ADR-006). The run list is fetched client-side from the consuming page's onMount (SSR nodes may not reach the ai-research executor at :9400), so the page owns the data lifecycle and hands the template the resolved runs + loaded + error + an onRetry callback; the template's job ends at \"render the right loading/error/empty/list state\". The route smoke-spec selectors (runs-loading/runs-error/runs-retry/runs-empty/operate-runs-list/run-row-{runId}) are preserved verbatim so the warp#974 / warp#4117 smoke keeps addressing the same hooks. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + this manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second cross-repo consumer materialising."
    },
    {
      "name": "server-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ServerDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7140",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the unit suite + e2e smoke spec (warp#7140) — the host-detail page `/infra/servers/[name]` was the canon-tier OUTLIER: every other entity-detail page imports exactly ONE dedicated template (project-detail-template warp#3999, platform-project-detail-template warp#3996, ticket-detail-template warp#4000, playbook-detail-template warp#4001) but the host instead assembled canon primitives directly at the page tier inside the generic DetailTemplate, used raw h2 headers, and carried a pixel-literal page-level style block. Hoisted into ServerDetailTemplate to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3100 / canon-tier-gate.sh). Applies the entity-detail canon patterns: (1) GyPageHero + GyPageHeroRow carrying eyebrow `HOST` + h1 (server.alias ONCE) + identity lede (identifier · synced rel) + right-aligned drift/in-sync GyBadge; (2) ONE GyKpiStrip with three gy-kpi-card tiles — Status / Synced / Drift — with semantic tone (active/running reads ok-green, unknown reads warn); (3) single-prop-render — server.alias in the hero h1 only; (4) Identity + Exposure-&-access + Containers + Drift + Provenance carded Panel(variant=elevated) sections, the paired ones in a 2-col Grid; (5) NO collection-page primitives (filter chips, active-filter banner, per-row dots); (6) NO duplicate breadcrumb beyond the single ← Infrastructure crumb; (7) canon composition only — GyPageHero/GyPageHeroRow, GyKpiStrip, GySectionH, GyPanel, GyStack, GyGrid, GyBadge, GyDataTableOrganism + gy-kpi-card/gy-list-row/section-h custom elements. Identity + provenance view-models derived in the pure host-detail-view helper (own unit suite); surface/container/drift view-models passed as props from the loader snapshot. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second consumer materialising (same target_repo decision as project-detail-template / platform-project-detail-template / ticket-detail-template)."
    },
    {
      "name": "ship-ci-status-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ShipCiStatusTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7433",
      "blocker": "Authored under warp#7433 (GyPageBody consumer wave 2c — ship + playbooks families). Hoisted out of `/ship/ci/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page hand-rolled a `section.wrap` page-width wrapper + a bespoke `header > h1 + .lede` hero at the page tier, the per-section `max-width + margin:0 auto + gutter` idiom GyPageBody replaces. Composition: GyPageBody (width=standard) -> hero band on GyPageHero -> body band carrying the pending-backend note, the error state, the canon GyPageEmptyState (testId ship-ci-empty), or the repo-rows grid. The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam (same documented fix as platform-overview-template). Tokens only — no hex, no px font-size (ADR-180); the repo rows are a plain token-only `<a>` list (no bespoke .cta/.card/.badge selector). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "ship-deploys-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ShipDeploysTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7433",
      "blocker": "Authored under warp#7433 (GyPageBody consumer wave 2c). Hoisted out of `/ship/deploys/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3100). Composition: GyPageBody (width=standard) -> hero band on GyPageHero -> body band carrying the stop-gap note, the error state, the canon GyPageEmptyState (testId ship-deploys-empty), or the day-grouped deploy timeline. The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Tokens only — no hex, no px font-size (ADR-180); the timeline is a plain token-only `<ol>` (no bespoke primitive selector). Path-A in-ticket authoring per CLAUDE.md §warp#3100 — consumer-tier authoring at-tier, so template + page refactor + manifest land together. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "ship-libraries-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ShipLibrariesTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7433",
      "blocker": "Authored under warp#7433 (GyPageBody consumer wave 2c). Hoisted out of `/ship/libraries/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3100). Composition: GyPageBody (width=wide; the matrix table earns the wider frame, mirroring the route prior --page-max-wide) -> hero band on GyPageHero -> body band carrying the error/info states, the version matrix (testId ship-libs-matrix), and the collapsible all-dependencies table. The multi-version warning is the canon GyBadge (already so in the route). The matrix + all-deps tables are the canon GyDataTable atom (warp#7433 GyDataTable-conversion decision 2026-06-07; ADR-182). The matrix is a cross-tab whose repo columns are built dynamically and whose per-cell outdated upgrade-candidate signal rides the rich-cell snippet map (warp#6393) as an in-cell accent marker (GyDataTable owns no per-cell class hook); ship-libs-matrix wraps the atom so the smoke selector survives. This drops the bespoke <table>s + border-collapse style, so the template was removed from the warp#7190 border-collapse ratchet allowlist (a genuine shrink). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Tokens only — no hex, no px font-size (ADR-180). Path-A in-ticket authoring per CLAUDE.md §warp#3100. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "ship-overview-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ShipOverviewTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7746",
      "blocker": "Authored under warp#7746 (R4b of the phoenix rebuild, epic warp#7742-#7752). Hoisted out of src/routes/ship/+page.svelte (444 lines of page-tier assembly) so the route composes EXACTLY ONE canon template (canon-tier rule, warp#2278 / warp#3100 / ADR-006). Content-contract upgrades (docs/design/ia-route-audit.md Ship row): the hero answers \"are we shipping?\" from live derivations; a needs-attention strip of degraded services leads the body (Action before state); KPI band, fleet grid, and the best-effort recent-deploys feed follow (the dedicated GitHub-proxy deploy feed upgrades the feed when it lands). Counts + deploys feed stay client-side so SSR is cheap and e2e intercepts via page.route. All ship-* testids carried verbatim. Path-A in-ticket authoring per CLAUDE.md (warp#3100). Guideline: ai-frontend-page@v1. Page-specific; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "ship-pulls-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ShipPullsTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7433",
      "blocker": "Authored under warp#7433 (GyPageBody consumer wave 2c). Hoisted out of `/ship/pulls/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3100). Composition: GyPageBody (width=wide; the data table earns the wider frame, mirroring the route prior --page-max-wide) -> hero band on GyPageHero -> body band carrying the backend-pending affordance (testId ship-pulls-pending), the error/empty states, or the PRs table. The per-row status indicator is the canon GyBadge (was a bespoke .pill class — replaced, not relocated); the .ci chip stays a token-only span outside the canon-primitive ratchet selector set. The PRs table is the canon GyDataTable atom (warp#7433 GyDataTable-conversion decision 2026-06-07; ADR-182): the atom owns the table chrome, the repo/PR-link/CI-chip/status-GyBadge cells ride the rich-cell snippet map (warp#6393), and the ship-pulls-table testid is forwarded onto its <table>. This drops the bespoke <table> + border-collapse style, so the template was removed from the warp#7190 border-collapse ratchet allowlist (a genuine shrink). The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Tokens only — no hex, no px font-size (ADR-180). Path-A in-ticket authoring per CLAUDE.md §warp#3100. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer."
    },
    {
      "name": "ship-repos-list-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/ShipReposListTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3915",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the smoke spec (warp#3915 — apply /projects calm-first canon to /ship/repos). Hoisted out of `/ship/repos/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / canon-tier-gate.sh) — the page composed GyPageHero + hand-rolled chip strip + table + filter $state inline before. Composes CatalogTemplate (page chrome) + GyPageHeroRow + GyFilterChipStrip × 2 (relevance + visibility chips with counts) + active-filter banner + GyListStack of RepoCard rows. Sister-shape to ProjectsListTemplate (warp#3046 / warp#3823) — same 7-pattern canon (filter chips with counts, calm-first CTA, single-prop-render, active-filter banner, single left dot per row, inline disambiguating flags, canon-only composition) but the row entity is a repo (source artefact) rather than a project (deploy stack). Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so template + page refactor + manifest entry land in the same PR. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second consumer materialising (same target_repo decision as home-overview-template / project-detail-template)."
    },
    {
      "name": "sitemap-nav-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/SitemapNavTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#8413",
      "blocker": "Authored under warp#8413 (operator-facing /sitemap). Tier-4 template rendering the SHELL_NAV / SHELL_REFERENCE IA tree (the same model the live-shell rail consumes) so it never drifts from the menu — distinct from the hand-curated SRE route map at /dev/sitemap (SitemapTemplate). Hoisted out of /sitemap/+page.svelte so the route composes EXACTLY ONE canon template (canon-tier rule warp#2278 / warp#3100 / ADR-006); the route thins to <svelte:head> + the one template. Composition: GyPageBody frame + GyPageHero band + a token-styled grouped link tree (no bespoke list-row/hero classes — gyrum-validate-route passes). Tokens only — no hex, no px font-size, no px radius (ADR-180). Path-A in-ticket authoring per CLAUDE.md §warp#3100 — page-tier consumer, template authored in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition; target_repo stays ai-frontend — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "sitemap-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/SitemapTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#7436",
      "blocker": "Authored under warp#7436 (GyPageBody consumer wave 2e — long-tail pages). Hoisted out of `/sitemap/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / warp#3098 / warp#3100 / canon-tier-gate.sh) — the page framed its hero + grouped-route list inside a bespoke `section.wrap` page-width wrapper at the page tier (the same max-width + margin:0 auto + gutter idiom the GyPageBody spine owns). Composition: GyPageBody (width=narrow; the page is text-heavy, a column of grouped links reads better at the narrow measure) -> hero band on GyPageHero (testId sitemap-hero preserved verbatim; the warp#855/#2397 sitemap-and-404 spec scopes the h1 into gy-page-hero[test-id=sitemap-hero]) -> body band carrying the per-mode route groups. The warp#7338 cross-axis shrink is fixed by the spine wrapper width:100% seam. Testids sitemap-page / sitemap-group-* / data-sitemap-route preserved verbatim. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Guideline: ai-frontend-page@v1. Page-specific composition (no current cross-repo consumer); target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion waits on a second consumer materialising."
    },
    {
      "name": "ticket-detail-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/TicketDetailTemplate.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#4000",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the smoke spec (warp#4000, Child C of warp#3993 entity-detail EPIC). Hoisted out of `/tickets/[id]/+page.svelte` — previous shape was 322 LOC of bespoke `<h1>` + two `<h2 class=\"h-minor\">` (Attachments / Tags) sub-section headers + inline 2-col flex. Mirrors the reference implementation platform-project-detail-template (warp#3996, Child A); applies all 7 entity-detail patterns from `dark-factory:/tmp/entity-detail-pattern-proposal.md`: (1) GyPageHero + GyPageHeroRow carrying eyebrow `TICKET` + h1 (item.title ONCE) + state-line lede with inline gy-dot-glyph lifecycle dot + identity (#number · repo · priority · kind) + secondary \"Open in Warp\" CTA; (2) ONE GyKpiStrip with three `<gy-kpi-card>` metric tiles — attachments / tags / days-open — identity (warp#, status) lifted to the hero lede, never a KPI tile (Comments / Linked-PRs dropped — no wire field on the warp item GET today; follow-up adds them when the counts ship); (3) single-prop-render — item.title in the hero h1 only; (4) Description + Related panels wrapped in `<gy-panel>` inside a `<gy-grid min=\"20rem\">` 2-col composition — the retired `<h2 class=\"h-minor\">` Attachments / Tags sections become gy-list-row rows + a badge-cluster inside the Related panel; (5) NO collection-page primitives (filter chips, active-filter banner, per-row dots); (6) NO duplicate breadcrumb — the global app shell owns the trail; (7) canon composition only — Wave A atoms (gy-stack, gy-grid) + Wave D molecules (gy-kpi-card, gy-panel, gy-dot-glyph) + Wave F (gy-kpi-strip, gy-page-hero-row). Data layer (`+page.server.ts` + `ticket-fetch.ts`) UNTOUCHED — shape-only refactor; the template imports WarpItemDetail + the attachment helpers from the route module unchanged. Path-A in-ticket authoring per CLAUDE.md §\"Authoring new canon — in-ticket vs sister ticket (warp#3100)\" — consumer-tier (page) authoring at-tier (template), so the template + page refactor + manifest entry land in the same PR. Page-specific composition; target_repo stays ai-frontend rather than gyrum-ui — Phase-4 promotion to @gyrum-labs/components/templates/ waits on a second consumer materialising."
    },
    {
      "name": "ticket-new-form-template",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/canon/TicketNewFormTemplate.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "lift-pending",
      "lift_state": "lift-pending",
      "tracking_ticket": "warp#3436",
      "blocker": "Phase-2 extraction landed in src/lib/components/canon/ alongside the unit suite (warp#3436). Hoisted out of `/tickets/new/+page.svelte` to satisfy the canon-tier rule \"page imports exactly one template\" (warp#2278 / canon-tier-gate.sh warp#2399 Phase 4b + warp#3098 page-tier enforcement) — the page composed five canon atoms (GyPageHero + GyForm + GyFormField + GySelect + GyButton) inline before. Phase-4 promotion needs the Lit port + Svelte adapter pair in gyrum-labs/gyrum-ui packages/components/src/templates/ticket-new-form/ — same shape as the wizard / projects-list / overview / rail tier-4 templates per warp#2435 / warp#2475 / warp#2509 / warp#3046. Page-specific to /tickets/new in ai-frontend; promotion is lower priority than wizard / projects-list (those have or will have cross-repo consumers)."
    },
    {
      "name": "side-rail",
      "tier": "template",
      "tag": null,
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/components/SideRail.svelte",
      "target_repo": "gyrum-labs/ai-frontend",
      "status": "keep-local",
      "lift_state": "keep-local",
      "tracking_ticket": null,
      "blocker": "Reads SvelteKit's $page store for active-route highlighting. Lifting would require passing the current path as a prop on every render, which is fine but loses the auto-resolution that's the SideRail's whole point. Re-evaluate post-warp#2281."
    },
    {
      "name": "overview",
      "tier": "template",
      "tag": "gy-overview",
      "owner_repo": "gyrum-labs/ai-frontend",
      "path": "src/lib/templates/OverviewTemplate.svelte",
      "target_repo": "gyrum-labs/gyrum-ui",
      "status": "retired",
      "lift_state": "retired",
      "tracking_ticket": "warp#2439",
      "blocker": null
    },
    {
      "name": "page",
      "tier": "page",
      "tag": "gy-page",
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/components/src/pages/page/page.ts",
      "dist": "packages/components/dist/pages/page/page.js",
      "package": "@gyrum-labs/components/page/page.js",
      "svelte_adapter": "@gyrum-labs/svelte/GyPage.svelte",
      "status": "registered-and-built",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "home-page",
      "tier": "page",
      "tag": null,
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/pages/home-page/GyHomePage.svelte",
      "dist": "packages/svelte/src/pages/home-page/GyHomePage.svelte",
      "package": "@gyrum-labs/svelte/pages/home-page/GyHomePage.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/pages/home-page/GyHomePage.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "project-overview-page",
      "tier": "page",
      "tag": null,
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/pages/project-overview-page/GyProjectOverviewPage.svelte",
      "dist": "packages/svelte/src/pages/project-overview-page/GyProjectOverviewPage.svelte",
      "package": "@gyrum-labs/svelte/pages/project-overview-page/GyProjectOverviewPage.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/pages/project-overview-page/GyProjectOverviewPage.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "services-list-page",
      "tier": "page",
      "tag": null,
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/pages/services-list-page/GyServicesListPage.svelte",
      "dist": "packages/svelte/src/pages/services-list-page/GyServicesListPage.svelte",
      "package": "@gyrum-labs/svelte/pages/services-list-page/GyServicesListPage.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/pages/services-list-page/GyServicesListPage.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    },
    {
      "name": "services-new-page",
      "tier": "page",
      "tag": null,
      "owner_repo": "gyrum-labs/gyrum-ui",
      "path": "packages/svelte/src/pages/services-new-page/GyServicesNewPage.svelte",
      "dist": "packages/svelte/src/pages/services-new-page/GyServicesNewPage.svelte",
      "package": "@gyrum-labs/svelte/pages/services-new-page/GyServicesNewPage.svelte",
      "svelte_adapter": "@gyrum-labs/svelte/pages/services-new-page/GyServicesNewPage.svelte",
      "status": "registered-missing-dist",
      "lift_state": null,
      "tracking_ticket": null,
      "blocker": null
    }
  ]
}
