create-principles-disciple 1.118.0 → 1.119.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/console/dist/server/index.js +17 -1
  2. package/console/dist/server/models/ActivationsConsoleModel.d.ts +77 -0
  3. package/console/dist/server/models/ActivationsConsoleModel.js +322 -4
  4. package/console/dist/server/models/ReceiptsConsoleModel.d.ts +42 -0
  5. package/console/dist/server/models/ReceiptsConsoleModel.js +160 -0
  6. package/console/dist/server/routes/activations.d.ts +6 -1
  7. package/console/dist/server/routes/activations.js +142 -1
  8. package/console/dist/server/routes/receipts.d.ts +8 -0
  9. package/console/dist/server/routes/receipts.js +63 -0
  10. package/console/dist/ui/App.js +6 -3
  11. package/console/dist/ui/api.d.ts +40 -3
  12. package/console/dist/ui/api.js +94 -3
  13. package/console/dist/ui/i18n/en.json +75 -0
  14. package/console/dist/ui/i18n/zh-CN.json +75 -0
  15. package/console/dist/ui/pages/activation/ActivationPage.js +114 -5
  16. package/console/dist/ui/pages/activation/ActivationValidators.js +3 -0
  17. package/console/dist/ui/pages/focus/FocusPage.js +16 -3
  18. package/console/dist/ui/pages/principles/PrincipleDetailPage.js +17 -3
  19. package/console/dist/ui/utils/validators.d.ts +100 -0
  20. package/console/dist/ui/utils/validators.js +133 -0
  21. package/console/dist/web/assets/app.css +34 -0
  22. package/console/dist/web/assets/app.js +704 -14
  23. package/console/package.json +2 -0
  24. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +8 -2
  25. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  26. package/core/dist/runtime-v2/activation/__tests__/openclaw-promotion-checks.test.d.ts +2 -0
  27. package/core/dist/runtime-v2/activation/__tests__/openclaw-promotion-checks.test.d.ts.map +1 -0
  28. package/core/dist/runtime-v2/activation/__tests__/openclaw-promotion-checks.test.js +91 -0
  29. package/core/dist/runtime-v2/activation/__tests__/openclaw-promotion-checks.test.js.map +1 -0
  30. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.d.ts +2 -0
  31. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.d.ts.map +1 -0
  32. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js +83 -0
  33. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js.map +1 -0
  34. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-reader.test.d.ts +2 -0
  35. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-reader.test.d.ts.map +1 -0
  36. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-reader.test.js +48 -0
  37. package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-reader.test.js.map +1 -0
  38. package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.d.ts +2 -0
  39. package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.d.ts.map +1 -0
  40. package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js +141 -0
  41. package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js.map +1 -0
  42. package/core/dist/runtime-v2/activation/__tests__/rulecode-safety-circuit-breaker.test.d.ts +2 -0
  43. package/core/dist/runtime-v2/activation/__tests__/rulecode-safety-circuit-breaker.test.d.ts.map +1 -0
  44. package/core/dist/runtime-v2/activation/__tests__/rulecode-safety-circuit-breaker.test.js +31 -0
  45. package/core/dist/runtime-v2/activation/__tests__/rulecode-safety-circuit-breaker.test.js.map +1 -0
  46. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.d.ts +2 -0
  47. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.d.ts.map +1 -0
  48. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js +311 -0
  49. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js.map +1 -0
  50. package/core/dist/runtime-v2/activation/activation-control-types.d.ts +61 -0
  51. package/core/dist/runtime-v2/activation/activation-control-types.d.ts.map +1 -0
  52. package/core/dist/runtime-v2/activation/activation-control-types.js +2 -0
  53. package/core/dist/runtime-v2/activation/activation-control-types.js.map +1 -0
  54. package/core/dist/runtime-v2/activation/index.d.ts +14 -0
  55. package/core/dist/runtime-v2/activation/index.d.ts.map +1 -1
  56. package/core/dist/runtime-v2/activation/index.js +7 -0
  57. package/core/dist/runtime-v2/activation/index.js.map +1 -1
  58. package/core/dist/runtime-v2/activation/openclaw-promotion-checks.d.ts +30 -0
  59. package/core/dist/runtime-v2/activation/openclaw-promotion-checks.d.ts.map +1 -0
  60. package/core/dist/runtime-v2/activation/openclaw-promotion-checks.js +124 -0
  61. package/core/dist/runtime-v2/activation/openclaw-promotion-checks.js.map +1 -0
  62. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.d.ts +17 -0
  63. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.d.ts.map +1 -0
  64. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.js +55 -0
  65. package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.js.map +1 -0
  66. package/core/dist/runtime-v2/activation/promotion-readiness-reader.d.ts +21 -0
  67. package/core/dist/runtime-v2/activation/promotion-readiness-reader.d.ts.map +1 -0
  68. package/core/dist/runtime-v2/activation/promotion-readiness-reader.js +44 -0
  69. package/core/dist/runtime-v2/activation/promotion-readiness-reader.js.map +1 -0
  70. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.d.ts +104 -0
  71. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.d.ts.map +1 -0
  72. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.js +86 -0
  73. package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.js.map +1 -0
  74. package/core/dist/runtime-v2/activation/rulecode-safety-circuit-breaker.d.ts +25 -0
  75. package/core/dist/runtime-v2/activation/rulecode-safety-circuit-breaker.d.ts.map +1 -0
  76. package/core/dist/runtime-v2/activation/rulecode-safety-circuit-breaker.js +23 -0
  77. package/core/dist/runtime-v2/activation/rulecode-safety-circuit-breaker.js.map +1 -0
  78. package/core/dist/runtime-v2/activation/rulecode-shadow-summary.d.ts +14 -0
  79. package/core/dist/runtime-v2/activation/rulecode-shadow-summary.d.ts.map +1 -0
  80. package/core/dist/runtime-v2/activation/rulecode-shadow-summary.js +57 -0
  81. package/core/dist/runtime-v2/activation/rulecode-shadow-summary.js.map +1 -0
  82. package/core/dist/runtime-v2/activation/sqlite-activation-safety-store.d.ts +40 -0
  83. package/core/dist/runtime-v2/activation/sqlite-activation-safety-store.d.ts.map +1 -0
  84. package/core/dist/runtime-v2/activation/sqlite-activation-safety-store.js +461 -0
  85. package/core/dist/runtime-v2/activation/sqlite-activation-safety-store.js.map +1 -0
  86. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts.map +1 -1
  87. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js +24 -6
  88. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js.map +1 -1
  89. package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js +19 -4
  90. package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js.map +1 -1
  91. package/core/dist/runtime-v2/activation/writers/rule-host-writer.d.ts.map +1 -1
  92. package/core/dist/runtime-v2/activation/writers/rule-host-writer.js +10 -0
  93. package/core/dist/runtime-v2/activation/writers/rule-host-writer.js.map +1 -1
  94. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js +13 -0
  95. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js.map +1 -1
  96. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +15 -2
  97. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  98. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  99. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +2 -0
  100. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  101. package/core/dist/runtime-v2/index.d.ts +2 -2
  102. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  103. package/core/dist/runtime-v2/index.js +1 -1
  104. package/core/dist/runtime-v2/index.js.map +1 -1
  105. package/core/dist/runtime-v2/internalization/__tests__/legacy-rule-contract-scanner.test.js +20 -1
  106. package/core/dist/runtime-v2/internalization/__tests__/legacy-rule-contract-scanner.test.js.map +1 -1
  107. package/core/dist/runtime-v2/internalization/legacy-rule-contract-scanner.d.ts +4 -4
  108. package/core/dist/runtime-v2/internalization/legacy-rule-contract-scanner.d.ts.map +1 -1
  109. package/core/dist/runtime-v2/internalization/legacy-rule-contract-scanner.js +92 -5
  110. package/core/dist/runtime-v2/internalization/legacy-rule-contract-scanner.js.map +1 -1
  111. package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.js +11 -11
  112. package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.js.map +1 -1
  113. package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
  114. package/core/dist/runtime-v2/store/sqlite-connection.js +111 -0
  115. package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
  116. package/host-runtime/dist/host-liveness-contract.d.ts +3 -0
  117. package/host-runtime/dist/host-liveness-contract.js +18 -0
  118. package/host-runtime/dist/index.d.ts +1 -0
  119. package/host-runtime/dist/index.js +1 -0
  120. package/host-runtime/dist/legacy-rule-contract-symbols.js +88 -1
  121. package/host-runtime/dist/production-rulehost-gate.js +33 -16
  122. package/package.json +2 -2
  123. package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.js +3 -3
  124. package/pd-cli/dist/commands/__tests__/runtime-activation-nextaction.test.js.map +1 -1
  125. package/pd-cli/dist/commands/runtime-activation.d.ts +15 -3
  126. package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
  127. package/pd-cli/dist/commands/runtime-activation.js +160 -49
  128. package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
  129. package/plugin/dist/bundle.js +730 -565
  130. package/plugin/dist/core/rule-host.d.ts +0 -19
  131. package/plugin/dist/core/rulecode-safety-circuit.d.ts +13 -0
  132. package/plugin/openclaw.plugin.json +1 -1
  133. package/plugin/package.json +1 -1
