create-principles-disciple 1.146.4 → 1.146.7
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.
- package/_release/product-identity.json +1 -1
- package/codex-adapter/package.json +1 -1
- package/core/dist/runtime-v2/evidence-triage/index.d.ts +1 -3
- package/core/dist/runtime-v2/evidence-triage/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/index.js +1 -2
- package/core/dist/runtime-v2/evidence-triage/index.js.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/observation-resolver.d.ts +0 -19
- package/core/dist/runtime-v2/evidence-triage/observation-resolver.d.ts.map +1 -1
- package/core/dist/runtime-v2/evidence-triage/observation-resolver.js +0 -25
- package/core/dist/runtime-v2/evidence-triage/observation-resolver.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +2 -2
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +1 -1
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/telemetry-event.d.ts +2 -2
- package/core/dist/telemetry-event.d.ts.map +1 -1
- package/core/dist/telemetry-event.js +4 -5
- package/core/dist/telemetry-event.js.map +1 -1
- package/core/dist/trajectory-store.d.ts.map +1 -1
- package/core/dist/trajectory-store.js +4 -44
- package/core/dist/trajectory-store.js.map +1 -1
- package/core/package.json +1 -1
- package/host-runtime/package.json +1 -1
- package/package.json +4 -4
- package/plugin/dist/bundle.js +460 -460
- package/plugin/dist/core/config.d.ts +0 -2
- package/plugin/dist/core/trajectory.d.ts +0 -6
- package/plugin/dist/hooks/llm.d.ts +0 -1
- package/plugin/dist/hooks/prompt-helpers.d.ts +2 -1
- package/plugin/dist/hooks/raw-observation-adapter.d.ts +6 -4
- package/plugin/dist/hooks/triage-adapter.d.ts +1 -1
- package/plugin/dist/openclaw.plugin.json +1 -1
- package/plugin/dist/rulehost-evidence.js +6 -6
- package/plugin/dist/templates/pain_settings.json +0 -2
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
- package/plugin/templates/pain_settings.json +0 -2
- package/release-manager/package.json +4 -4
- package/workbuddy-adapter/package.json +1 -1
- package/console/dist/ui/App.d.ts +0 -1
- package/console/dist/ui/App.js +0 -172
- package/console/dist/ui/api.d.ts +0 -611
- package/console/dist/ui/api.js +0 -1094
- package/console/dist/ui/components/auth/login-form.d.ts +0 -4
- package/console/dist/ui/components/auth/login-form.js +0 -142
- package/console/dist/ui/components/auth/splash-screen.d.ts +0 -9
- package/console/dist/ui/components/auth/splash-screen.js +0 -22
- package/console/dist/ui/components/error-boundary.d.ts +0 -15
- package/console/dist/ui/components/error-boundary.js +0 -30
- package/console/dist/ui/components/focus/daily-thought-card.d.ts +0 -1
- package/console/dist/ui/components/focus/daily-thought-card.js +0 -41
- package/console/dist/ui/components/language-switcher.d.ts +0 -2
- package/console/dist/ui/components/language-switcher.js +0 -17
- package/console/dist/ui/components/layout/app-sidebar.d.ts +0 -27
- package/console/dist/ui/components/layout/app-sidebar.js +0 -128
- package/console/dist/ui/components/layout/page-loading.d.ts +0 -13
- package/console/dist/ui/components/layout/page-loading.js +0 -14
- package/console/dist/ui/components/layout/page-shell.d.ts +0 -12
- package/console/dist/ui/components/layout/page-shell.js +0 -11
- package/console/dist/ui/components/layout/section-title.d.ts +0 -10
- package/console/dist/ui/components/layout/section-title.js +0 -9
- package/console/dist/ui/components/notifications/NotificationProvider.d.ts +0 -14
- package/console/dist/ui/components/notifications/NotificationProvider.js +0 -136
- package/console/dist/ui/components/notifications/favicon-badge.d.ts +0 -3
- package/console/dist/ui/components/notifications/favicon-badge.js +0 -68
- package/console/dist/ui/components/notifications/notification-reducer.d.ts +0 -9
- package/console/dist/ui/components/notifications/notification-reducer.js +0 -9
- package/console/dist/ui/components/notifications/sound-storage.d.ts +0 -3
- package/console/dist/ui/components/notifications/sound-storage.js +0 -37
- package/console/dist/ui/components/notifications/useNotifications.d.ts +0 -1
- package/console/dist/ui/components/notifications/useNotifications.js +0 -9
- package/console/dist/ui/components/onboarding/CircuitDiagram.d.ts +0 -8
- package/console/dist/ui/components/onboarding/CircuitDiagram.js +0 -18
- package/console/dist/ui/components/onboarding/DemoResultView.d.ts +0 -22
- package/console/dist/ui/components/onboarding/DemoResultView.js +0 -33
- package/console/dist/ui/components/onboarding/SlashCommandsCard.d.ts +0 -16
- package/console/dist/ui/components/onboarding/SlashCommandsCard.js +0 -20
- package/console/dist/ui/components/onboarding/slashCommands.d.ts +0 -20
- package/console/dist/ui/components/onboarding/slashCommands.js +0 -22
- package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.d.ts +0 -6
- package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.js +0 -66
- package/console/dist/ui/components/theme-provider.d.ts +0 -14
- package/console/dist/ui/components/theme-provider.js +0 -40
- package/console/dist/ui/components/theme-toggle.d.ts +0 -2
- package/console/dist/ui/components/theme-toggle.js +0 -11
- package/console/dist/ui/components/ui/alert-dialog.d.ts +0 -20
- package/console/dist/ui/components/ui/alert-dialog.js +0 -26
- package/console/dist/ui/components/ui/badge.d.ts +0 -9
- package/console/dist/ui/components/ui/badge.js +0 -22
- package/console/dist/ui/components/ui/button.d.ts +0 -11
- package/console/dist/ui/components/ui/button.js +0 -34
- package/console/dist/ui/components/ui/card.d.ts +0 -8
- package/console/dist/ui/components/ui/card.js +0 -16
- package/console/dist/ui/components/ui/charts.d.ts +0 -51
- package/console/dist/ui/components/ui/charts.js +0 -72
- package/console/dist/ui/components/ui/dialog.d.ts +0 -19
- package/console/dist/ui/components/ui/dialog.js +0 -22
- package/console/dist/ui/components/ui/input.d.ts +0 -3
- package/console/dist/ui/components/ui/input.js +0 -8
- package/console/dist/ui/components/ui/markdown.d.ts +0 -24
- package/console/dist/ui/components/ui/markdown.js +0 -119
- package/console/dist/ui/components/ui/progress-bar.d.ts +0 -20
- package/console/dist/ui/components/ui/progress-bar.js +0 -38
- package/console/dist/ui/components/ui/select.d.ts +0 -13
- package/console/dist/ui/components/ui/select.js +0 -26
- package/console/dist/ui/components/ui/separator.d.ts +0 -3
- package/console/dist/ui/components/ui/separator.js +0 -6
- package/console/dist/ui/components/ui/sheet.d.ts +0 -25
- package/console/dist/ui/components/ui/sheet.js +0 -37
- package/console/dist/ui/components/ui/shiny-text.d.ts +0 -28
- package/console/dist/ui/components/ui/shiny-text.js +0 -46
- package/console/dist/ui/components/ui/skeleton.d.ts +0 -3
- package/console/dist/ui/components/ui/skeleton.js +0 -6
- package/console/dist/ui/components/ui/sonner.d.ts +0 -3
- package/console/dist/ui/components/ui/sonner.js +0 -13
- package/console/dist/ui/components/ui/tooltip.d.ts +0 -7
- package/console/dist/ui/components/ui/tooltip.js +0 -10
- package/console/dist/ui/data/daily-thoughts.d.ts +0 -15
- package/console/dist/ui/data/daily-thoughts.js +0 -164
- package/console/dist/ui/hooks/useNotificationSound.d.ts +0 -12
- package/console/dist/ui/hooks/useNotificationSound.js +0 -74
- package/console/dist/ui/i18n/en.json +0 -2399
- package/console/dist/ui/i18n/index.d.ts +0 -2
- package/console/dist/ui/i18n/index.js +0 -32
- package/console/dist/ui/i18n/zh-CN.json +0 -2399
- package/console/dist/ui/main.d.ts +0 -1
- package/console/dist/ui/main.js +0 -9
- package/console/dist/ui/pages/ReportProblemValidators.d.ts +0 -144
- package/console/dist/ui/pages/ReportProblemValidators.js +0 -418
- package/console/dist/ui/pages/activation/ActivationPage.d.ts +0 -1
- package/console/dist/ui/pages/activation/ActivationPage.js +0 -512
- package/console/dist/ui/pages/activation/ActivationValidators.d.ts +0 -20
- package/console/dist/ui/pages/activation/ActivationValidators.js +0 -160
- package/console/dist/ui/pages/control-center/AgentCard.d.ts +0 -31
- package/console/dist/ui/pages/control-center/AgentCard.js +0 -212
- package/console/dist/ui/pages/control-center/AgentGroup.d.ts +0 -26
- package/console/dist/ui/pages/control-center/AgentGroup.js +0 -38
- package/console/dist/ui/pages/control-center/ControlCenterPage.d.ts +0 -1
- package/console/dist/ui/pages/control-center/ControlCenterPage.js +0 -509
- package/console/dist/ui/pages/control-center/DesignGatePanel.d.ts +0 -1
- package/console/dist/ui/pages/control-center/DesignGatePanel.js +0 -137
- package/console/dist/ui/pages/control-center/RuntimeProfileManager.d.ts +0 -31
- package/console/dist/ui/pages/control-center/RuntimeProfileManager.js +0 -199
- package/console/dist/ui/pages/control-center/WorkflowDiagram.d.ts +0 -17
- package/console/dist/ui/pages/control-center/WorkflowDiagram.js +0 -55
- package/console/dist/ui/pages/debt/DebtPage.d.ts +0 -2
- package/console/dist/ui/pages/debt/DebtPage.js +0 -222
- package/console/dist/ui/pages/design-system/DesignSystemPage.d.ts +0 -2
- package/console/dist/ui/pages/design-system/DesignSystemPage.js +0 -30
- package/console/dist/ui/pages/examiner/ExaminerPage.d.ts +0 -15
- package/console/dist/ui/pages/examiner/ExaminerPage.js +0 -158
- package/console/dist/ui/pages/failed-tasks/FailedTasksPage.d.ts +0 -1
- package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +0 -421
- package/console/dist/ui/pages/focus/ApprovalSubjectReading.d.ts +0 -24
- package/console/dist/ui/pages/focus/ApprovalSubjectReading.js +0 -133
- package/console/dist/ui/pages/focus/FocusPage.d.ts +0 -123
- package/console/dist/ui/pages/focus/FocusPage.js +0 -567
- package/console/dist/ui/pages/focus/OwnerDecisionCard.d.ts +0 -9
- package/console/dist/ui/pages/focus/OwnerDecisionCard.js +0 -111
- package/console/dist/ui/pages/focus/OwnerWorkbench.d.ts +0 -19
- package/console/dist/ui/pages/focus/OwnerWorkbench.js +0 -75
- package/console/dist/ui/pages/focus/RuleCandidateBindingPanel.d.ts +0 -34
- package/console/dist/ui/pages/focus/RuleCandidateBindingPanel.js +0 -298
- package/console/dist/ui/pages/focus/focus-validation.d.ts +0 -40
- package/console/dist/ui/pages/focus/focus-validation.js +0 -211
- package/console/dist/ui/pages/intent/IntentOnboarding.d.ts +0 -67
- package/console/dist/ui/pages/intent/IntentOnboarding.js +0 -289
- package/console/dist/ui/pages/intent/IntentPage.d.ts +0 -1
- package/console/dist/ui/pages/intent/IntentPage.js +0 -252
- package/console/dist/ui/pages/pain/PainEvidenceValidators.d.ts +0 -59
- package/console/dist/ui/pages/pain/PainEvidenceValidators.js +0 -125
- package/console/dist/ui/pages/pain/PainPage.d.ts +0 -1
- package/console/dist/ui/pages/pain/PainPage.js +0 -420
- package/console/dist/ui/pages/pain/pain-card-helpers.d.ts +0 -175
- package/console/dist/ui/pages/pain/pain-card-helpers.js +0 -181
- package/console/dist/ui/pages/principles/CorePrinciplesPage.d.ts +0 -10
- package/console/dist/ui/pages/principles/CorePrinciplesPage.js +0 -59
- package/console/dist/ui/pages/principles/PrincipleDetailPage.d.ts +0 -60
- package/console/dist/ui/pages/principles/PrincipleDetailPage.js +0 -602
- package/console/dist/ui/pages/principles/PrinciplesPage.d.ts +0 -1
- package/console/dist/ui/pages/principles/PrinciplesPage.js +0 -327
- package/console/dist/ui/pages/principles/PrinciplesViewNav.d.ts +0 -8
- package/console/dist/ui/pages/principles/PrinciplesViewNav.js +0 -15
- package/console/dist/ui/pages/report-problem/ReportProblemPage.d.ts +0 -1
- package/console/dist/ui/pages/report-problem/ReportProblemPage.js +0 -467
- package/console/dist/ui/pages/settings/SettingsPage.d.ts +0 -4
- package/console/dist/ui/pages/settings/SettingsPage.js +0 -457
- package/console/dist/ui/pages/settings/UpdatePage.d.ts +0 -1
- package/console/dist/ui/pages/settings/UpdatePage.js +0 -215
- package/console/dist/ui/pages/welcome/WelcomePage.d.ts +0 -5
- package/console/dist/ui/pages/welcome/WelcomePage.js +0 -187
- package/console/dist/ui/utils/agent-metadata.d.ts +0 -71
- package/console/dist/ui/utils/agent-metadata.js +0 -284
- package/console/dist/ui/utils/approval-review.d.ts +0 -30
- package/console/dist/ui/utils/approval-review.js +0 -50
- package/console/dist/ui/utils/approval-warning-localization.d.ts +0 -34
- package/console/dist/ui/utils/approval-warning-localization.js +0 -148
- package/console/dist/ui/utils/attention-presentation.d.ts +0 -35
- package/console/dist/ui/utils/attention-presentation.js +0 -46
- package/console/dist/ui/utils/blocker-localization.d.ts +0 -23
- package/console/dist/ui/utils/blocker-localization.js +0 -36
- package/console/dist/ui/utils/control-center-helpers.d.ts +0 -79
- package/console/dist/ui/utils/control-center-helpers.js +0 -189
- package/console/dist/ui/utils/enum-labels.d.ts +0 -50
- package/console/dist/ui/utils/enum-labels.js +0 -171
- package/console/dist/ui/utils/format-date.d.ts +0 -11
- package/console/dist/ui/utils/format-date.js +0 -17
- package/console/dist/ui/utils/onboarding-state.d.ts +0 -25
- package/console/dist/ui/utils/onboarding-state.js +0 -77
- package/console/dist/ui/utils/reading-layout.d.ts +0 -20
- package/console/dist/ui/utils/reading-layout.js +0 -46
- package/console/dist/ui/utils/rule-binding-validators.d.ts +0 -13
- package/console/dist/ui/utils/rule-binding-validators.js +0 -188
- package/console/dist/ui/utils/runtime-mode.d.ts +0 -11
- package/console/dist/ui/utils/runtime-mode.js +0 -11
- package/console/dist/ui/utils/token-storage.d.ts +0 -22
- package/console/dist/ui/utils/token-storage.js +0 -47
- package/console/dist/ui/utils/validators.d.ts +0 -1178
- package/console/dist/ui/utils/validators.js +0 -3297
- package/core/dist/runtime-v2/evidence-triage/admission-events.d.ts +0 -126
- package/core/dist/runtime-v2/evidence-triage/admission-events.d.ts.map +0 -1
- package/core/dist/runtime-v2/evidence-triage/admission-events.js +0 -159
- package/core/dist/runtime-v2/evidence-triage/admission-events.js.map +0 -1
- package/plugin/dist/core/detection-funnel.d.ts +0 -47
- package/plugin/dist/core/detection-service.d.ts +0 -15
- package/release-manager/dist/bootstrap-entry.d.ts +0 -2
- package/release-manager/dist/bootstrap-entry.d.ts.map +0 -1
- package/release-manager/dist/bootstrap-entry.js.map +0 -1
- package/release-manager/dist/i18n.d.ts +0 -6
- package/release-manager/dist/i18n.d.ts.map +0 -1
- package/release-manager/dist/i18n.js.map +0 -1
- package/release-manager/dist/index.d.ts +0 -7
- package/release-manager/dist/index.d.ts.map +0 -1
- package/release-manager/dist/index.js +0 -656
- package/release-manager/dist/index.js.map +0 -1
- package/release-manager/dist/installer.d.ts +0 -629
- package/release-manager/dist/installer.d.ts.map +0 -1
- package/release-manager/dist/installer.js.map +0 -1
- package/release-manager/dist/installers/codex-host-installer.d.ts +0 -39
- package/release-manager/dist/installers/codex-host-installer.d.ts.map +0 -1
- package/release-manager/dist/installers/codex-host-installer.js.map +0 -1
- package/release-manager/dist/installers/index.d.ts +0 -51
- package/release-manager/dist/installers/index.d.ts.map +0 -1
- package/release-manager/dist/installers/index.js.map +0 -1
- package/release-manager/dist/installers/openclaw-host-installer.d.ts +0 -14
- package/release-manager/dist/installers/openclaw-host-installer.d.ts.map +0 -1
- package/release-manager/dist/installers/openclaw-host-installer.js.map +0 -1
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts +0 -335
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts.map +0 -1
- package/release-manager/dist/installers/workbuddy-host-installer.js.map +0 -1
- package/release-manager/dist/mvp-config.d.ts +0 -233
- package/release-manager/dist/mvp-config.d.ts.map +0 -1
- package/release-manager/dist/mvp-config.js.map +0 -1
- package/release-manager/dist/prompts.d.ts +0 -43
- package/release-manager/dist/prompts.d.ts.map +0 -1
- package/release-manager/dist/prompts.js +0 -268
- package/release-manager/dist/prompts.js.map +0 -1
- package/release-manager/dist/skill-language.d.ts +0 -32
- package/release-manager/dist/skill-language.d.ts.map +0 -1
- package/release-manager/dist/skill-language.js.map +0 -1
- package/release-manager/dist/uninstaller.d.ts +0 -68
- package/release-manager/dist/uninstaller.d.ts.map +0 -1
- package/release-manager/dist/uninstaller.js +0 -746
- package/release-manager/dist/uninstaller.js.map +0 -1
- package/release-manager/dist/update/apply-payload.d.ts +0 -143
- package/release-manager/dist/update/apply-payload.d.ts.map +0 -1
- package/release-manager/dist/update/apply-payload.js.map +0 -1
- package/release-manager/dist/update/atomic-file.d.ts +0 -35
- package/release-manager/dist/update/atomic-file.d.ts.map +0 -1
- package/release-manager/dist/update/atomic-file.js.map +0 -1
- package/release-manager/dist/update/bootstrap-executor.d.ts +0 -21
- package/release-manager/dist/update/bootstrap-executor.d.ts.map +0 -1
- package/release-manager/dist/update/bootstrap-executor.js.map +0 -1
- package/release-manager/dist/update/bootstrap-protocol.d.ts +0 -56
- package/release-manager/dist/update/bootstrap-protocol.d.ts.map +0 -1
- package/release-manager/dist/update/bootstrap-protocol.js.map +0 -1
- package/release-manager/dist/update/channel-metadata.d.ts +0 -28
- package/release-manager/dist/update/channel-metadata.d.ts.map +0 -1
- package/release-manager/dist/update/channel-metadata.js.map +0 -1
- package/release-manager/dist/update/channel-promotion.d.ts +0 -39
- package/release-manager/dist/update/channel-promotion.d.ts.map +0 -1
- package/release-manager/dist/update/channel-promotion.js +0 -55
- package/release-manager/dist/update/channel-promotion.js.map +0 -1
- package/release-manager/dist/update/console-surface.d.ts +0 -19
- package/release-manager/dist/update/console-surface.d.ts.map +0 -1
- package/release-manager/dist/update/console-surface.js.map +0 -1
- package/release-manager/dist/update/data-compatibility.d.ts +0 -35
- package/release-manager/dist/update/data-compatibility.d.ts.map +0 -1
- package/release-manager/dist/update/data-compatibility.js +0 -45
- package/release-manager/dist/update/data-compatibility.js.map +0 -1
- package/release-manager/dist/update/install-layout.d.ts +0 -105
- package/release-manager/dist/update/install-layout.d.ts.map +0 -1
- package/release-manager/dist/update/install-layout.js.map +0 -1
- package/release-manager/dist/update/product-identity.d.ts +0 -70
- package/release-manager/dist/update/product-identity.d.ts.map +0 -1
- package/release-manager/dist/update/product-identity.js.map +0 -1
- package/release-manager/dist/update/release-asset-manifest.d.ts +0 -31
- package/release-manager/dist/update/release-asset-manifest.d.ts.map +0 -1
- package/release-manager/dist/update/release-asset-manifest.js.map +0 -1
- package/release-manager/dist/update/release-identity.d.ts +0 -33
- package/release-manager/dist/update/release-identity.d.ts.map +0 -1
- package/release-manager/dist/update/release-identity.js.map +0 -1
- package/release-manager/dist/update/release-manager-authority.d.ts +0 -39
- package/release-manager/dist/update/release-manager-authority.d.ts.map +0 -1
- package/release-manager/dist/update/release-manager-authority.js.map +0 -1
- package/release-manager/dist/update/release-manager.d.ts +0 -156
- package/release-manager/dist/update/release-manager.d.ts.map +0 -1
- package/release-manager/dist/update/release-manager.js.map +0 -1
- package/release-manager/dist/update/release-metadata-publisher.d.ts +0 -199
- package/release-manager/dist/update/release-metadata-publisher.d.ts.map +0 -1
- package/release-manager/dist/update/release-metadata-publisher.js +0 -478
- package/release-manager/dist/update/release-metadata-publisher.js.map +0 -1
- package/release-manager/dist/update/release-metadata-source.d.ts +0 -85
- package/release-manager/dist/update/release-metadata-source.d.ts.map +0 -1
- package/release-manager/dist/update/release-metadata-source.js.map +0 -1
- package/release-manager/dist/update/release-metadata.d.ts +0 -60
- package/release-manager/dist/update/release-metadata.d.ts.map +0 -1
- package/release-manager/dist/update/release-metadata.js.map +0 -1
- package/release-manager/dist/update/release-policy.d.ts +0 -51
- package/release-manager/dist/update/release-policy.d.ts.map +0 -1
- package/release-manager/dist/update/release-policy.js.map +0 -1
- package/release-manager/dist/update/rollback-policy.d.ts +0 -56
- package/release-manager/dist/update/rollback-policy.d.ts.map +0 -1
- package/release-manager/dist/update/rollback-policy.js +0 -61
- package/release-manager/dist/update/rollback-policy.js.map +0 -1
- package/release-manager/dist/update/transaction-journal.d.ts +0 -212
- package/release-manager/dist/update/transaction-journal.d.ts.map +0 -1
- package/release-manager/dist/update/transaction-journal.js.map +0 -1
- package/release-manager/dist/update/trust-metadata.d.ts +0 -55
- package/release-manager/dist/update/trust-metadata.d.ts.map +0 -1
- package/release-manager/dist/update/trust-metadata.js.map +0 -1
- package/release-manager/dist/update/trust-root-provisioning.d.ts +0 -99
- package/release-manager/dist/update/trust-root-provisioning.d.ts.map +0 -1
- package/release-manager/dist/update/trust-root-provisioning.js.map +0 -1
- package/release-manager/dist/update/update-history.d.ts +0 -46
- package/release-manager/dist/update/update-history.d.ts.map +0 -1
- package/release-manager/dist/update/update-history.js +0 -123
- package/release-manager/dist/update/update-history.js.map +0 -1
- package/release-manager/dist/utils/config-file-io.d.ts +0 -34
- package/release-manager/dist/utils/config-file-io.d.ts.map +0 -1
- package/release-manager/dist/utils/config-file-io.js.map +0 -1
- package/release-manager/dist/utils/env.d.ts +0 -94
- package/release-manager/dist/utils/env.d.ts.map +0 -1
- package/release-manager/dist/utils/env.js.map +0 -1
- package/release-manager/dist/utils/logger.d.ts +0 -15
- package/release-manager/dist/utils/logger.d.ts.map +0 -1
- package/release-manager/dist/utils/logger.js.map +0 -1
- package/release-manager/dist/utils/workspace-divergence.d.ts +0 -36
- package/release-manager/dist/utils/workspace-divergence.d.ts.map +0 -1
- package/release-manager/dist/utils/workspace-divergence.js.map +0 -1
|
@@ -1,602 +0,0 @@
|
|
|
1
|
-
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect, useCallback, useRef } from "react";
|
|
3
|
-
import { useParams, useNavigate, useLocation, Link } from "react-router-dom";
|
|
4
|
-
import { useTranslation } from "react-i18next";
|
|
5
|
-
import { toast } from "sonner";
|
|
6
|
-
import { PageShell } from "../../components/layout/page-shell.js";
|
|
7
|
-
import { PageLoading } from "../../components/layout/page-loading.js";
|
|
8
|
-
import { SectionTitle } from "../../components/layout/section-title.js";
|
|
9
|
-
import { Button } from "../../components/ui/button.js";
|
|
10
|
-
import { fetchPrincipleDetail, fetchApprovalsGrouped, fetchLifecycleMetrics, fetchPrincipleTrajectory, fetchPrincipleGovernance, fetchPrincipleReceipts, fetchEvidenceAudit, fetchOwnerDecisionView, disableActivation, } from "../../api.js";
|
|
11
|
-
import { ApprovalSubjectReading } from "../focus/ApprovalSubjectReading.js";
|
|
12
|
-
import { ReceiptCoverageDisclosure, getReceiptSourceStatusLabelKey } from "../../components/receipts/ReceiptCoverageDisclosure.js";
|
|
13
|
-
import { formatDate } from "../../utils/format-date.js";
|
|
14
|
-
import { localizeAggregatedBlocker } from "../../utils/blocker-localization.js";
|
|
15
|
-
import { groupByReasonCode, formatGroupedReasonLine } from "../../utils/attention-presentation.js";
|
|
16
|
-
import { splitReadingTitleBody, truncateByCodePoints } from "../../utils/reading-layout.js";
|
|
17
|
-
import { IS_DEV } from "../../utils/runtime-mode.js";
|
|
18
|
-
// ── Runtime validation (H section) ──────────────────────────────────────────
|
|
19
|
-
function isString(v) {
|
|
20
|
-
return typeof v === "string";
|
|
21
|
-
}
|
|
22
|
-
function isRecord(v) {
|
|
23
|
-
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
24
|
-
}
|
|
25
|
-
function safeStringArray(v) {
|
|
26
|
-
if (!Array.isArray(v))
|
|
27
|
-
return [];
|
|
28
|
-
return v.filter(isString);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Validate and normalize a PrincipleDetail from untrusted network data.
|
|
32
|
-
* Returns a normalized object with safe defaults for all fields the page
|
|
33
|
-
* actually accesses. Never returns null for individual fields — only for
|
|
34
|
-
* completely unparseable top-level structures.
|
|
35
|
-
*/
|
|
36
|
-
function validatePrincipleDetail(data) {
|
|
37
|
-
if (!isRecord(data))
|
|
38
|
-
return null;
|
|
39
|
-
if (!Object.hasOwn(data, "principle") || !isRecord(data.principle))
|
|
40
|
-
return null;
|
|
41
|
-
const raw = data.principle;
|
|
42
|
-
// Required fields — fail loud if missing
|
|
43
|
-
if (!Object.hasOwn(raw, "id") || !isString(raw.id))
|
|
44
|
-
return null;
|
|
45
|
-
if (!Object.hasOwn(raw, "text") || !isString(raw.text))
|
|
46
|
-
return null;
|
|
47
|
-
if (!Object.hasOwn(raw, "status") || !isString(raw.status))
|
|
48
|
-
return null;
|
|
49
|
-
// Normalize fields the page accesses with safe defaults
|
|
50
|
-
const normalized = {
|
|
51
|
-
...raw,
|
|
52
|
-
triggerPattern: typeof raw.triggerPattern === "string" ? raw.triggerPattern : "",
|
|
53
|
-
action: typeof raw.action === "string" ? raw.action : "",
|
|
54
|
-
derivedFromPainIds: safeStringArray(raw.derivedFromPainIds),
|
|
55
|
-
rules: Array.isArray(raw.rules) ? raw.rules : [],
|
|
56
|
-
};
|
|
57
|
-
return { principle: normalized };
|
|
58
|
-
}
|
|
59
|
-
function validateApprovalsGrouped(data) {
|
|
60
|
-
if (!isRecord(data))
|
|
61
|
-
return null;
|
|
62
|
-
if (!Object.hasOwn(data, "groups") || !Array.isArray(data.groups))
|
|
63
|
-
return null;
|
|
64
|
-
for (const g of data.groups) {
|
|
65
|
-
if (!isRecord(g))
|
|
66
|
-
return null;
|
|
67
|
-
if (!Object.hasOwn(g, "principleId") || !isString(g.principleId))
|
|
68
|
-
return null;
|
|
69
|
-
if (!Object.hasOwn(g, "status") || !isString(g.status))
|
|
70
|
-
return null;
|
|
71
|
-
if (!Object.hasOwn(g, "records") || !Array.isArray(g.records))
|
|
72
|
-
return null;
|
|
73
|
-
for (const r of g.records) {
|
|
74
|
-
if (!isRecord(r))
|
|
75
|
-
return null;
|
|
76
|
-
if (!Object.hasOwn(r, "id") || !isString(r.id))
|
|
77
|
-
return null;
|
|
78
|
-
if (!Object.hasOwn(r, "channel") || !isString(r.channel))
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return data;
|
|
83
|
-
}
|
|
84
|
-
function validateLifecycleMetrics(data) {
|
|
85
|
-
if (!isRecord(data))
|
|
86
|
-
return null;
|
|
87
|
-
if (!Object.hasOwn(data, "adherence") || !isRecord(data.adherence))
|
|
88
|
-
return null;
|
|
89
|
-
const a = data.adherence;
|
|
90
|
-
if (!Object.hasOwn(a, "insufficientData") || typeof a.insufficientData !== "boolean")
|
|
91
|
-
return null;
|
|
92
|
-
if (!Object.hasOwn(a, "note") || !isString(a.note))
|
|
93
|
-
return null;
|
|
94
|
-
// rate can be number or null
|
|
95
|
-
if (Object.hasOwn(a, "rate") && a.rate !== null && typeof a.rate !== "number")
|
|
96
|
-
return null;
|
|
97
|
-
if (!Object.hasOwn(data, "ruleMetrics") || !Array.isArray(data.ruleMetrics))
|
|
98
|
-
return null;
|
|
99
|
-
return data;
|
|
100
|
-
}
|
|
101
|
-
// ── Trajectory stage labels (i18n key mapping) ─────────────────────────────
|
|
102
|
-
const STAGE_LABEL_KEYS = {
|
|
103
|
-
evidence: "principles.detail.stageEvidence",
|
|
104
|
-
diagnosis: "principles.detail.stageDiagnosis",
|
|
105
|
-
proposal: "principles.detail.stageProposal",
|
|
106
|
-
review: "principles.detail.stageReview",
|
|
107
|
-
deploy: "principles.detail.stageDeploy",
|
|
108
|
-
behavior: "principles.detail.stageBehavior",
|
|
109
|
-
};
|
|
110
|
-
// ── Component ───────────────────────────────────────────────────────────────
|
|
111
|
-
// SPEC-PD-UIUX-001 R1: the headline must agree with BOTH verified counts.
|
|
112
|
-
// effect>0 → effect headline (records exist; no permanence claim)
|
|
113
|
-
// effect=0,presence>0 → "injections recorded, no effect records yet"
|
|
114
|
-
// effect=0,presence=0 → "nothing observed within the current retention window"
|
|
115
|
-
// Presence is never inferred from approval/activation, and effect is never
|
|
116
|
-
// inferred from presence — the degraded branch (status≠ok) handles
|
|
117
|
-
// "cannot be confirmed" separately.
|
|
118
|
-
export function getReceiptPresentation(effectCount, presenceCount) {
|
|
119
|
-
if (effectCount > 0) {
|
|
120
|
-
return {
|
|
121
|
-
headlineKey: 'principles.detail.receipts.headline',
|
|
122
|
-
presenceMissing: presenceCount === 0,
|
|
123
|
-
showZeroEffectExplanation: false,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
if (presenceCount > 0) {
|
|
127
|
-
return {
|
|
128
|
-
headlineKey: 'principles.detail.receipts.headlinePresence',
|
|
129
|
-
presenceMissing: false,
|
|
130
|
-
showZeroEffectExplanation: true,
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
headlineKey: 'principles.detail.receipts.headlineNone',
|
|
135
|
-
presenceMissing: false,
|
|
136
|
-
showZeroEffectExplanation: true,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
export const GOVERNANCE_BLOCK_I18N_KEYS = {
|
|
140
|
-
recoveryReason: 'principles.detail.governance.reason.recovery_required',
|
|
141
|
-
recoveryNextAction: 'principles.detail.governance.next.inspect_recovery',
|
|
142
|
-
noDecisionReason: 'principles.detail.governance.actionsNotAuthorized',
|
|
143
|
-
nextActionLabel: 'principles.detail.governance.nextActionLabel',
|
|
144
|
-
};
|
|
145
|
-
/**
|
|
146
|
-
* Returns `null` when decision controls may render; otherwise the reason they
|
|
147
|
-
* must stay hidden.
|
|
148
|
-
*/
|
|
149
|
-
export function deriveGovernanceControlBlock(input) {
|
|
150
|
-
const { governance, governanceUnavailable } = input;
|
|
151
|
-
if (governance === null) {
|
|
152
|
-
// Flag-off keeps the pre-projection experience: controls stay available and
|
|
153
|
-
// no blocked notice is shown (ERR-102: disabled ≠ unavailable).
|
|
154
|
-
if (governanceUnavailable === null)
|
|
155
|
-
return null;
|
|
156
|
-
return governanceUnavailable.nextAction === undefined
|
|
157
|
-
? { source: 'server', reason: governanceUnavailable.reason }
|
|
158
|
-
: { source: 'server', reason: governanceUnavailable.reason, nextAction: governanceUnavailable.nextAction };
|
|
159
|
-
}
|
|
160
|
-
if (governance.attention.primary === 'owner_required')
|
|
161
|
-
return null;
|
|
162
|
-
if (governance.attention.primary === 'recovery_required') {
|
|
163
|
-
return {
|
|
164
|
-
source: 'i18n',
|
|
165
|
-
reasonKey: GOVERNANCE_BLOCK_I18N_KEYS.recoveryReason,
|
|
166
|
-
nextActionKey: GOVERNANCE_BLOCK_I18N_KEYS.recoveryNextAction,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
return { source: 'i18n', reasonKey: GOVERNANCE_BLOCK_I18N_KEYS.noDecisionReason };
|
|
170
|
-
}
|
|
171
|
-
export function narrativeTexts(field) {
|
|
172
|
-
if (field.status === 'known' && Array.isArray(field.value)) {
|
|
173
|
-
const texts = [];
|
|
174
|
-
for (const item of field.value) {
|
|
175
|
-
if (isRecord(item) && isString(item.text))
|
|
176
|
-
texts.push(item.text);
|
|
177
|
-
}
|
|
178
|
-
return { status: 'known', texts };
|
|
179
|
-
}
|
|
180
|
-
const reason = isRecord(field.reason) && isString(field.reason.ownerText) ? field.reason.ownerText : '';
|
|
181
|
-
return { status: 'unknown', reason };
|
|
182
|
-
}
|
|
183
|
-
/** Resolves the concrete mutation target id for an action (never from URL). */
|
|
184
|
-
export function actionTargetId(action, kind) {
|
|
185
|
-
const ref = action.targetRefs.find((target) => target.kind === kind);
|
|
186
|
-
return ref?.id ?? null;
|
|
187
|
-
}
|
|
188
|
-
// Codex review P2 fix (localization): the decision panel's CHROME (action
|
|
189
|
-
// labels, next action, blocker headline) localizes in the client via stable
|
|
190
|
-
// semantic codes; narrative CONTENT (artifact-derived text) stays in its
|
|
191
|
-
// source language — the model-generated material cannot be translated by a
|
|
192
|
-
// key lookup, so a full locale-carried response remains a follow-up.
|
|
193
|
-
const ACTION_LABEL_KEY = {
|
|
194
|
-
approve: 'principles.detail.ownerDecision.actionLabel.approve',
|
|
195
|
-
reject: 'principles.detail.ownerDecision.actionLabel.reject',
|
|
196
|
-
edit_approval: 'principles.detail.ownerDecision.actionLabel.edit_approval',
|
|
197
|
-
disable: 'principles.detail.ownerDecision.actionLabel.disable',
|
|
198
|
-
};
|
|
199
|
-
export function localizeActionLabel(action, t) {
|
|
200
|
-
const key = ACTION_LABEL_KEY[action.semantic];
|
|
201
|
-
if (key === undefined)
|
|
202
|
-
return action.label;
|
|
203
|
-
const localized = t(key, { defaultValue: '' });
|
|
204
|
-
return localized === '' ? action.label : localized;
|
|
205
|
-
}
|
|
206
|
-
export function localizeNextAction(code, ownerText, t) {
|
|
207
|
-
const localized = t(`principles.detail.ownerDecision.next.${code}`, { defaultValue: '' });
|
|
208
|
-
return localized === '' ? ownerText : localized;
|
|
209
|
-
}
|
|
210
|
-
const DECISION_STATE_LABEL_KEY = {
|
|
211
|
-
needs_owner_decision: 'principles.detail.ownerDecision.state.needs_owner_decision',
|
|
212
|
-
processing: 'principles.detail.ownerDecision.state.processing',
|
|
213
|
-
blocked: 'principles.detail.ownerDecision.state.blocked',
|
|
214
|
-
recovery_needed: 'principles.detail.ownerDecision.state.recovery_needed',
|
|
215
|
-
decided: 'principles.detail.ownerDecision.state.decided',
|
|
216
|
-
no_action: 'principles.detail.ownerDecision.state.no_action',
|
|
217
|
-
};
|
|
218
|
-
export function PrincipleDetailPage() {
|
|
219
|
-
const { t, i18n } = useTranslation("pages");
|
|
220
|
-
const { id } = useParams();
|
|
221
|
-
const navigate = useNavigate();
|
|
222
|
-
const location = useLocation();
|
|
223
|
-
const navigationState = location.state;
|
|
224
|
-
const requestedReturn = navigationState !== null && typeof navigationState === 'object' && Object.hasOwn(navigationState, 'returnTo') ? Reflect.get(navigationState, 'returnTo') : null;
|
|
225
|
-
const returnTo = typeof requestedReturn === 'string' && (requestedReturn === '/principles' || requestedReturn.startsWith('/principles?') || requestedReturn === '/focus' || requestedReturn.startsWith('/focus?')) ? requestedReturn : '/principles';
|
|
226
|
-
const [principle, setPrinciple] = useState(null);
|
|
227
|
-
const [approvalGroup, setApprovalGroup] = useState(null);
|
|
228
|
-
const [approvalGroupUnavailable, setApprovalGroupUnavailable] = useState(false);
|
|
229
|
-
const [lifecycle, setLifecycle] = useState(null);
|
|
230
|
-
const [trajectory, setTrajectory] = useState(null);
|
|
231
|
-
const [governance, setGovernance] = useState(null);
|
|
232
|
-
const [governanceUnavailable, setGovernanceUnavailable] = useState(null);
|
|
233
|
-
const [ownerDecision, setOwnerDecision] = useState(null);
|
|
234
|
-
const [ownerDecisionUnavailable, setOwnerDecisionUnavailable] = useState(null);
|
|
235
|
-
const [receipts, setReceipts] = useState(null);
|
|
236
|
-
// PD v2 Phase 1: normalized intervention evidence audit (ADR-0027) — the
|
|
237
|
-
// four-query read stays a separate surface from the legacy receipt history.
|
|
238
|
-
const [evidenceAudit, setEvidenceAudit] = useState(null);
|
|
239
|
-
const [loadingEvidenceKind, setLoadingEvidenceKind] = useState(null);
|
|
240
|
-
const [loading, setLoading] = useState(true);
|
|
241
|
-
const [error, setError] = useState(null);
|
|
242
|
-
const detailEpoch = useRef(0);
|
|
243
|
-
// Decision action state — driven by backend available_actions only.
|
|
244
|
-
const [pendingAction, setPendingAction] = useState(null);
|
|
245
|
-
const [rejectReason, setRejectReason] = useState("");
|
|
246
|
-
const [newArtifactId, setNewArtifactId] = useState("");
|
|
247
|
-
const [approveNote, setApproveNote] = useState("");
|
|
248
|
-
const [actionLoading, setActionLoading] = useState(false);
|
|
249
|
-
// Evidence ID copy state (Wave 6: stop showing raw UUIDs as primary content)
|
|
250
|
-
const [evidenceCopied, setEvidenceCopied] = useState(false);
|
|
251
|
-
const [evidenceExpanded, setEvidenceExpanded] = useState(false);
|
|
252
|
-
// Fetch data
|
|
253
|
-
const loadData = useCallback(async () => {
|
|
254
|
-
if (!id)
|
|
255
|
-
return;
|
|
256
|
-
const epoch = ++detailEpoch.current;
|
|
257
|
-
setLoading(true);
|
|
258
|
-
setLoadingEvidenceKind(null);
|
|
259
|
-
setError(null);
|
|
260
|
-
setApprovalGroup(null); // Clear previous approval group to prevent stale actionability (P1)
|
|
261
|
-
setApprovalGroupUnavailable(false);
|
|
262
|
-
setGovernance(null);
|
|
263
|
-
setGovernanceUnavailable(null);
|
|
264
|
-
setOwnerDecision(null);
|
|
265
|
-
setOwnerDecisionUnavailable(null);
|
|
266
|
-
setReceipts(null);
|
|
267
|
-
setEvidenceAudit(null);
|
|
268
|
-
try {
|
|
269
|
-
const [pResult, aResult, lResult, tResult, gResult, dResult, rResult, eResult] = await Promise.all([
|
|
270
|
-
fetchPrincipleDetail(id),
|
|
271
|
-
fetchApprovalsGrouped(),
|
|
272
|
-
fetchLifecycleMetrics(id),
|
|
273
|
-
fetchPrincipleTrajectory(id),
|
|
274
|
-
fetchPrincipleGovernance(id),
|
|
275
|
-
fetchOwnerDecisionView(id),
|
|
276
|
-
fetchPrincipleReceipts(id),
|
|
277
|
-
fetchEvidenceAudit('principle', id),
|
|
278
|
-
]);
|
|
279
|
-
if (epoch !== detailEpoch.current)
|
|
280
|
-
return;
|
|
281
|
-
if (!pResult.success) {
|
|
282
|
-
setError(pResult.error ?? "Failed to load principle");
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
const pData = validatePrincipleDetail(pResult.data);
|
|
286
|
-
if (!pData) {
|
|
287
|
-
setError("Invalid principle data received");
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
setPrinciple(pData.principle);
|
|
291
|
-
const aData = aResult.success ? validateApprovalsGrouped(aResult.data) : null;
|
|
292
|
-
if (aData) {
|
|
293
|
-
const group = aData.groups.find((g) => g.principleId === id);
|
|
294
|
-
setApprovalGroup(group ?? null);
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
setApprovalGroup(null);
|
|
298
|
-
// The grouped list is the only source of pending approval records here;
|
|
299
|
-
// swallowing the failure would hide the decision surface without a word.
|
|
300
|
-
setApprovalGroupUnavailable(true);
|
|
301
|
-
}
|
|
302
|
-
const lData = lResult.success ? validateLifecycleMetrics(lResult.data) : null;
|
|
303
|
-
setLifecycle(lData);
|
|
304
|
-
// Trajectory — validated at request layer via validateTrajectoryData
|
|
305
|
-
if (tResult.success && tResult.data) {
|
|
306
|
-
setTrajectory(tResult.data);
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
setTrajectory(null);
|
|
310
|
-
}
|
|
311
|
-
if (gResult.success && gResult.data) {
|
|
312
|
-
setGovernance(gResult.data);
|
|
313
|
-
}
|
|
314
|
-
else if (!gResult.success && gResult.reason !== 'feature_disabled') {
|
|
315
|
-
setGovernanceUnavailable({ reason: gResult.error, ...(gResult.nextAction === undefined ? {} : { nextAction: gResult.nextAction }) });
|
|
316
|
-
}
|
|
317
|
-
// Owner Decision Experience v1: the canonical first layer. feature_disabled
|
|
318
|
-
// mirrors the governance flag-off path (no owner-decision data, no error).
|
|
319
|
-
if (dResult.success && dResult.data) {
|
|
320
|
-
setOwnerDecision(dResult.data);
|
|
321
|
-
}
|
|
322
|
-
else if (!dResult.success && dResult.reason !== 'feature_disabled') {
|
|
323
|
-
setOwnerDecisionUnavailable({ reason: dResult.error });
|
|
324
|
-
}
|
|
325
|
-
// PRI-533: receipt history (degraded carries reason + nextAction)
|
|
326
|
-
if (rResult.success && rResult.data) {
|
|
327
|
-
setReceipts(rResult.data);
|
|
328
|
-
}
|
|
329
|
-
else {
|
|
330
|
-
setReceipts(null);
|
|
331
|
-
}
|
|
332
|
-
// PD v2 Phase 1: evidence audit (degraded carries reason + nextAction)
|
|
333
|
-
if (eResult.success && eResult.data) {
|
|
334
|
-
setEvidenceAudit(eResult.data);
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
setEvidenceAudit(null);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
catch (err) {
|
|
341
|
-
if (epoch !== detailEpoch.current)
|
|
342
|
-
return;
|
|
343
|
-
setError(err instanceof Error ? err.message : "Unknown error");
|
|
344
|
-
setApprovalGroup(null);
|
|
345
|
-
setApprovalGroupUnavailable(true);
|
|
346
|
-
}
|
|
347
|
-
finally {
|
|
348
|
-
if (epoch === detailEpoch.current)
|
|
349
|
-
setLoading(false);
|
|
350
|
-
}
|
|
351
|
-
}, [id]);
|
|
352
|
-
useEffect(() => {
|
|
353
|
-
setPendingAction(null);
|
|
354
|
-
setRejectReason('');
|
|
355
|
-
setNewArtifactId('');
|
|
356
|
-
setApproveNote('');
|
|
357
|
-
setActionLoading(false);
|
|
358
|
-
void loadData();
|
|
359
|
-
return () => { detailEpoch.current++; };
|
|
360
|
-
}, [loadData]);
|
|
361
|
-
const loadOlderEvidence = async (kind) => {
|
|
362
|
-
if (!id || !evidenceAudit || loadingEvidenceKind)
|
|
363
|
-
return;
|
|
364
|
-
const page = evidenceAudit.pages[kind];
|
|
365
|
-
if (!page.hasMore || !page.nextCursor)
|
|
366
|
-
return;
|
|
367
|
-
setLoadingEvidenceKind(kind);
|
|
368
|
-
const epoch = detailEpoch.current;
|
|
369
|
-
try {
|
|
370
|
-
const result = await fetchEvidenceAudit('principle', id, { kind, after: page.nextCursor });
|
|
371
|
-
if (epoch !== detailEpoch.current)
|
|
372
|
-
return;
|
|
373
|
-
if (!result.success || !result.data)
|
|
374
|
-
return;
|
|
375
|
-
if (result.data.status !== 'ok') {
|
|
376
|
-
toast.error(result.data.reason ?? '读取更早的干预证据失败');
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
const section = kind === 'delivery' ? 'deliveries'
|
|
380
|
-
: kind === 'application' ? 'applications'
|
|
381
|
-
: kind === 'behavior_episode' ? 'episodes'
|
|
382
|
-
: kind === 'effect' ? 'effects' : 'outcomes';
|
|
383
|
-
setEvidenceAudit((current) => current === null ? current : ({
|
|
384
|
-
...current,
|
|
385
|
-
[section]: [...current[section], ...result.data[section]],
|
|
386
|
-
pages: { ...current.pages, [kind]: result.data.pages[kind] },
|
|
387
|
-
unresolvedReferences: [...new Map([...current.unresolvedReferences, ...result.data.unresolvedReferences]
|
|
388
|
-
.map((entry) => [`${entry.evidenceId}:${entry.field}:${entry.missingKey}`, entry])).values()],
|
|
389
|
-
}));
|
|
390
|
-
}
|
|
391
|
-
catch (err) {
|
|
392
|
-
if (epoch !== detailEpoch.current)
|
|
393
|
-
return;
|
|
394
|
-
toast.error(err instanceof Error ? err.message : '读取更早的干预证据失败');
|
|
395
|
-
}
|
|
396
|
-
finally {
|
|
397
|
-
if (epoch === detailEpoch.current)
|
|
398
|
-
setLoadingEvidenceKind(null);
|
|
399
|
-
}
|
|
400
|
-
};
|
|
401
|
-
// ── Owner decision actions (SPEC §8.4: mutation service is the authority) ─
|
|
402
|
-
// The view's actions are advisory; every submission goes through the real
|
|
403
|
-
// mutation service. On failure: show the service reason, invalidate stale
|
|
404
|
-
// actions, re-GET the view. Never auto-retry a mutation.
|
|
405
|
-
const submitOwnerAction = async (action) => {
|
|
406
|
-
if (actionLoading)
|
|
407
|
-
return;
|
|
408
|
-
if (action.semantic !== 'disable')
|
|
409
|
-
return;
|
|
410
|
-
setActionLoading(true);
|
|
411
|
-
const epoch = detailEpoch.current;
|
|
412
|
-
try {
|
|
413
|
-
let failed = false;
|
|
414
|
-
let failureDetail = '';
|
|
415
|
-
const settle = (result) => {
|
|
416
|
-
if (!result.success) {
|
|
417
|
-
failed = true;
|
|
418
|
-
failureDetail = `${result.error ?? ''}${result.nextAction ? ` ${result.nextAction}` : ''}`.trim();
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
if (action.semantic === 'disable') {
|
|
422
|
-
const activationId = actionTargetId(action, 'activation');
|
|
423
|
-
if (activationId === null) {
|
|
424
|
-
toast.error(t("principles.detail.ownerDecision.invalidTarget", { defaultValue: "动作目标缺失,无法提交。" }));
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
settle(await disableActivation(activationId));
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
430
|
-
return; // unknown semantics are never rendered; belt-and-suspenders
|
|
431
|
-
}
|
|
432
|
-
if (epoch !== detailEpoch.current)
|
|
433
|
-
return;
|
|
434
|
-
if (!failed) {
|
|
435
|
-
toast.success(t("principles.detail.ownerDecision.actionDone", { defaultValue: "操作已提交。" }));
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
// SPEC §8.4: surface the service's real refusal reason and let the
|
|
439
|
-
// fresh GET decide what is actionable now — never auto-retry.
|
|
440
|
-
toast.error(t("principles.detail.ownerDecision.actionFailed", {
|
|
441
|
-
defaultValue: "操作被拒绝:{{detail}} 可用操作已刷新,请基于最新状态重新决定。",
|
|
442
|
-
detail: failureDetail === '' ? t("principles.detail.unknownFailure", { defaultValue: "请检查服务日志。" }) : failureDetail,
|
|
443
|
-
}));
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
catch (err) {
|
|
447
|
-
if (epoch !== detailEpoch.current)
|
|
448
|
-
return;
|
|
449
|
-
toast.error(err instanceof Error ? err.message : String(err));
|
|
450
|
-
}
|
|
451
|
-
finally {
|
|
452
|
-
if (epoch === detailEpoch.current) {
|
|
453
|
-
setActionLoading(false);
|
|
454
|
-
setPendingAction(null);
|
|
455
|
-
setRejectReason("");
|
|
456
|
-
setNewArtifactId("");
|
|
457
|
-
setApproveNote("");
|
|
458
|
-
// Invalidate the stale action list and re-derive from a fresh GET.
|
|
459
|
-
await loadData();
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
};
|
|
463
|
-
// ── Render ──────────────────────────────────────────────────────────────
|
|
464
|
-
if (loading) {
|
|
465
|
-
return (_jsx(PageShell, { children: _jsx(PageLoading, { cardCount: 1, label: t("principles.loading", { defaultValue: "Loading…" }) }) }));
|
|
466
|
-
}
|
|
467
|
-
if (error || !principle) {
|
|
468
|
-
return (_jsxs(PageShell, { children: [_jsxs(Button, { variant: "ghost", onClick: () => navigate(returnTo), className: "mb-4", children: ["\u2190 ", t("principles.detail.backToList")] }), _jsxs("div", { className: "border border-danger/30 rounded-[var(--radius-md)] p-4", children: [_jsx("p", { className: "text-danger text-sm", children: error ?? t("principles.notFound") }), _jsx(Button, { variant: "outline", size: "sm", onClick: loadData, className: "mt-2", children: t("principles.retry", { defaultValue: "Retry" }) })] })] }));
|
|
469
|
-
}
|
|
470
|
-
const hasRules = principle.rules.length > 0;
|
|
471
|
-
const receiptPresentation = receipts?.status === 'ok'
|
|
472
|
-
? getReceiptPresentation(receipts.effectCount, receipts.presenceCount)
|
|
473
|
-
: null;
|
|
474
|
-
// 切片1(R2/R3/R7):标题/正文分层——h1 只承载短标题预览;known 路径的逐字
|
|
475
|
-
// 全文在下方 learned 块渲染(一次),unknown 路径在此处正文块渲染(一次)。
|
|
476
|
-
const learnedText = ownerDecision?.learnedPrinciple.status === 'known'
|
|
477
|
-
? ownerDecision.learnedPrinciple.value.text
|
|
478
|
-
: undefined;
|
|
479
|
-
const learnedKnown = learnedText !== undefined;
|
|
480
|
-
const learnedPreview = learnedText === undefined ? undefined : truncateByCodePoints(learnedText, 240);
|
|
481
|
-
const learnedTruncated = learnedPreview !== learnedText;
|
|
482
|
-
const headlineLayout = splitReadingTitleBody(learnedText ?? principle.text);
|
|
483
|
-
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsxs("div", { className: "mb-4 flex items-center justify-between", children: [_jsxs(Button, { variant: "ghost", onClick: () => navigate(returnTo), className: "-ml-2", children: ["\u2190 ", t("principles.detail.backToList")] }), IS_DEV && (_jsx(Link, { to: `/examiner?principle=${encodeURIComponent(String(id ?? ''))}`, className: "text-[13px] text-ink-3 underline decoration-dotted underline-offset-4 hover:text-ink", "data-testid": "principle-detail-examiner-link", children: t("principles.detail.examinerEntry", { defaultValue: "验证此原则的行为效果 (Examiner)" }) }))] }), _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", "data-testid": "principle-detail-title", children: headlineLayout.title }), headlineLayout.body !== null && !learnedKnown && (_jsx("div", { className: "mb-3 text-[15px] leading-relaxed text-ink whitespace-pre-wrap break-words", "data-testid": "principle-detail-body", children: headlineLayout.body })), ownerDecision !== null && ownerDecision.learnedPrinciple.status !== 'known' && (_jsx("p", { className: "text-amber text-[13px] leading-relaxed mb-3", "data-testid": "owner-decision-technical-note", children: t("principles.detail.ownerDecision.technicalOriginalNote", {
|
|
484
|
-
defaultValue: "以上为原始技术建议文本;可读的行为准则暂缺(保留原文以保证可追溯)。",
|
|
485
|
-
}) })), _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("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: () => {
|
|
486
|
-
const params = new URLSearchParams({ source: "principle_page", principleId: id ?? "" });
|
|
487
|
-
navigate(`/report-problem?${params.toString()}`);
|
|
488
|
-
}, children: t("reportProblem.entryFeedback") })] })] }), ownerDecision !== null && (_jsxs("section", { className: "mb-8", "aria-labelledby": "owner-decision-title", "data-testid": "owner-decision-view", children: [_jsx(SectionTitle, { children: t("principles.detail.ownerDecision.title", { defaultValue: "这条原则的决策视图" }) }), _jsxs("div", { className: "rounded-[var(--radius-md)] border border-gov/25 bg-gov/5 p-4", 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: "owner-decision-title", className: "text-[18px] font-semibold text-ink", children: t(DECISION_STATE_LABEL_KEY[ownerDecision.decisionState]) }), _jsx("p", { className: "mt-1 text-[13px] leading-relaxed text-ink-2", children: localizeNextAction(ownerDecision.nextAction.code, ownerDecision.nextAction.ownerText, t) })] }), _jsx("span", { "data-testid": "owner-decision-state", className: "w-fit rounded-full border border-line px-2 py-1 font-mono text-[11px] text-ink-3", children: ownerDecision.sourceReadStatus === 'complete'
|
|
489
|
-
? t("principles.detail.ownerDecision.readsComplete", { defaultValue: "本次所需数据已读取" })
|
|
490
|
-
: t("principles.detail.ownerDecision.readsPartial", { defaultValue: "部分数据源读取失败" }) })] }), _jsxs("div", { className: "mt-4", "data-testid": "owner-decision-learned", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t("principles.detail.ownerDecision.learned", { defaultValue: "Agent 学到的行为准则" }) }), ownerDecision.learnedPrinciple.status === 'known' ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "mt-1 text-ink-2 text-[15px] leading-relaxed whitespace-pre-wrap break-words", children: learnedPreview }), learnedTruncated && _jsxs("details", { className: "mt-3 text-sm text-ink-2", children: [_jsx("summary", { className: "cursor-pointer text-gov", children: t('principles.detail.fullRule') }), _jsx("p", { className: "mt-3 whitespace-pre-wrap break-words leading-relaxed", children: learnedText })] }), _jsx("p", { className: "mt-1 text-ink-4 text-[12px]", children: t("principles.detail.ownerDecision.sourceTierLabel", {
|
|
491
|
-
defaultValue: "来源:{{tier}}(未经改写)",
|
|
492
|
-
tier: t(`principles.detail.ownerDecision.tier.${ownerDecision.learnedPrinciple.value.sourceTier}`, { defaultValue: ownerDecision.learnedPrinciple.value.sourceTier }),
|
|
493
|
-
}) })] })) : (_jsx("p", { className: "mt-1 text-amber text-[13px] leading-relaxed", children: ownerDecision.learnedPrinciple.reason.ownerText }))] }), ownerDecision.decisionSubjects.some((subject) => subject.state !== 'pending') && (_jsxs("div", { className: "mt-3", "data-testid": "owner-decision-history", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t("principles.detail.ownerDecision.history", { defaultValue: "决定历史" }) }), _jsx("ul", { className: "mt-1 space-y-1 text-[13px] text-ink-2", children: ownerDecision.decisionSubjects.filter((subject) => subject.state !== 'pending').map((subject) => {
|
|
494
|
-
const decidedAt = subject.targetRefs.find((target) => target.kind === 'approval')?.recordedAt;
|
|
495
|
-
const stateKey = `principles.detail.ownerDecision.historyState.${subject.state}`;
|
|
496
|
-
return (_jsxs("li", { children: [t(stateKey, { defaultValue: subject.state }), decidedAt !== undefined ? ` · ${decidedAt.slice(0, 10)}` : '', ' · ', t(`principles.detail.ownerDecision.channel.${subject.channel}`, { defaultValue: subject.channel })] }, `hist-${subject.key}`));
|
|
497
|
-
}) })] })), _jsxs("div", { className: "mt-5 border-t border-line pt-4", "data-testid": "owner-decision-actions", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t("principles.detail.ownerDecision.decision", { defaultValue: "你的决定" }) }), ownerDecision.availableActions.length === 0 && (_jsx("p", { className: "mt-1 text-ink-3 text-[13px]", children: t("principles.detail.ownerDecision.noActions", { defaultValue: "当前没有可以执行的操作。" }) })), approvalGroupUnavailable && ownerDecision.availableActions.length > 0 && (_jsxs("div", { role: "alert", className: "mt-2 text-[13px] leading-relaxed text-amber", "data-testid": "detail-approvals-unavailable", children: [_jsx("p", { children: t('focus.workbench.approvalsUnavailable') }), _jsx("button", { type: "button", onClick: () => { void loadData(); }, className: "mt-1 text-gov underline", children: t('focus.workbench.retry') })] })), approvalGroup?.records.filter(record => record.status === 'pending').map(record => {
|
|
498
|
-
const allowedActions = ownerDecision.availableActions
|
|
499
|
-
.filter(action => actionTargetId(action, 'approval') === record.id)
|
|
500
|
-
.map(action => action.semantic)
|
|
501
|
-
.filter((semantic) => semantic === 'approve' || semantic === 'reject' || semantic === 'edit_approval');
|
|
502
|
-
// A sibling's broken revision review must not block this record;
|
|
503
|
-
// without any per-record defect the group flag still covers the
|
|
504
|
-
// "multiple versions pending" ambiguity.
|
|
505
|
-
const revisionReviewUnavailable = record.revisionReviewUnavailable
|
|
506
|
-
?? (approvalGroup.records.some(entry => entry.status === 'pending' && entry.revisionReviewUnavailable === true)
|
|
507
|
-
? false : approvalGroup.revisionReviewUnavailable);
|
|
508
|
-
return _jsxs("details", { className: "mt-4 rounded border border-line p-4", "data-testid": "detail-approval-review", children: [_jsxs("summary", { className: "cursor-pointer text-sm text-gov", children: [t('focus.workbench.proposal'), " \u00B7 ", t(`principles.detail.ownerDecision.channel.${record.channel}`, { defaultValue: record.channel })] }), _jsx("div", { className: "mt-5", children: _jsx(ApprovalSubjectReading, { principleId: principle.id, approvalId: record.id, artifactId: record.artifactId, channel: record.channel, showPrincipleLink: false, revisionReview: new Set(approvalGroup.records.filter(entry => entry.status === 'pending').map(entry => entry.artifactId)).size === 1 ? approvalGroup.revisionReview : undefined, revisionReviewUnavailable: revisionReviewUnavailable, allowedActions: allowedActions, lockedReason: ownerDecision.availableActions.some(action => actionTargetId(action, 'approval') === record.id) ? undefined : t('focus.workbench.permissionsUnknown'), onResolved: message => { toast.success(message); void loadData(); } }) })] }, record.id);
|
|
509
|
-
}), _jsx("div", { className: "mt-2 flex flex-wrap gap-3", children: ownerDecision.availableActions.filter(action => action.semantic === 'disable').map((action) => (_jsx(Button, { variant: action.semantic === 'reject' ? 'destructive' : action.semantic === 'disable' ? 'outline' : 'default', size: "sm", disabled: actionLoading, "data-action-semantic": action.semantic, onClick: () => {
|
|
510
|
-
setRejectReason("");
|
|
511
|
-
setApproveNote("");
|
|
512
|
-
setPendingAction(action);
|
|
513
|
-
}, children: localizeActionLabel(action, t) }, action.key))) }), ownerDecision.blockers.length > 0 && (_jsx("ul", { className: "mt-3 space-y-1 text-[12px] text-ink-3", children: ownerDecision.blockers.map((blocker, index) => (_jsx("li", { "data-testid": "owner-decision-blocker", children: localizeAggregatedBlocker(blocker.reason, t) }, `blk-${index}`))) })), pendingAction !== null && (_jsxs("div", { className: "border-t border-line pt-6 mt-6", "data-testid": "owner-decision-confirm", children: [_jsx(SectionTitle, { children: pendingAction.label }), _jsxs("div", { className: "mt-2 p-3 bg-gov/5 border border-gov/20 rounded-[var(--radius-md)]", children: [pendingAction.expectedConsequence.status === 'known' && (_jsx("div", { className: "mb-3", children: pendingAction.expectedConsequence.value.map((item, index) => (_jsx("p", { className: "text-ink-2 text-[13px] leading-relaxed mb-1", children: item.text }, `exp-${index}`))) })), _jsx("p", { className: "text-ink-2 text-[13px] mb-3", children: pendingAction.confirmation.text }), pendingAction.requirements.some((req) => req.name === 'newArtifactId') && (_jsxs(_Fragment, { children: [_jsx("label", { className: "block font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("principles.detail.editNewArtifactLabel", { defaultValue: "新的已验证工件 ID" }) }), _jsx("input", { type: "text", value: newArtifactId, onChange: (e) => setNewArtifactId(e.target.value), placeholder: t("principles.detail.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }), className: "w-full border border-line rounded-[var(--radius-md)] bg-surface text-ink px-3 py-2 text-[13px] mb-2 font-mono focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": t("principles.detail.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }) })] })), pendingAction.requirements.some((req) => req.name === 'reason') && (_jsxs(_Fragment, { children: [_jsx("label", { className: "block font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("principles.detail.rejectReasonLabel", { defaultValue: "拒绝原因" }) }), _jsx("textarea", { value: rejectReason, onChange: (e) => setRejectReason(e.target.value), placeholder: t("principles.detail.rejectReasonPlaceholder"), className: "w-full border border-line rounded-[var(--radius-md)] bg-surface text-ink px-3 py-2 text-[13px] min-h-[80px] resize-y focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": t("principles.detail.rejectReasonPlaceholder") })] })), pendingAction.requirements.some((req) => req.name === 'note') && (_jsxs(_Fragment, { children: [_jsx("label", { className: "block font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("principles.detail.approveNoteLabel", { defaultValue: "批准备注(可选)" }) }), _jsx("textarea", { "data-testid": "owner-decision-note", value: approveNote, onChange: (e) => setApproveNote(e.target.value), placeholder: pendingAction.requirements.find((req) => req.name === 'note')?.ownerText
|
|
514
|
-
?? t("principles.detail.approveNotePlaceholder", { defaultValue: "写下批准的理由(可留空)" }), className: "w-full border border-line rounded-[var(--radius-md)] bg-surface text-ink px-3 py-2 text-[13px] min-h-[80px] resize-y focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": t("principles.detail.approveNoteLabel", { defaultValue: "批准备注(可选)" }) })] })), _jsxs("div", { className: "flex gap-2 mt-3", children: [_jsx(Button, { variant: pendingAction.semantic === 'reject' ? 'destructive' : 'default', size: "sm", disabled: actionLoading
|
|
515
|
-
|| (pendingAction.requirements.some((req) => req.name === 'reason') && !rejectReason.trim())
|
|
516
|
-
|| (pendingAction.requirements.some((req) => req.name === 'newArtifactId') && !newArtifactId.trim()), onClick: () => {
|
|
517
|
-
const action = pendingAction;
|
|
518
|
-
void submitOwnerAction(action);
|
|
519
|
-
}, children: t("principles.detail.confirm", { defaultValue: "确认" }) }), _jsx(Button, { variant: "outline", size: "sm", onClick: () => { setPendingAction(null); setRejectReason(""); setNewArtifactId(""); setApproveNote(""); }, children: t("principles.detail.cancel") })] })] })] }))] }), _jsxs("details", { className: "mt-5 border-t border-line pt-4", "data-testid": "principle-formation-disclosure", children: [_jsx("summary", { className: "cursor-pointer text-sm text-gov", children: t('principles.detail.formationDisclosure') }), _jsxs("div", { className: "mt-4", children: [_jsx(OwnerNarrativeBlock, { testId: "owner-decision-incident", label: t("principles.detail.ownerDecision.incident", { defaultValue: "发生了什么" }), field: ownerDecision.incidentSummary }), _jsx(OwnerNarrativeBlock, { testId: "owner-decision-rationale", label: t("principles.detail.ownerDecision.rationale", { defaultValue: "为什么这么判断" }), field: ownerDecision.rationale })] })] }), _jsx(OwnerNarrativeBlock, { testId: "owner-decision-applicability", label: t("principles.detail.ownerDecision.applicability", { defaultValue: "什么时候适用" }), field: ownerDecision.applicability }), _jsx(OwnerNarrativeBlock, { testId: "owner-decision-expected", label: t("principles.detail.ownerDecision.expected", { defaultValue: "批准后会怎样(拟议行为,未部署)" }), field: ownerDecision.expectedBehavior }), ownerDecision.currentEnforcement.status === 'known' && (_jsxs("div", { className: "mt-4", "data-testid": "owner-decision-enforcement", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t("principles.detail.ownerDecision.enforcementLabel", { defaultValue: "当前实际执行" }) }), _jsx("p", { className: "mt-1 text-ink-2 text-[14px] leading-relaxed", children: ownerDecision.currentEnforcement.value?.state === 'active'
|
|
520
|
-
? t("principles.detail.ownerDecision.enforcement.active", { defaultValue: "当前有正在执行的生效方式(见下方明细)。" })
|
|
521
|
-
: ownerDecision.currentEnforcement.value?.state === 'deactivated'
|
|
522
|
-
? t("principles.detail.ownerDecision.enforcement.deactivated", { defaultValue: "此前的执行方式已停用;当前没有正在执行的生效方式。" })
|
|
523
|
-
: ownerDecision.currentEnforcement.value?.state === 'partially_active'
|
|
524
|
-
? t("principles.detail.ownerDecision.enforcement.partial", { defaultValue: "部分执行方式仍在运行(见下方明细)。" })
|
|
525
|
-
: t("principles.detail.ownerDecision.enforcement.none", { defaultValue: "这条原则当前没有生效中的执行方式。" }) }), ownerDecision.currentEnforcement.value?.items.map((item) => (_jsxs("p", { className: "mt-1 text-ink-3 text-[12px]", children: [item.mode.status === 'known' ? item.mode.value : item.channel, " · ", item.active
|
|
526
|
-
? t("principles.detail.ownerDecision.enforcement.since", { defaultValue: "生效中(自 {{since}})", since: item.since.status === 'known' ? item.since.value.slice(0, 10) : '?' })
|
|
527
|
-
: t("principles.detail.ownerDecision.enforcement.stopped", { defaultValue: "已停用" })] }, item.activationRef.id)))] })), ownerDecision.currentEnforcement.status === 'unknown' && (_jsx("p", { className: "mt-4 text-amber text-[13px]", "data-testid": "owner-decision-enforcement-unknown", children: ownerDecision.currentEnforcement.reason?.ownerText })), ownerDecision.evidenceSummary.status === 'known' && (_jsxs("div", { className: "mt-4", "data-testid": "owner-decision-evidence", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t("principles.detail.ownerDecision.evidence", { defaultValue: "行为证据" }) }), _jsx("p", { className: "mt-1 text-ink-2 text-[13px] leading-relaxed", children: ownerDecision.evidenceSummary.value?.ownerExplanation })] })), _jsxs("div", { className: "mt-4", "data-testid": "owner-decision-uncertainty", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t("principles.detail.ownerDecision.uncertainty", { defaultValue: "风险与不确定性" }) }), ownerDecision.risk.status === 'known' && (ownerDecision.risk.value?.items.length ?? 0) > 0 && (_jsx("ul", { className: "mt-1 space-y-1 text-[13px] text-ink-2", children: ownerDecision.risk.value?.items.map((item, index) => (_jsx("li", { children: item.text }, `risk-${index}`))) })), ownerDecision.risk.status === 'known' && (ownerDecision.risk.value?.items.length ?? 0) === 0 && (_jsx("p", { className: "mt-1 text-ink-3 text-[13px]", children: t("principles.detail.ownerDecision.riskNotAssessed", { defaultValue: "尚未做过风险评估;这不代表没有风险。" }) })), ownerDecision.risk.status === 'unknown' && (_jsx("p", { className: "mt-1 text-ink-3 text-[13px]", children: ownerDecision.risk.reason?.ownerText })), ownerDecision.uncertainty.status === 'known' && ownerDecision.uncertainty.value.length > 0 && (_jsx("ul", { className: "mt-2 space-y-1 text-[12px] text-ink-3", children: ownerDecision.uncertainty.value.map((item, index) => (_jsx("li", { children: item.text }, `unc-${index}`))) }))] }), _jsxs("div", { className: "mt-4", "data-testid": "owner-decision-rollback", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t("principles.detail.ownerDecision.rollback", { defaultValue: "如何停止影响" }) }), ownerDecision.rollback.status === 'known' && (_jsxs(_Fragment, { children: [_jsx("p", { className: "mt-1 text-ink-2 text-[13px] leading-relaxed", children: ownerDecision.rollback.value?.ownerText }), ownerDecision.rollback.value?.stopFuture.status === 'known' && (_jsx("ul", { className: "mt-1 space-y-1 text-[12px] text-ink-3", children: ownerDecision.rollback.value.stopFuture.value.map((item, index) => (_jsx("li", { children: item.text }, `rb-${index}`))) })), ownerDecision.rollback.value?.stopFuture.status === 'not_applicable' && (_jsx("p", { className: "mt-1 text-ink-3 text-[12px]", children: ownerDecision.rollback.value.stopFuture.reason.ownerText }))] })), ownerDecision.rollback.status === 'unknown' && (_jsx("p", { className: "mt-1 text-amber text-[13px]", children: ownerDecision.rollback.reason?.ownerText }))] })] })] })), ownerDecision === null && ownerDecisionUnavailable !== null && (_jsxs("section", { className: "mb-8", "data-testid": "owner-decision-unavailable", children: [_jsx(SectionTitle, { children: t("principles.detail.ownerDecision.title", { defaultValue: "这条原则的决策视图" }) }), _jsxs("div", { className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("p", { className: "text-ink-2 text-[13px]", children: t("principles.detail.ownerDecision.unavailable", { defaultValue: "决策视图暂时不可用,无法据此做决定。" }) }), _jsx("p", { className: "mt-1 text-ink-4 text-[12px] font-mono", children: ownerDecisionUnavailable.reason })] })] })), (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: groupByReasonCode(governance.attention.items).map(group => _jsx("li", { children: formatGroupedReasonLine(t, 'principles.detail.governance.attention', group) }, group.reasonCode)) })] })), 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: groupByReasonCode(governance.dataQuality.issues).map(group => _jsx("li", { children: formatGroupedReasonLine(t, 'principles.detail.governance.issue', group) }, group.reasonCode)) })] }))] })) : (_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: receiptPresentation?.headlineKey === 'principles.detail.receipts.headline'
|
|
528
|
-
? t(receiptPresentation.headlineKey, {
|
|
529
|
-
defaultValue: '',
|
|
530
|
-
effectCount: receipts.effectCount,
|
|
531
|
-
lastEffectAt: receipts.lastEffectAt ? formatDate(receipts.lastEffectAt, i18n.language) : '',
|
|
532
|
-
})
|
|
533
|
-
: t(receiptPresentation?.headlineKey ?? 'principles.detail.receipts.headlinePresence') }), _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 }) })] }), receiptPresentation?.showZeroEffectExplanation && (_jsx("p", { "data-testid": "receipt-history-zero-effect", className: "mt-2 text-[12px] leading-relaxed text-ink-3", children: t(receipts.presenceCount > 0
|
|
534
|
-
? 'principles.detail.receipts.zeroEffectPresence'
|
|
535
|
-
: 'principles.detail.receipts.zeroEffectNone') })), receiptPresentation?.presenceMissing && (_jsx("p", { "data-testid": "receipt-history-presence-missing", className: "mt-2 text-[12px] leading-relaxed text-ink-3", children: t('principles.detail.receipts.presenceMissingNote') })), 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') }), _jsx("div", { className: "mt-3 border-t border-line pt-3", children: _jsx(ReceiptCoverageDisclosure, { coverage: receipts.coverage }) })] })) : (_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("h3", { className: "text-[13px] font-semibold text-ink", children: i18n.t(getReceiptSourceStatusLabelKey(receipts.coverage.sourceStatus)) }), _jsx("p", { className: "mt-1 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 })] }))] })), evidenceAudit !== null && (_jsxs("section", { className: "mb-8", "aria-labelledby": "evidence-audit-title", children: [_jsx(SectionTitle, { children: t('principles.detail.evidenceAudit.title') }), evidenceAudit.status === 'ok' ? (_jsxs("div", { "data-testid": "evidence-audit", className: "rounded-[var(--radius-md)] border border-line p-4", children: [_jsx("h2", { id: "evidence-audit-title", className: "text-[15px] font-semibold text-ink", children: t('principles.detail.evidenceAudit.headline', {
|
|
536
|
-
d: evidenceAudit.deliveries.length,
|
|
537
|
-
a: evidenceAudit.applications.length,
|
|
538
|
-
e: evidenceAudit.episodes.length,
|
|
539
|
-
f: evidenceAudit.effects.length,
|
|
540
|
-
o: evidenceAudit.outcomes.length,
|
|
541
|
-
}) }), evidenceAudit.unresolvedReferences.length > 0 && (_jsx("p", { "data-testid": "evidence-audit-unresolved", className: "mt-2 text-[12px] text-amber", children: t('principles.detail.evidenceAudit.unresolved', {
|
|
542
|
-
count: evidenceAudit.unresolvedReferences.length,
|
|
543
|
-
}) })), _jsx("dl", { className: "mt-3 space-y-2 text-[13px]", children: [
|
|
544
|
-
['delivery', 'principles.detail.evidenceAudit.sectionDelivery', evidenceAudit.deliveries, 'delivery'],
|
|
545
|
-
['application', 'principles.detail.evidenceAudit.sectionApplication', evidenceAudit.applications, 'application'],
|
|
546
|
-
['episode', 'principles.detail.evidenceAudit.sectionEpisode', evidenceAudit.episodes, 'behavior_episode'],
|
|
547
|
-
['effect', 'principles.detail.evidenceAudit.sectionEffect', evidenceAudit.effects, 'effect'],
|
|
548
|
-
['outcome', 'principles.detail.evidenceAudit.sectionOutcome', evidenceAudit.outcomes, 'outcome'],
|
|
549
|
-
].map(([key, labelKey, list, recordKind]) => (_jsxs("div", { className: "border-t border-line pt-2", children: [_jsx("dt", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t(labelKey) }), _jsx("dd", { className: "mt-1", children: list.length === 0 ? (_jsx("span", { className: "text-[13px] text-ink-3", children: t('principles.detail.evidenceAudit.emptySection') })) : (_jsx("ul", { className: "space-y-1", children: list.map((record) => (_jsxs("li", { className: "flex flex-wrap items-baseline gap-2 text-[13px] text-ink-2", children: [_jsx("span", { className: "font-mono text-[11px] text-ink-4", children: record.recordedAt.slice(0, 16).replace('T', ' ') }), _jsx("span", { className: "font-mono text-[11px]", children: record.summary }), _jsx("span", { className: "min-w-0 flex-1 break-words", title: `${record.observationKey}\n${record.detail}`, children: record.detail }), record.associationStatus === 'pending_association' && (_jsx("span", { className: "font-mono text-[10px] rounded bg-amber/15 px-1.5 py-0.5 text-amber", children: t('principles.detail.evidenceAudit.pending') }))] }, record.evidenceId))) })) }), evidenceAudit.pages[recordKind].hasMore && (_jsx(Button, { variant: "ghost", size: "sm", disabled: loadingEvidenceKind !== null, onClick: () => void loadOlderEvidence(recordKind), children: loadingEvidenceKind === recordKind ? t('principles.detail.evidenceAudit.loading') : t('principles.detail.evidenceAudit.loadOlder') }))] }, key))) }), evidenceAudit.capabilityDeclarations.length > 0 && (_jsxs("details", { className: "mt-3 border-t border-line pt-3", children: [_jsx("summary", { className: "cursor-pointer font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.evidenceAudit.capabilities') }), _jsx("ul", { className: "mt-2 space-y-1", children: evidenceAudit.capabilityDeclarations.map((cap) => (_jsxs("li", { className: "text-[12px] text-ink-3", children: [_jsxs("span", { className: "font-mono", children: [cap.hostKind, " \u00B7 ", cap.capability, " \u00B7 ", cap.status] }), cap.note && _jsxs("span", { children: [" \u2014 ", cap.note] })] }, `${cap.hostKind}-${cap.capability}`))) })] })), _jsxs("details", { className: "mt-3 border-t border-line pt-3", "data-testid": "evidence-audit-technical", children: [_jsx("summary", { className: "cursor-pointer font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.evidenceAudit.technicalSummary') }), _jsx("p", { className: "mt-2 text-[11px] leading-relaxed text-ink-4", children: t('principles.detail.evidenceAudit.technicalNote') }), _jsx("ul", { className: "mt-2 space-y-1", children: [
|
|
550
|
-
['principles.detail.evidenceAudit.sectionDelivery', evidenceAudit.deliveries],
|
|
551
|
-
['principles.detail.evidenceAudit.sectionApplication', evidenceAudit.applications],
|
|
552
|
-
['principles.detail.evidenceAudit.sectionEpisode', evidenceAudit.episodes],
|
|
553
|
-
['principles.detail.evidenceAudit.sectionEffect', evidenceAudit.effects],
|
|
554
|
-
['principles.detail.evidenceAudit.sectionOutcome', evidenceAudit.outcomes],
|
|
555
|
-
].flatMap(([labelKey, list]) => list.map((record) => (_jsxs("li", { className: "text-[11px] leading-relaxed text-ink-4", children: [_jsx("span", { className: "font-mono", children: record.evidenceId }), record.sourceStatus === 'unknown' && _jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.sourceUnknown')] }), record.contentRedactedAt && _jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.contentRedacted', { date: record.contentRedactedAt.slice(0, 10) })] }), record.contentReference && (_jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.contentReference', {
|
|
556
|
-
resolution: record.contentReference.resolution === 'resolved' ? t('principles.detail.evidenceAudit.referenceResolved') : t('principles.detail.evidenceAudit.referenceUnresolved'),
|
|
557
|
-
principleId: record.contentReference.principleId,
|
|
558
|
-
artifactId: record.contentReference.artifactId ? ` · ${record.contentReference.artifactId}` : '',
|
|
559
|
-
// Review round (P2): keep the payload digest traceable —
|
|
560
|
-
// the technical note promises it.
|
|
561
|
-
payloadDigest: ` · ${t('principles.detail.evidenceAudit.payloadDigestLabel')}: ${record.contentReference.payloadDigest ?? t('principles.detail.evidenceAudit.noPayloadDigest')}`,
|
|
562
|
-
})] })), record.activationReference && (_jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.activationReference', {
|
|
563
|
-
activationId: record.activationReference.activationId,
|
|
564
|
-
activatedAt: record.activationReference.activatedAt ? ` · ${record.activationReference.activatedAt}` : '',
|
|
565
|
-
snapshotDigest: ` · ${t('principles.detail.evidenceAudit.snapshotDigestLabel')}: ${record.activationReference.sourceSnapshotDigest}`,
|
|
566
|
-
})] })), record.nativeLineage.length > 0 && _jsxs(_Fragment, { children: [" \u00B7 ", t('principles.detail.evidenceAudit.nativeLineage', { lineage: record.nativeLineage.join(' · ') })] })] }, record.evidenceId)))) })] }), _jsx("p", { className: "mt-3 text-[11px] leading-relaxed text-ink-4", children: t('principles.detail.evidenceAudit.note') })] })) : (_jsxs("div", { "data-testid": "evidence-audit-degraded", className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("h3", { className: "text-[13px] font-semibold text-ink", children: t('principles.detail.evidenceAudit.unavailable') }), _jsx("p", { className: "mt-1 text-[13px] text-ink-2", children: evidenceAudit.reason ?? '—' }), evidenceAudit.nextAction && _jsx("p", { className: "mt-1 text-[12px] text-ink-3", children: evidenceAudit.nextAction })] }))] })), _jsxs("details", { className: "mb-8 border-t border-line pt-4", "data-testid": "principle-extra-context", children: [_jsx("summary", { className: "cursor-pointer text-sm text-gov", children: t('principles.detail.extraContext') }), _jsxs("div", { className: "mt-5", children: [_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 font-mono break-all", 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", {
|
|
567
|
-
defaultValue: "已关联 {{count}} 条证据记录",
|
|
568
|
-
count: principle.derivedFromPainIds.length,
|
|
569
|
-
}) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: async () => {
|
|
570
|
-
try {
|
|
571
|
-
const summary = principle.derivedFromPainIds
|
|
572
|
-
.map((pid, i) => `pain_${i + 1}_id: ${pid}`)
|
|
573
|
-
.join("\n");
|
|
574
|
-
await navigator.clipboard.writeText(summary);
|
|
575
|
-
setEvidenceCopied(true);
|
|
576
|
-
setTimeout(() => setEvidenceCopied(false), 2000);
|
|
577
|
-
}
|
|
578
|
-
catch (error) {
|
|
579
|
-
// clipboard unavailable — expand as fallback
|
|
580
|
-
console.warn("Evidence ID copy failed; expanding technical details.", error);
|
|
581
|
-
if (!evidenceExpanded)
|
|
582
|
-
setEvidenceExpanded(true);
|
|
583
|
-
}
|
|
584
|
-
}, className: "font-mono text-[11px] h-7", children: evidenceCopied
|
|
585
|
-
? t("principles.detail.evidenceCopied", { defaultValue: "已复制" })
|
|
586
|
-
: t("principles.detail.copyEvidenceId", { defaultValue: "复制证据 ID" }) }), _jsx("button", { type: "button", onClick: () => setEvidenceExpanded((v) => !v), className: "font-mono text-[11px] text-ink-4 hover:text-ink-3 transition-colors underline-offset-2 hover:underline", children: t("principles.detail.expandTechDetails", { defaultValue: "展开技术细节" }) }), _jsx(Link, { to: "/pain", className: "font-mono text-[11px] text-gov hover:underline transition-colors", children: t("principles.detail.viewEvidenceChain", { defaultValue: "在证据链页查看 →" }) })] }), evidenceExpanded && (_jsx("div", { className: "mt-3 p-3 bg-paper-2 border border-line rounded-[var(--radius-sm)]", children: _jsx("div", { className: "grid grid-cols-[auto 1fr] gap-x-4 gap-y-2 text-[13px]", children: principle.derivedFromPainIds.map((painId, idx) => (_jsxs("div", { className: "contents", children: [_jsx("span", { className: "font-mono text-ink-4", children: t("principles.detail.evidenceIdLabel", {
|
|
587
|
-
defaultValue: "证据 {{n}} ID",
|
|
588
|
-
n: idx + 1,
|
|
589
|
-
}) }), _jsx("span", { className: "font-mono text-ink-2 break-all", children: painId })] }, `${painId}-${idx}`))) }) }))] }))] }), _jsxs("section", { className: "mb-8 border-t border-line pt-6", children: [_jsx(SectionTitle, { children: t("principles.detail.ownerReflection") }), _jsxs("div", { className: "space-y-3", children: [_jsx("div", { className: "border-l-2 border-l-gov pl-3 text-ink-2 text-[13px] leading-relaxed", children: t("principles.detail.reflectionQ1") }), _jsx("div", { className: "border-l-2 border-l-gov pl-3 text-ink-2 text-[13px] leading-relaxed", children: t("principles.detail.reflectionQ2") }), _jsx("div", { className: "border-l-2 border-l-gov pl-3 text-ink-2 text-[13px] leading-relaxed", children: t("principles.detail.reflectionQ3") })] })] })] })] }), _jsxs("details", { className: "mb-8 border border-line rounded-[var(--radius-md)]", children: [_jsx("summary", { className: "px-4 py-3 cursor-pointer font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 hover:text-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", children: t("principles.detail.trajectory") }), _jsxs("div", { className: "px-4 pb-4 border-t border-line pt-4", children: [governance !== null && (_jsxs("section", { className: "mb-6", "data-testid": "governance-timeline", children: [_jsx(SectionTitle, { children: t('principles.detail.governance.timeline') }), governance.timeline.length === 0 ? _jsx("p", { className: "text-[13px] text-ink-4", children: t('principles.detail.governance.timelineEmpty') }) : (_jsx("ol", { className: "space-y-3 border-l border-line pl-4", children: governance.timeline.map((event, index) => {
|
|
590
|
-
const derived = event.code === 'revision_requested' || event.code === 'revision_reopened';
|
|
591
|
-
return _jsxs("li", { children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "text-[13px] text-ink-2", children: t(`principles.detail.governance.timelineCode.${event.code}`, { defaultValue: event.code }) }), _jsx("span", { className: "rounded border border-line px-1.5 py-0.5 font-mono text-[10px] text-ink-4", children: t(`principles.detail.governance.${derived ? 'derived' : 'fact'}`) })] }), _jsx("p", { className: "mt-0.5 font-mono text-[11px] text-ink-4", children: event.occurredAt ?? event.recordedAt })] }, `${event.sourceRef.type}-${event.sourceRef.id}-${event.code}-${index}`);
|
|
592
|
-
}) }))] })), trajectory?.degraded && (_jsxs("div", { className: "mb-4 p-3 bg-amber/5 border border-amber/20 rounded-[var(--radius-sm)]", children: [_jsx("p", { className: "text-amber text-[12px] font-mono", children: trajectory.degraded.reason }), _jsx("p", { className: "text-ink-4 text-[11px] mt-1", children: trajectory.degraded.nextAction })] })), _jsx("div", { className: "space-y-4", children: (trajectory?.stages ?? []).length > 0 ? (trajectory.stages.map((stage) => (_jsxs("div", { className: "flex gap-4", children: [_jsx("span", { className: "font-mono text-[12px] text-ink-3 min-w-[80px]", children: t(STAGE_LABEL_KEYS[stage.key] ?? `principles.detail.stage${stage.key}`, { defaultValue: stage.key }) }), _jsx("div", { className: "flex-1", children: stage.status === 'available' ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "text-ink-2 text-[13px]", children: stage.summary }), stage.detail && (_jsx("p", { className: "text-ink-3 text-[12px] mt-0.5", children: stage.detail })), stage.timestamp && (_jsx("p", { className: "text-ink-4 text-[11px] mt-0.5 font-mono", children: stage.timestamp }))] })) : (_jsxs("p", { className: "text-ink-4 text-[13px]", children: [stage.unavailableReason ?? '—', stage.nextAction && (_jsx("span", { className: "block text-ink-4 text-[11px] mt-0.5", children: stage.nextAction }))] })) })] }, stage.key)))) : (
|
|
593
|
-
// Fallback: show loading state or no-data message
|
|
594
|
-
['evidence', 'diagnosis', 'proposal', 'review', 'deploy', 'behavior'].map((key) => (_jsxs("div", { className: "flex gap-4", children: [_jsx("span", { className: "font-mono text-[12px] text-ink-3 min-w-[80px]", children: t(STAGE_LABEL_KEYS[key] ?? `principles.detail.stage${key}`, { defaultValue: key }) }), _jsx("div", { className: "flex-1", children: _jsx("p", { className: "text-ink-4 text-[13px]", children: trajectory === null
|
|
595
|
-
? t("principles.detail.trajectoryLoadFailed", { defaultValue: "无法加载轨迹数据" })
|
|
596
|
-
: "—" }) })] }, key)))) }), hasRules && lifecycle && (_jsxs("div", { className: "mt-6 pt-4 border-t border-line", children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.lifecycleMetrics", { defaultValue: "生命周期指标" }) }), _jsx("p", { className: "text-amber text-[12px] font-mono mt-1 mb-3", children: t("principles.detail.lifecycleNote") }), lifecycle.adherence.insufficientData ? (_jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed", children: t("principles.detail.insufficientData") })) : (_jsxs("div", { children: [_jsxs("p", { className: "text-ink-2 text-[14px]", children: [t("principles.detail.adherenceRate", { defaultValue: "遵守率" }), ": ", lifecycle.adherence.rate !== null ? `${(lifecycle.adherence.rate * 100).toFixed(1)}%` : "—"] }), _jsx("p", { className: "text-ink-3 text-[12px] mt-1", children: lifecycle.adherence.note })] })), lifecycle.ruleMetrics.length > 0 && (_jsx("div", { className: "mt-3", children: lifecycle.ruleMetrics.map((rm) => (_jsxs("div", { className: "flex gap-3 text-[12px] font-mono text-ink-3", children: [_jsx("span", { children: rm.ruleId }), _jsxs("span", { children: [t("principles.detail.triggered", { defaultValue: "触发" }), ": ", rm.triggered] })] }, rm.ruleId))) }))] })), hasRules && !lifecycle && (_jsx("div", { className: "mt-6 pt-4 border-t border-line", children: _jsx("p", { className: "text-ink-3 text-[13px]", children: t("principles.detail.lifecycleLoadFailed", { defaultValue: "无法加载生命周期指标。你可以稍后重试。" }) }) }))] })] })] }) }));
|
|
597
|
-
}
|
|
598
|
-
/** Small presentational block: known narrative items or the honest unknown. */
|
|
599
|
-
function OwnerNarrativeBlock({ label, field, testId }) {
|
|
600
|
-
const rendered = narrativeTexts(field);
|
|
601
|
-
return (_jsxs("div", { className: "mt-4", "data-testid": testId, children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: label }), rendered.status === 'known' ? (rendered.texts.length > 0 ? (rendered.texts.map((text, index) => (_jsx("p", { className: "mt-1 text-ink-2 text-[14px] leading-relaxed", children: text }, `${testId}-${index}`)))) : (_jsx("p", { className: "mt-1 text-ink-4 text-[13px]", children: "\u2014" }))) : (_jsx("p", { className: "mt-1 text-ink-3 text-[13px] leading-relaxed", children: rendered.reason }))] }));
|
|
602
|
-
}
|