@@ -7,7 +7,7 @@ import { PageShell } from "../../components/layout/page-shell.js";
7
7
  import { PageLoading } from "../../components/layout/page-loading.js";
8
8
  import { SectionTitle } from "../../components/layout/section-title.js";
9
9
  import { Button } from "../../components/ui/button.js";
10
- import { fetchPrincipleDetail, fetchApprovalsGrouped, fetchLifecycleMetrics, fetchPrincipleTrajectory, fetchPrincipleGovernance, approveApproval, rejectApproval, editApproval, } from "../../api.js";
10
+ import { fetchPrincipleDetail, fetchApprovalsGrouped, fetchLifecycleMetrics, fetchPrincipleTrajectory, fetchPrincipleGovernance, fetchPrincipleReceipts, approveApproval, rejectApproval, editApproval, } from "../../api.js";
11
11
  // ── Runtime validation (H section) ──────────────────────────────────────────
12
12
  function isString(v) {
13
13
  return typeof v === "string";
@@ -117,6 +117,7 @@ export function PrincipleDetailPage() {
117
117
  const [trajectory, setTrajectory] = useState(null);
118
118
  const [governance, setGovernance] = useState(null);
119
119
  const [governanceUnavailable, setGovernanceUnavailable] = useState(null);
120
+ const [receipts, setReceipts] = useState(null);
120
121
  const [loading, setLoading] = useState(true);
121
122
  const [error, setError] = useState(null);
122
123
  // Decision state
@@ -139,13 +140,15 @@ export function PrincipleDetailPage() {
139
140
  setApprovalGroup(null); // Clear previous approval group to prevent stale actionability (P1)
140
141
  setGovernance(null);
141
142
  setGovernanceUnavailable(null);
143
+ setReceipts(null);
142
144
  try {
143
- const [pResult, aResult, lResult, tResult, gResult] = await Promise.all([
145
+ const [pResult, aResult, lResult, tResult, gResult, rResult] = await Promise.all([
144
146
  fetchPrincipleDetail(id),
145
147
  fetchApprovalsGrouped(),
146
148
  fetchLifecycleMetrics(id),
147
149
  fetchPrincipleTrajectory(id),
148
150
  fetchPrincipleGovernance(id),
151
+ fetchPrincipleReceipts(id),
149
152
  ]);
150
153
  if (!pResult.success) {
151
154
  setError(pResult.error ?? "Failed to load principle");
@@ -180,6 +183,13 @@ export function PrincipleDetailPage() {
180
183
  else if (!gResult.success && gResult.reason !== 'feature_disabled') {
181
184
  setGovernanceUnavailable({ reason: gResult.error, ...(gResult.nextAction === undefined ? {} : { nextAction: gResult.nextAction }) });
182
185
  }
186
+ // PRI-533: receipt history (degraded carries reason + nextAction)
187
+ if (rResult.success && rResult.data) {
188
+ setReceipts(rResult.data);
189
+ }
190
+ else {
191
+ setReceipts(null);
192
+ }
183
193
  }
184
194
  catch (err) {
185
195
  setError(err instanceof Error ? err.message : "Unknown error");
@@ -401,7 +411,11 @@ export function PrincipleDetailPage() {
401
411
  return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsxs(Button, { variant: "ghost", onClick: () => navigate("/principles"), className: "mb-4 -ml-2", children: ["\u2190 ", t("principles.detail.backToList")] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.conclusion") }), _jsx("h1", { className: "text-[22px] font-semibold text-ink leading-snug mb-3", children: principle.text }), _jsx("p", { className: "text-ink-3 text-[14px] leading-relaxed mb-3", children: t("principles.detail.policyNote") }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Button, { variant: "outline", size: "sm", disabled: true, children: t("principles.detail.modifyWording") }), _jsx("span", { className: "text-ink-4 text-[13px]", children: t("principles.detail.modifyWordingNote") }), _jsx(Button, { variant: "ghost", size: "sm", className: "ml-auto", "data-testid": "principle-feedback", onClick: () => {
402
412
  const params = new URLSearchParams({ source: "principle_page", principleId: id ?? "" });
403
413
  navigate(`/report-problem?${params.toString()}`);
404
- }, children: t("reportProblem.entryFeedback") })] })] }), (governance !== null || governanceUnavailable !== null) && (_jsxs("section", { className: "mb-8", "aria-labelledby": "governance-summary-title", children: [_jsx(SectionTitle, { children: t('principles.detail.governance.title') }), governance !== null ? (_jsxs("div", { "data-testid": "governance-summary", className: `rounded-[var(--radius-md)] border p-4 ${governance.dataQuality.degraded ? 'border-amber/30 bg-amber/5' : 'border-gov/25 bg-gov/5'}`, children: [_jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between", children: [_jsxs("div", { children: [_jsx("h2", { id: "governance-summary-title", className: "text-[18px] font-semibold text-ink", children: t(`principles.detail.${governance.summary.headlineCode}`, { defaultValue: governance.summary.headlineCode }) }), _jsx("p", { className: "mt-1 text-[13px] leading-relaxed text-ink-2", children: t(`principles.detail.${governance.summary.reasonCode}`, { defaultValue: governance.summary.reasonCode }) })] }), _jsx("span", { className: "w-fit rounded-full border border-line px-2 py-1 font-mono text-[11px] text-ink-3", children: t(`principles.detail.governance.confidence.${governance.dataQuality.degraded ? 'degraded' : 'strong'}`) })] }), _jsxs("dl", { className: "mt-4 grid grid-cols-1 gap-3 sm:grid-cols-3", children: [_jsxs("div", { children: [_jsx("dt", { className: "font-mono text-[11px] text-ink-4", children: t('principles.detail.governance.principleState') }), _jsx("dd", { className: "text-[13px] text-ink-2", children: t(`principles.detail.governance.state.${governance.principleState.value}`) })] }), _jsxs("div", { children: [_jsx("dt", { className: "font-mono text-[11px] text-ink-4", children: t('principles.detail.governance.process') }), _jsx("dd", { className: "text-[13px] text-ink-2", children: governance.process.stage === undefined ? t('principles.detail.governance.none') : t(`principles.detail.governance.stage.${governance.process.stage}`) })] }), _jsxs("div", { children: [_jsx("dt", { className: "font-mono text-[11px] text-ink-4", children: t('principles.detail.governance.automation') }), _jsx("dd", { className: "text-[13px] text-ink-2", children: t(`principles.detail.governance.automationState.${governance.automation.state}`) })] })] }), _jsxs("div", { "data-testid": "governance-next-action", className: "mt-4 border-l-2 border-l-gov pl-3", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.governance.nextAction') }), _jsx("p", { className: "text-[13px] text-ink-2", children: t(`principles.detail.${governance.summary.nextActionCode}`, { defaultValue: governance.summary.nextActionCode }) })] }), governance.attention.items.length > 0 && (_jsxs("div", { className: "mt-4", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.governance.blockers') }), _jsx("ul", { className: "mt-1 space-y-1 text-[13px] text-ink-2", children: governance.attention.items.map(item => _jsx("li", { children: t(`principles.detail.governance.attention.${item.reasonCode}`, { defaultValue: item.reasonCode }) }, `${item.kind}-${item.sourceRef.type}-${item.sourceRef.id}`)) })] })), governance.dataQuality.degraded && (_jsxs("div", { "data-testid": "governance-data-quality", className: "mt-4 rounded-[var(--radius-sm)] border border-amber/20 p-3", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-amber", children: t('principles.detail.governance.uncertainty') }), _jsx("ul", { className: "mt-1 space-y-1 text-[12px] text-ink-3", children: governance.dataQuality.issues.map((item, index) => _jsx("li", { children: t(`principles.detail.governance.issue.${item.reasonCode}`, { defaultValue: item.reasonCode }) }, `${item.source}-${item.reasonCode}-${index}`)) })] }))] })) : (_jsxs("div", { "data-testid": "governance-data-quality", className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("h2", { id: "governance-summary-title", className: "text-[16px] font-semibold text-ink", children: t('principles.detail.governance.unavailable') }), _jsx("p", { className: "mt-1 text-[13px] text-ink-2", children: t('principles.detail.governance.unavailableReason') }), _jsx("p", { className: "mt-2 text-[12px] text-ink-3", children: t('principles.detail.governance.unavailableNextAction') })] }))] })), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.channel") }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.channelPromptReversible") })] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.whyExists") }), _jsxs("div", { className: "space-y-3 mb-6", children: [_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.applicable", { defaultValue: "适用场景" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.triggerPattern || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] }), _jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.expectedBehavior", { defaultValue: "预期行为" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.action || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] })] }), principle.derivedFromPainIds.length > 0 && (_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.evidence") }), _jsxs("div", { className: "mt-2 flex items-center gap-3 flex-wrap", children: [_jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.evidenceCount", {
414
+ }, children: t("reportProblem.entryFeedback") })] })] }), (governance !== null || governanceUnavailable !== null) && (_jsxs("section", { className: "mb-8", "aria-labelledby": "governance-summary-title", children: [_jsx(SectionTitle, { children: t('principles.detail.governance.title') }), governance !== null ? (_jsxs("div", { "data-testid": "governance-summary", className: `rounded-[var(--radius-md)] border p-4 ${governance.dataQuality.degraded ? 'border-amber/30 bg-amber/5' : 'border-gov/25 bg-gov/5'}`, children: [_jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between", children: [_jsxs("div", { children: [_jsx("h2", { id: "governance-summary-title", className: "text-[18px] font-semibold text-ink", children: t(`principles.detail.${governance.summary.headlineCode}`, { defaultValue: governance.summary.headlineCode }) }), _jsx("p", { className: "mt-1 text-[13px] leading-relaxed text-ink-2", children: t(`principles.detail.${governance.summary.reasonCode}`, { defaultValue: governance.summary.reasonCode }) })] }), _jsx("span", { className: "w-fit rounded-full border border-line px-2 py-1 font-mono text-[11px] text-ink-3", children: t(`principles.detail.governance.confidence.${governance.dataQuality.degraded ? 'degraded' : 'strong'}`) })] }), _jsxs("dl", { className: "mt-4 grid grid-cols-1 gap-3 sm:grid-cols-3", children: [_jsxs("div", { children: [_jsx("dt", { className: "font-mono text-[11px] text-ink-4", children: t('principles.detail.governance.principleState') }), _jsx("dd", { className: "text-[13px] text-ink-2", children: t(`principles.detail.governance.state.${governance.principleState.value}`) })] }), _jsxs("div", { children: [_jsx("dt", { className: "font-mono text-[11px] text-ink-4", children: t('principles.detail.governance.process') }), _jsx("dd", { className: "text-[13px] text-ink-2", children: governance.process.stage === undefined ? t('principles.detail.governance.none') : t(`principles.detail.governance.stage.${governance.process.stage}`) })] }), _jsxs("div", { children: [_jsx("dt", { className: "font-mono text-[11px] text-ink-4", children: t('principles.detail.governance.automation') }), _jsx("dd", { className: "text-[13px] text-ink-2", children: t(`principles.detail.governance.automationState.${governance.automation.state}`) })] })] }), _jsxs("div", { "data-testid": "governance-next-action", className: "mt-4 border-l-2 border-l-gov pl-3", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.governance.nextAction') }), _jsx("p", { className: "text-[13px] text-ink-2", children: t(`principles.detail.${governance.summary.nextActionCode}`, { defaultValue: governance.summary.nextActionCode }) })] }), governance.attention.items.length > 0 && (_jsxs("div", { className: "mt-4", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.governance.blockers') }), _jsx("ul", { className: "mt-1 space-y-1 text-[13px] text-ink-2", children: governance.attention.items.map(item => _jsx("li", { children: t(`principles.detail.governance.attention.${item.reasonCode}`, { defaultValue: item.reasonCode }) }, `${item.kind}-${item.sourceRef.type}-${item.sourceRef.id}`)) })] })), governance.dataQuality.degraded && (_jsxs("div", { "data-testid": "governance-data-quality", className: "mt-4 rounded-[var(--radius-sm)] border border-amber/20 p-3", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-amber", children: t('principles.detail.governance.uncertainty') }), _jsx("ul", { className: "mt-1 space-y-1 text-[12px] text-ink-3", children: governance.dataQuality.issues.map((item, index) => _jsx("li", { children: t(`principles.detail.governance.issue.${item.reasonCode}`, { defaultValue: item.reasonCode }) }, `${item.source}-${item.reasonCode}-${index}`)) })] }))] })) : (_jsxs("div", { "data-testid": "governance-data-quality", className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("h2", { id: "governance-summary-title", className: "text-[16px] font-semibold text-ink", children: t('principles.detail.governance.unavailable') }), _jsx("p", { className: "mt-1 text-[13px] text-ink-2", children: t('principles.detail.governance.unavailableReason') }), _jsx("p", { className: "mt-2 text-[12px] text-ink-3", children: t('principles.detail.governance.unavailableNextAction') })] }))] })), receipts !== null && (_jsxs("section", { className: "mb-8", "aria-labelledby": "receipt-history-title", children: [_jsx(SectionTitle, { children: t('principles.detail.receipts.title') }), receipts.status === 'ok' ? (_jsxs("div", { "data-testid": "receipt-history", className: "rounded-[var(--radius-md)] border border-line p-4", children: [_jsxs("div", { className: "flex flex-wrap items-baseline justify-between gap-2", children: [_jsx("h2", { id: "receipt-history-title", className: "text-[15px] font-semibold text-ink", children: t('principles.detail.receipts.headline', {
415
+ defaultValue: '',
416
+ effectCount: receipts.effectCount,
417
+ lastEffectAt: receipts.lastEffectAt ? new Date(receipts.lastEffectAt).toLocaleDateString() : '',
418
+ }) }), _jsx("span", { "data-testid": "receipt-history-counts", className: "font-mono text-[11px] text-ink-3", children: t('principles.detail.receipts.counts', { effectCount: receipts.effectCount, presenceCount: receipts.presenceCount }) })] }), receipts.events.length > 0 ? (_jsx("ul", { className: "mt-3 space-y-1.5", children: receipts.events.map((event, index) => (_jsxs("li", { className: `flex flex-wrap items-baseline gap-2 text-[13px] ${event.level === 'presence' ? 'text-ink-4' : 'text-ink-2'}`, children: [_jsx("span", { className: "font-mono text-[11px] text-ink-4", children: event.createdAt.slice(0, 16).replace('T', ' ') }), _jsx("span", { className: "font-mono text-[11px]", children: t(`principles.detail.receipts.kind.${event.kind}`, { defaultValue: event.kind }) }), event.digest && _jsx("span", { className: "min-w-0 flex-1 truncate", title: event.digest, children: event.digest })] }, `${event.createdAt}-${index}`))) })) : (_jsx("p", { className: "mt-2 text-[13px] text-ink-3", children: t('principles.detail.receipts.empty') })), _jsx("p", { className: "mt-3 text-[11px] leading-relaxed text-ink-4", children: t('principles.detail.receipts.note') })] })) : (_jsxs("div", { "data-testid": "receipt-history-degraded", className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("p", { className: "text-[13px] text-ink-2", children: receipts.reason ?? t('principles.detail.receipts.unavailableReason') }), receipts.nextAction && _jsx("p", { className: "mt-1 text-[12px] text-ink-3", children: receipts.nextAction })] }))] })), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.channel") }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.channelPromptReversible") })] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.whyExists") }), _jsxs("div", { className: "space-y-3 mb-6", children: [_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.applicable", { defaultValue: "适用场景" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.triggerPattern || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] }), _jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.expectedBehavior", { defaultValue: "预期行为" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.action || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] })] }), principle.derivedFromPainIds.length > 0 && (_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.evidence") }), _jsxs("div", { className: "mt-2 flex items-center gap-3 flex-wrap", children: [_jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.evidenceCount", {
405
419
  defaultValue: "已关联 {{count}} 条证据记录",
406
420
  count: principle.derivedFromPainIds.length,
407
421
  }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: async () => {
@@ -242,6 +242,9 @@ export interface ActivationRecordData {
242
242
  targetRef: string;
243
243
  activatedAt: string | null;
244
244
  status: string;
245
+ enforcement?: 'eligible' | 'safety_isolated';
246
+ legacyDecisionUnknown?: boolean;
247
+ ownerReviewDueAt?: string;
245
248
  }
246
249
  export interface ActivationsData {
247
250
  activations: ActivationRecordData[];
@@ -254,6 +257,103 @@ export interface DisableActivationData {
254
257
  activationId: string;
255
258
  status: string;
256
259
  }
260
+ export interface RuleCodeOwnerReviewData {
261
+ activation: {
262
+ activationId: string;
263
+ artifactId: string;
264
+ action: string;
265
+ };
266
+ artifact: {
267
+ artifactId: string;
268
+ digest: string;
269
+ content: Record<string, unknown> | null;
270
+ };
271
+ readiness: {
272
+ status: 'ready' | 'evidence_insufficient' | 'blocked' | 'unavailable';
273
+ evaluationId: string;
274
+ failedChecks: {
275
+ checkId: string;
276
+ reasonCode: string;
277
+ }[];
278
+ evidenceSnapshot: {
279
+ snapshotDigest: string;
280
+ shadowSummary: RuleCodeShadowSummaryData;
281
+ safetyGateResults: {
282
+ checkId: string;
283
+ status: 'passed' | 'failed';
284
+ reasonCode?: string;
285
+ }[];
286
+ };
287
+ };
288
+ controlState: {
289
+ enforcement: 'eligible' | 'safety_isolated';
290
+ version: number;
291
+ } | null;
292
+ globalPause: {
293
+ pauseId: string;
294
+ status: 'paused' | 'released';
295
+ version: number;
296
+ } | null;
297
+ decisions: RuleCodeOwnerDecisionData[];
298
+ ownerDecisionEnabled: boolean;
299
+ runtimeCapability: {
300
+ hostRuntimeVersion: string;
301
+ shadowEvidence: boolean;
302
+ };
303
+ liveMetrics: {
304
+ last24Hours: RuleCodeTelemetryWindowData;
305
+ last7Days: RuleCodeTelemetryWindowData;
306
+ representativeSamples: {
307
+ toolName: string;
308
+ decision: string;
309
+ pathCategory: string;
310
+ }[];
311
+ };
312
+ behaviorDrift: {
313
+ approvedBlockRate: number | null;
314
+ liveBlockRate: number | null;
315
+ delta: number | null;
316
+ };
317
+ }
318
+ interface RuleCodeOwnerDecisionData {
319
+ decisionId: string;
320
+ decision: string;
321
+ principalKind: string;
322
+ actorId: string;
323
+ authenticationMethod: string;
324
+ reasonCode: string;
325
+ note: string | null;
326
+ decidedAt: string;
327
+ }
328
+ interface RuleCodeShadowSummaryData {
329
+ observed: number | null;
330
+ matched: number | null;
331
+ wouldBlock: number | null;
332
+ wouldAllow: number | null;
333
+ requireApproval: number | null;
334
+ autoCorrect: number | null;
335
+ errors: number | null;
336
+ neutralControl: number | null;
337
+ firstObservedAt: string | null;
338
+ lastObservedAt: string | null;
339
+ }
340
+ interface RuleCodeTelemetryWindowData {
341
+ eligible: number | null;
342
+ matched: number | null;
343
+ blocked: number | null;
344
+ unhealthy: number | null;
345
+ circuitTrips: number;
346
+ toolDistribution: Record<string, number> | null;
347
+ }
348
+ export declare function validateRuleCodeOwnerReview(v: unknown): RuleCodeOwnerReviewData | null;
349
+ export interface RuleCodeMutationData {
350
+ decisionId?: string;
351
+ activationId?: string;
352
+ status?: string;
353
+ pauseId?: string;
354
+ version?: number;
355
+ }
356
+ export declare function validateRuleCodeMutation(v: unknown): RuleCodeMutationData | null;
257
357
  export declare function validateDisableActivation(v: unknown): DisableActivationData | null;
258
358
  export interface LifecycleAdherenceData {
259
359
  insufficientData: boolean;
@@ -727,11 +727,17 @@ function validateActivationRecord(v) {
727
727
  return null;
728
728
  if (!Object.hasOwn(v, 'status') || !isString(v.status))
729
729
  return null;
730
+ const enforcement = Object.hasOwn(v, 'enforcement') && (v.enforcement === 'eligible' || v.enforcement === 'safety_isolated')
731
+ ? v.enforcement
732
+ : undefined;
730
733
  return {
731
734
  activationId: v.activationId, artifactId: v.artifactId, principleId: v.principleId,
732
735
  channel: v.channel, action: v.action, targetRef: v.targetRef,
733
736
  activatedAt: activatedAt.value,
734
737
  status: v.status,
738
+ ...(enforcement ? { enforcement } : {}),
739
+ ...(Object.hasOwn(v, 'legacyDecisionUnknown') && v.legacyDecisionUnknown === true ? { legacyDecisionUnknown: true } : {}),
740
+ ...(Object.hasOwn(v, 'ownerReviewDueAt') && isString(v.ownerReviewDueAt) ? { ownerReviewDueAt: v.ownerReviewDueAt } : {}),
735
741
  };
736
742
  }
737
743
  export function validateActivations(v) {
@@ -751,6 +757,133 @@ export function validateActivations(v) {
751
757
  result.nextAction = v.nextAction;
752
758
  return result;
753
759
  }
760
+ function validateTelemetryWindow(value) {
761
+ if (!isObject(value))
762
+ return null;
763
+ const keys = ['eligible', 'matched', 'blocked', 'unhealthy'];
764
+ if (!keys.every(key => value[key] === null || isNumber(value[key])) || !isNumber(value.circuitTrips))
765
+ return null;
766
+ if (value.toolDistribution !== null && (!isObject(value.toolDistribution) || !Object.values(value.toolDistribution).every(isNumber)))
767
+ return null;
768
+ return { eligible: typeof value.eligible === 'number' ? value.eligible : null, matched: typeof value.matched === 'number' ? value.matched : null, blocked: typeof value.blocked === 'number' ? value.blocked : null, unhealthy: typeof value.unhealthy === 'number' ? value.unhealthy : null, circuitTrips: value.circuitTrips, toolDistribution: isObject(value.toolDistribution) ? Object.fromEntries(Object.entries(value.toolDistribution).filter((entry) => typeof entry[1] === 'number')) : null };
769
+ }
770
+ function validateRuleCodeDecision(value) {
771
+ if (!isObject(value) || !isString(value.decisionId) || !isString(value.decision)
772
+ || !isObject(value.principal) || !isString(value.principal.kind)
773
+ || !isObject(value.authentication) || !isString(value.authentication.method)
774
+ || !isString(value.reasonCode) || (value.note !== null && !isString(value.note))
775
+ || !isString(value.decidedAt))
776
+ return null;
777
+ const actorId = typeof value.principal.ownerId === 'string'
778
+ ? value.principal.ownerId
779
+ : typeof value.principal.policyVersion === 'string'
780
+ ? value.principal.policyVersion
781
+ : typeof value.principal.reason === 'string' ? value.principal.reason : value.principal.kind;
782
+ return {
783
+ decisionId: value.decisionId,
784
+ decision: value.decision,
785
+ principalKind: value.principal.kind,
786
+ actorId,
787
+ authenticationMethod: value.authentication.method,
788
+ reasonCode: value.reasonCode,
789
+ note: typeof value.note === 'string' ? value.note : null,
790
+ decidedAt: value.decidedAt,
791
+ };
792
+ }
793
+ export function validateRuleCodeOwnerReview(v) {
794
+ if (!isObject(v) || !isObject(v.activation) || !isObject(v.artifact) || !isObject(v.readiness))
795
+ return null;
796
+ const { activation, artifact, readiness } = v;
797
+ if (!isString(activation.activationId) || !isString(activation.artifactId) || !isString(activation.action)
798
+ || !isString(artifact.artifactId) || !isString(artifact.digest)
799
+ || (artifact.content !== null && !isObject(artifact.content))
800
+ || !isString(readiness.status) || !['ready', 'evidence_insufficient', 'blocked', 'unavailable'].includes(readiness.status)
801
+ || !isString(readiness.evaluationId) || !Array.isArray(readiness.failedChecks)
802
+ || !readiness.failedChecks.every(item => isObject(item) && isString(item.checkId) && isString(item.reasonCode))
803
+ || !isObject(readiness.evidenceSnapshot) || !isString(readiness.evidenceSnapshot.snapshotDigest)
804
+ || !isObject(readiness.evidenceSnapshot.shadowSummary) || !Array.isArray(readiness.evidenceSnapshot.safetyGateResults)
805
+ || !readiness.evidenceSnapshot.safetyGateResults.every(item => isObject(item) && isString(item.checkId) && (item.status === 'passed' || item.status === 'failed') && (!Object.hasOwn(item, 'reasonCode') || isString(item.reasonCode))))
806
+ return null;
807
+ const summary = readiness.evidenceSnapshot.shadowSummary;
808
+ const summaryCounts = ['observed', 'matched', 'wouldBlock', 'wouldAllow', 'requireApproval', 'autoCorrect', 'errors', 'neutralControl'];
809
+ if (!summaryCounts.every(key => summary[key] === null || isNumber(summary[key])))
810
+ return null;
811
+ if (![summary.firstObservedAt, summary.lastObservedAt].every(value => value === null || isString(value)))
812
+ return null;
813
+ let controlState = null;
814
+ if (v.controlState !== null) {
815
+ if (!isObject(v.controlState) || (v.controlState.enforcement !== 'eligible' && v.controlState.enforcement !== 'safety_isolated') || !isNumber(v.controlState.version))
816
+ return null;
817
+ controlState = { enforcement: v.controlState.enforcement, version: v.controlState.version };
818
+ }
819
+ let globalPause = null;
820
+ if (v.globalPause !== null) {
821
+ if (!isObject(v.globalPause) || !isString(v.globalPause.pauseId) || (v.globalPause.status !== 'paused' && v.globalPause.status !== 'released') || !isNumber(v.globalPause.version))
822
+ return null;
823
+ globalPause = { pauseId: v.globalPause.pauseId, status: v.globalPause.status, version: v.globalPause.version };
824
+ }
825
+ if (!isBoolean(v.ownerDecisionEnabled))
826
+ return null;
827
+ if (!Array.isArray(v.decisions) || !isObject(v.runtimeCapability) || !isString(v.runtimeCapability.hostRuntimeVersion) || !isBoolean(v.runtimeCapability.shadowEvidence) || !isObject(v.liveMetrics) || !Array.isArray(v.liveMetrics.representativeSamples) || !v.liveMetrics.representativeSamples.every(sample => isObject(sample) && isString(sample.toolName) && isString(sample.decision) && isString(sample.pathCategory)) || !isObject(v.behaviorDrift))
828
+ return null;
829
+ const { behaviorDrift } = v;
830
+ const decisions = v.decisions.map(validateRuleCodeDecision);
831
+ if (decisions.some(decision => decision === null))
832
+ return null;
833
+ const driftKeys = ['approvedBlockRate', 'liveBlockRate', 'delta'];
834
+ if (!driftKeys.every(key => behaviorDrift[key] === null || isNumber(behaviorDrift[key])))
835
+ return null;
836
+ const last24Hours = validateTelemetryWindow(v.liveMetrics.last24Hours);
837
+ const last7Days = validateTelemetryWindow(v.liveMetrics.last7Days);
838
+ if (!last24Hours || !last7Days)
839
+ return null;
840
+ const readinessStatus = readiness.status === 'ready' || readiness.status === 'evidence_insufficient' || readiness.status === 'blocked' || readiness.status === 'unavailable' ? readiness.status : null;
841
+ const shadowSummary = {
842
+ observed: typeof summary.observed === 'number' ? summary.observed : null,
843
+ matched: typeof summary.matched === 'number' ? summary.matched : null,
844
+ wouldBlock: typeof summary.wouldBlock === 'number' ? summary.wouldBlock : null,
845
+ wouldAllow: typeof summary.wouldAllow === 'number' ? summary.wouldAllow : null,
846
+ requireApproval: typeof summary.requireApproval === 'number' ? summary.requireApproval : null,
847
+ autoCorrect: typeof summary.autoCorrect === 'number' ? summary.autoCorrect : null,
848
+ errors: typeof summary.errors === 'number' ? summary.errors : null,
849
+ neutralControl: typeof summary.neutralControl === 'number' ? summary.neutralControl : null,
850
+ firstObservedAt: typeof summary.firstObservedAt === 'string' ? summary.firstObservedAt : null,
851
+ lastObservedAt: typeof summary.lastObservedAt === 'string' ? summary.lastObservedAt : null,
852
+ };
853
+ if (readinessStatus === null)
854
+ return null;
855
+ return {
856
+ activation: { activationId: activation.activationId, artifactId: activation.artifactId, action: activation.action },
857
+ artifact: { artifactId: artifact.artifactId, digest: artifact.digest, content: artifact.content },
858
+ readiness: { status: readinessStatus, evaluationId: readiness.evaluationId, failedChecks: readiness.failedChecks.map(item => ({ checkId: item.checkId, reasonCode: item.reasonCode })), evidenceSnapshot: { snapshotDigest: readiness.evidenceSnapshot.snapshotDigest, shadowSummary, safetyGateResults: readiness.evidenceSnapshot.safetyGateResults.map(item => ({ checkId: item.checkId, status: item.status, ...(typeof item.reasonCode === 'string' ? { reasonCode: item.reasonCode } : {}) })) } },
859
+ controlState, globalPause, decisions: decisions.filter((decision) => decision !== null), ownerDecisionEnabled: v.ownerDecisionEnabled,
860
+ runtimeCapability: { hostRuntimeVersion: v.runtimeCapability.hostRuntimeVersion, shadowEvidence: v.runtimeCapability.shadowEvidence },
861
+ liveMetrics: { last24Hours, last7Days, representativeSamples: v.liveMetrics.representativeSamples.map(sample => ({ toolName: sample.toolName, decision: sample.decision, pathCategory: sample.pathCategory })) },
862
+ behaviorDrift: {
863
+ approvedBlockRate: typeof behaviorDrift.approvedBlockRate === 'number' ? behaviorDrift.approvedBlockRate : null,
864
+ liveBlockRate: typeof behaviorDrift.liveBlockRate === 'number' ? behaviorDrift.liveBlockRate : null,
865
+ delta: typeof behaviorDrift.delta === 'number' ? behaviorDrift.delta : null,
866
+ },
867
+ };
868
+ }
869
+ export function validateRuleCodeMutation(v) {
870
+ if (!isObject(v))
871
+ return null;
872
+ const result = {};
873
+ for (const key of ['decisionId', 'activationId', 'status', 'pauseId']) {
874
+ if (Object.hasOwn(v, key)) {
875
+ if (!isString(v[key]))
876
+ return null;
877
+ result[key] = v[key];
878
+ }
879
+ }
880
+ if (Object.hasOwn(v, 'version')) {
881
+ if (!isNumber(v.version))
882
+ return null;
883
+ result.version = v.version;
884
+ }
885
+ return result;
886
+ }
754
887
  export function validateDisableActivation(v) {
755
888
  if (!isObject(v))
756
889
  return null;
@@ -628,6 +628,9 @@
628
628
  .h-screen {
629
629
  height: 100vh;
630
630
  }
631
+ .max-h-64 {
632
+ max-height: calc(var(--spacing) * 64);
633
+ }
631
634
  .max-h-80 {
632
635
  max-height: calc(var(--spacing) * 80);
633
636
  }
@@ -1101,6 +1104,9 @@
1101
1104
  .rounded-\[4px\] {
1102
1105
  border-radius: 4px;
1103
1106
  }
1107
+ .rounded-\[5px\] {
1108
+ border-radius: 5px;
1109
+ }
1104
1110
  .rounded-\[6px\] {
1105
1111
  border-radius: 6px;
1106
1112
  }
@@ -1569,6 +1575,12 @@
1569
1575
  background-color: color-mix(in oklab, var(--color-surface) 60%, transparent);
1570
1576
  }
1571
1577
  }
1578
+ .bg-surface\/70 {
1579
+ background-color: color-mix(in srgb, #fbf8f0 70%, transparent);
1580
+ @supports (color: color-mix(in lab, red, red)) {
1581
+ background-color: color-mix(in oklab, var(--color-surface) 70%, transparent);
1582
+ }
1583
+ }
1572
1584
  .bg-surface\/80 {
1573
1585
  background-color: color-mix(in srgb, #fbf8f0 80%, transparent);
1574
1586
  @supports (color: color-mix(in lab, red, red)) {
@@ -1797,6 +1809,9 @@
1797
1809
  .pb-\[14px\] {
1798
1810
  padding-bottom: 14px;
1799
1811
  }
1812
+ .pl-2 {
1813
+ padding-left: calc(var(--spacing) * 2);
1814
+ }
1800
1815
  .pl-3 {
1801
1816
  padding-left: calc(var(--spacing) * 3);
1802
1817
  }
@@ -2168,6 +2183,10 @@
2168
2183
  --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
2169
2184
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2170
2185
  }
2186
+ .shadow\/live {
2187
+ --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
2188
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2189
+ }
2171
2190
  .ring-offset-background {
2172
2191
  --tw-ring-offset-color: var(--color-background);
2173
2192
  }
@@ -2382,6 +2401,9 @@
2382
2401
  .hover\:rotate-180:hover {
2383
2402
  rotate: 180deg;
2384
2403
  }
2404
+ .hover\:border-danger:hover {
2405
+ border-color: var(--color-danger);
2406
+ }
2385
2407
  .hover\:border-danger\/30:hover {
2386
2408
  border-color: color-mix(in srgb, #8b3a3a 30%, transparent);
2387
2409
  }
@@ -2390,6 +2412,9 @@
2390
2412
  border-color: color-mix(in oklab, var(--color-danger) 30%, transparent);
2391
2413
  }
2392
2414
  }
2415
+ .hover\:border-gov:hover {
2416
+ border-color: var(--color-gov);
2417
+ }
2393
2418
  .hover\:border-line:hover {
2394
2419
  border-color: var(--color-line);
2395
2420
  }
@@ -2726,6 +2751,15 @@
2726
2751
  .md\:w-48 {
2727
2752
  width: calc(var(--spacing) * 48);
2728
2753
  }
2754
+ .md\:grid-cols-2 {
2755
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2756
+ }
2757
+ .md\:grid-cols-4 {
2758
+ grid-template-columns: repeat(4, minmax(0, 1fr));
2759
+ }
2760
+ .md\:grid-cols-5 {
2761
+ grid-template-columns: repeat(5, minmax(0, 1fr));
2762
+ }
2729
2763
  .md\:flex-row {
2730
2764
  flex-direction: row;
2731
2765
  }