create-principles-disciple 1.113.0 → 1.115.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/console/dist/server/index.js +8 -0
- package/console/dist/server/models/GovernanceProjectionCollector.d.ts +16 -0
- package/console/dist/server/models/GovernanceProjectionCollector.js +540 -0
- package/console/dist/server/routes/principles.d.ts +5 -1
- package/console/dist/server/routes/principles.js +44 -1
- package/console/dist/ui/api.d.ts +3 -1
- package/console/dist/ui/api.js +5 -2
- package/console/dist/ui/i18n/en.json +82 -1
- package/console/dist/ui/i18n/zh-CN.json +82 -1
- package/console/dist/ui/pages/principles/PrincipleDetailPage.js +26 -5
- package/console/dist/ui/utils/validators.d.ts +2 -0
- package/console/dist/ui/utils/validators.js +82 -10
- package/console/dist/web/assets/app.css +16 -0
- package/console/dist/web/assets/app.js +304 -6
- package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.js +78 -0
- package/core/dist/runtime-v2/__tests__/governance-projection-contract.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/governance-projection.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/governance-projection.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/governance-projection.test.js +154 -0
- package/core/dist/runtime-v2/__tests__/governance-projection.test.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +15 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +9 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/core/dist/runtime-v2/governance-projection-contract.d.ts +721 -0
- package/core/dist/runtime-v2/governance-projection-contract.d.ts.map +1 -0
- package/core/dist/runtime-v2/governance-projection-contract.js +136 -0
- package/core/dist/runtime-v2/governance-projection-contract.js.map +1 -0
- package/core/dist/runtime-v2/governance-projection.d.ts +4 -0
- package/core/dist/runtime-v2/governance-projection.d.ts.map +1 -0
- package/core/dist/runtime-v2/governance-projection.js +176 -0
- package/core/dist/runtime-v2/governance-projection.js.map +1 -0
- package/core/dist/runtime-v2/index.d.ts +3 -0
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +2 -0
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.js +95 -0
- package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/artificer-runner.d.ts +25 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.js +37 -3
- package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/package.json +2 -2
- package/pd-cli/dist/commands/runtime-init.d.ts +6 -0
- package/pd-cli/dist/commands/runtime-init.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-init.js +127 -2
- package/pd-cli/dist/commands/runtime-init.js.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.js +6 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.js +6 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.js.map +1 -1
- package/plugin/dist/bundle.js +471 -471
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
package/console/dist/ui/api.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ApiResponse } from "../types.js";
|
|
2
2
|
import { listActiveSignalKeywords, listPendingSignalTerms, fetchKeywordStore, fetchPendingTerms, updateKeywordStore, admitPendingTerm, rejectPendingTerm } from "./utils/signal-keywords-api.js";
|
|
3
|
+
import type { OwnerGovernanceView } from '@principles/core/runtime-v2';
|
|
3
4
|
import type { FeedbackReportData, FeedbackDraftSummaryData, FeedbackDraftEnvelopeData, FeedbackChannelsData, FeedbackSubmitResultData, DeleteEnvelopeData, WorkspaceEntryData, RemovedEnvelopeData, SyncResultData, ConfigSummaryData, ConfigCatalogData, AgentBindingUpdateData, DefaultRuntimeUpdateData, RuntimeProfileMutationData, ReadinessCheckData, FeatureFlagUpdateData, OutputLanguageData, GovernanceQueueData, ActivationsData, DisableActivationData, LifecycleMetricsData, UpdateStatusData, UpdateHistoryData, ApplyUpdateResultData, RollbackResultData, ApprovalRecordData, PrinciplesListData, ApprovalsGroupedData, EvidenceChainData, TrajectoryData, IntentSummaryData, IntentDecisionRecordData, IntentDecisionResultData, IntentDecisionSummaryData, FollowUpResponseData, IntentInitResultData, IntentSaveResultData, IntentRawContentData, IntentVersionData } from "./utils/validators.js";
|
|
4
5
|
declare function getToken(): string | null;
|
|
5
6
|
declare function setToken(token: string): void;
|
|
@@ -25,6 +26,7 @@ declare function removeWorkspace(name: string): Promise<ApiResponse<RemovedEnvel
|
|
|
25
26
|
declare function syncWorkspace(name: string): Promise<ApiResponse<SyncResultData>>;
|
|
26
27
|
declare function fetchPrinciples(filter?: 'all' | 'actionable'): Promise<ApiResponse<PrinciplesListData>>;
|
|
27
28
|
declare function fetchPrincipleDetail(principleId: string): Promise<ApiResponse<unknown>>;
|
|
29
|
+
declare function fetchPrincipleGovernance(principleId: string): Promise<ApiResponse<OwnerGovernanceView>>;
|
|
28
30
|
declare function archivePrinciple(principleId: string): Promise<ApiResponse<unknown>>;
|
|
29
31
|
declare function unarchivePrinciple(principleId: string): Promise<ApiResponse<unknown>>;
|
|
30
32
|
declare function fetchPrincipleTrajectory(principleId: string): Promise<ApiResponse<TrajectoryData>>;
|
|
@@ -156,7 +158,7 @@ export interface FollowUpPayload {
|
|
|
156
158
|
candidateId?: string;
|
|
157
159
|
}
|
|
158
160
|
declare function dispatchFollowUp(decisionId: string, payload: FollowUpPayload): Promise<ApiResponse<FollowUpResponseData>>;
|
|
159
|
-
export { request, listActiveSignalKeywords, listPendingSignalTerms, fetchKeywordStore, fetchPendingTerms, updateKeywordStore, admitPendingTerm, rejectPendingTerm, getToken, setToken, clearToken, checkAuth, approveApproval, rejectApproval, editApproval, fetchPrinciples, fetchPrincipleDetail, fetchPrincipleTrajectory, archivePrinciple, unarchivePrinciple, createFeedbackReport, listFeedbackReports, getFeedbackReport, deleteFeedbackReport, fetchFeedbackChannels, submitFeedbackReport, markFeedbackReportSent, fetchConfigSummary, fetchConfigCatalog, updateAgentBinding, updateDefaultRuntime, createRuntimeProfile, updateRuntimeProfile, deleteRuntimeProfile, fetchAgentReadiness, patchFeatureFlag, fetchOutputLanguage, updateOutputLanguage, fetchWorkspaces, addWorkspace, removeWorkspace, syncWorkspace, fetchGovernanceQueue, fetchApprovalsGrouped, fetchAllActivations, disableActivation, fetchLifecycleMetrics, fetchUpdateStatus, fetchUpdateHistory, applyUpdate, applyFullUpdate, rollbackUpdate, fetchEvidenceChain, fetchIntentSummary, fetchIntentContent, createIntentTemplate, saveIntentContent, fetchIntentVersions, recordIntentDecision, listIntentDecisionsByPainId, listIntentDecisionsByTaskId, fetchIntentDecisionSummary, dispatchFollowUp, };
|
|
161
|
+
export { request, listActiveSignalKeywords, listPendingSignalTerms, fetchKeywordStore, fetchPendingTerms, updateKeywordStore, admitPendingTerm, rejectPendingTerm, getToken, setToken, clearToken, checkAuth, approveApproval, rejectApproval, editApproval, fetchPrinciples, fetchPrincipleDetail, fetchPrincipleGovernance, fetchPrincipleTrajectory, archivePrinciple, unarchivePrinciple, createFeedbackReport, listFeedbackReports, getFeedbackReport, deleteFeedbackReport, fetchFeedbackChannels, submitFeedbackReport, markFeedbackReportSent, fetchConfigSummary, fetchConfigCatalog, updateAgentBinding, updateDefaultRuntime, createRuntimeProfile, updateRuntimeProfile, deleteRuntimeProfile, fetchAgentReadiness, patchFeatureFlag, fetchOutputLanguage, updateOutputLanguage, fetchWorkspaces, addWorkspace, removeWorkspace, syncWorkspace, fetchGovernanceQueue, fetchApprovalsGrouped, fetchAllActivations, disableActivation, fetchLifecycleMetrics, fetchUpdateStatus, fetchUpdateHistory, applyUpdate, applyFullUpdate, rollbackUpdate, fetchEvidenceChain, fetchIntentSummary, fetchIntentContent, createIntentTemplate, saveIntentContent, fetchIntentVersions, recordIntentDecision, listIntentDecisionsByPainId, listIntentDecisionsByTaskId, fetchIntentDecisionSummary, dispatchFollowUp, };
|
|
160
162
|
export type { FeedbackReportData, FeedbackDraftSummaryData, FeedbackDraftEnvelopeData, FeedbackChannelsData, FeedbackSubmitResultData, DeleteEnvelopeData, WorkspaceEntryData, RemovedEnvelopeData, SyncResultData, ConfigSummaryData, ConfigCatalogData, AgentBindingUpdateData, DefaultRuntimeUpdateData, RuntimeProfileMutationData, ReadinessCheckData, FeatureFlagUpdateData, OutputLanguageData, GovernanceQueueData, ActivationsData, DisableActivationData, LifecycleMetricsData, UpdateStatusData, UpdateHistoryData, ApplyUpdateResultData, RollbackResultData, ApprovalRecordData, PrinciplesListData, ApprovalsGroupedData, EvidenceChainData, EvidenceChainRecordData, EvidenceChainStateData, TrajectoryData, TrajectoryStageData, IntentSummaryData, IntentSectionsData, IntentDocWarningData, IntentDecisionRecordData, IntentDecisionResultData, IntentDecisionSummaryData, FollowUpResponseData, LinkCandidateFollowUpData, GuideRulehostFollowUpData, GeneratePatchProposalFollowUpData, IntentVersionEntry, IntentVersionData, } from "./utils/validators.js";
|
|
161
163
|
export type { SignalKeyword, PendingSignalTerm } from "./utils/signal-keywords-types.js";
|
|
162
164
|
export type { ActivationRecordData as ActivationRecord } from "./utils/validators.js";
|
package/console/dist/ui/api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { listActiveSignalKeywords, listPendingSignalTerms, fetchKeywordStore, fetchPendingTerms, updateKeywordStore, admitPendingTerm, rejectPendingTerm, } from "./utils/signal-keywords-api.js";
|
|
2
|
-
import { validateErrorResponse, validateHeaders, validateFeedbackReport, validateFeedbackDraftsList, validateFeedbackDraftEnvelope, validateFeedbackChannels, validateFeedbackSubmitResult, validateDeleteEnvelope, validateWorkspaceEntry, validateWorkspaceList, validateRemovedEnvelope, validateSyncResult, validateConfigSummary, validateConfigCatalog, validateAgentBindingUpdate, validateDefaultRuntimeUpdate, validateRuntimeProfileMutation, validateReadinessCheck, validateFeatureFlagUpdate, validateOutputLanguage, validateGovernanceQueue, validateActivations, validateDisableActivation, validateLifecycleMetrics, validateUpdateStatus, validateUpdateHistory, validateApplyUpdateResult, validateRollbackResult, validateApprovalRecordDirect, validatePrinciplesList, validateApprovalsGrouped, validateEvidenceChain, validateTrajectoryData, validateIntentSummary, validateIntentDecisionList, validateIntentDecisionResult, validateIntentDecisionSummary, validateFollowUpResponse, validateIntentInitResult, validateIntentSaveResult, validateIntentRawContent, validateIntentVersions, } from "./utils/validators.js";
|
|
2
|
+
import { validateErrorResponse, validateHeaders, validateFeedbackReport, validateFeedbackDraftsList, validateFeedbackDraftEnvelope, validateFeedbackChannels, validateFeedbackSubmitResult, validateDeleteEnvelope, validateWorkspaceEntry, validateWorkspaceList, validateRemovedEnvelope, validateSyncResult, validateConfigSummary, validateConfigCatalog, validateAgentBindingUpdate, validateDefaultRuntimeUpdate, validateRuntimeProfileMutation, validateReadinessCheck, validateFeatureFlagUpdate, validateOutputLanguage, validateGovernanceQueue, validateActivations, validateDisableActivation, validateLifecycleMetrics, validateUpdateStatus, validateUpdateHistory, validateApplyUpdateResult, validateRollbackResult, validateApprovalRecordDirect, validatePrinciplesList, validateApprovalsGrouped, validateEvidenceChain, validateTrajectoryData, validateIntentSummary, validateIntentDecisionList, validateIntentDecisionResult, validateIntentDecisionSummary, validateFollowUpResponse, validateIntentInitResult, validateIntentSaveResult, validateIntentRawContent, validateIntentVersions, validateOwnerGovernanceView, } from "./utils/validators.js";
|
|
3
3
|
// ── Auth ──────────────────────────────────────────────────────────────────────
|
|
4
4
|
function getToken() {
|
|
5
5
|
return sessionStorage.getItem("pd_token");
|
|
@@ -119,6 +119,9 @@ async function fetchPrinciples(filter) {
|
|
|
119
119
|
async function fetchPrincipleDetail(principleId) {
|
|
120
120
|
return request(`/api/principles/${encodeURIComponent(principleId)}`);
|
|
121
121
|
}
|
|
122
|
+
async function fetchPrincipleGovernance(principleId) {
|
|
123
|
+
return request(`/api/v1/principles/${encodeURIComponent(principleId)}/governance`, undefined, validateOwnerGovernanceView);
|
|
124
|
+
}
|
|
122
125
|
async function archivePrinciple(principleId) {
|
|
123
126
|
return request(`/api/principles/${encodeURIComponent(principleId)}/archive`, {
|
|
124
127
|
method: "POST",
|
|
@@ -402,6 +405,6 @@ export { request,
|
|
|
402
405
|
// signal-keywords (UI stubs, see signal-keywords-api.ts)
|
|
403
406
|
listActiveSignalKeywords, listPendingSignalTerms, fetchKeywordStore, fetchPendingTerms, updateKeywordStore, admitPendingTerm, rejectPendingTerm,
|
|
404
407
|
// auth
|
|
405
|
-
getToken, setToken, clearToken, checkAuth, approveApproval, rejectApproval, editApproval, fetchPrinciples, fetchPrincipleDetail, fetchPrincipleTrajectory, archivePrinciple, unarchivePrinciple, createFeedbackReport, listFeedbackReports, getFeedbackReport, deleteFeedbackReport,
|
|
408
|
+
getToken, setToken, clearToken, checkAuth, approveApproval, rejectApproval, editApproval, fetchPrinciples, fetchPrincipleDetail, fetchPrincipleGovernance, fetchPrincipleTrajectory, archivePrinciple, unarchivePrinciple, createFeedbackReport, listFeedbackReports, getFeedbackReport, deleteFeedbackReport,
|
|
406
409
|
// Feedback submit ladder (Slice 3, spec §8)
|
|
407
410
|
fetchFeedbackChannels, submitFeedbackReport, markFeedbackReportSent, fetchConfigSummary, fetchConfigCatalog, updateAgentBinding, updateDefaultRuntime, createRuntimeProfile, updateRuntimeProfile, deleteRuntimeProfile, fetchAgentReadiness, patchFeatureFlag, fetchOutputLanguage, updateOutputLanguage, fetchWorkspaces, addWorkspace, removeWorkspace, syncWorkspace, fetchGovernanceQueue, fetchApprovalsGrouped, fetchAllActivations, disableActivation, fetchLifecycleMetrics, fetchUpdateStatus, fetchUpdateHistory, applyUpdate, applyFullUpdate, rollbackUpdate, fetchEvidenceChain, fetchIntentSummary, fetchIntentContent, createIntentTemplate, saveIntentContent, fetchIntentVersions, recordIntentDecision, listIntentDecisionsByPainId, listIntentDecisionsByTaskId, fetchIntentDecisionSummary, dispatchFollowUp, };
|
|
@@ -461,7 +461,88 @@
|
|
|
461
461
|
"reasonAlreadyHandled": "Already handled",
|
|
462
462
|
"reasonNoRecords": "No pending approval records",
|
|
463
463
|
"reasonUnsupportedChannel": "Not a supported channel in the current version",
|
|
464
|
-
"unactionableReasonPrefix": "Unactionable reason: "
|
|
464
|
+
"unactionableReasonPrefix": "Unactionable reason: ",
|
|
465
|
+
"governance": {
|
|
466
|
+
"title": "Governance status",
|
|
467
|
+
"principleState": "Principle state",
|
|
468
|
+
"process": "Current stage",
|
|
469
|
+
"automation": "Automation",
|
|
470
|
+
"nextAction": "Next safe action",
|
|
471
|
+
"blockers": "Needs attention",
|
|
472
|
+
"uncertainty": "Evidence uncertainty",
|
|
473
|
+
"provenance": "Canonical evidence references",
|
|
474
|
+
"timeline": "Governance timeline",
|
|
475
|
+
"timelineEmpty": "No governance events are available yet.",
|
|
476
|
+
"unavailable": "Governance view unavailable",
|
|
477
|
+
"unavailableReason": "The governance evidence could not be validated or loaded safely.",
|
|
478
|
+
"unavailableNextAction": "Refresh once. If this persists, inspect the Console diagnostics before taking an approval action.",
|
|
479
|
+
"none": "None",
|
|
480
|
+
"fact": "Fact",
|
|
481
|
+
"derived": "Derived",
|
|
482
|
+
"actionsNotAuthorized": "No current Owner decision is required.",
|
|
483
|
+
"confidence": { "strong": "Source-backed", "degraded": "Incomplete evidence" },
|
|
484
|
+
"state": { "candidate": "Candidate", "active": "Active", "archived": "Archived", "deprecated": "Deprecated", "probation": "Probation" },
|
|
485
|
+
"stage": { "generating": "Generating", "reviewing": "Reviewing", "revising": "Revising", "approval": "Approval", "activation": "Activation" },
|
|
486
|
+
"automationState": { "idle": "Idle", "queued": "Queued", "running": "Running", "retry_scheduled": "Retry scheduled", "stalled": "Stalled" },
|
|
487
|
+
"headline": {
|
|
488
|
+
"owner_decision": "Your decision is needed",
|
|
489
|
+
"recovery": "Runtime recovery is needed",
|
|
490
|
+
"revision": "PD is revising this principle",
|
|
491
|
+
"processing": "PD is processing this principle",
|
|
492
|
+
"active": "This principle is active",
|
|
493
|
+
"unavailable": "Governance evidence is incomplete",
|
|
494
|
+
"recorded": "Principle recorded"
|
|
495
|
+
},
|
|
496
|
+
"reason": {
|
|
497
|
+
"approval_pending": "A source-backed approval is waiting for your review.",
|
|
498
|
+
"recovery_required": "The current processing frontier cannot continue automatically.",
|
|
499
|
+
"automatic_revision": "A revision or retry is already in progress.",
|
|
500
|
+
"processing": "The current source-backed task is still running or queued.",
|
|
501
|
+
"activation_active": "At least one validated activation channel is active.",
|
|
502
|
+
"data_incomplete": "Available records cannot establish a complete governance view.",
|
|
503
|
+
"no_current_process": "No current processing or Owner action is recorded."
|
|
504
|
+
},
|
|
505
|
+
"next": {
|
|
506
|
+
"review": "Review the existing approval actions below.",
|
|
507
|
+
"inspect_recovery": "Inspect the blocker evidence; do not approve until Runtime recovers.",
|
|
508
|
+
"wait": "No action is needed now. Wait for PD to finish the current work.",
|
|
509
|
+
"monitor": "No action is needed. Monitor the active behavior channel.",
|
|
510
|
+
"inspect_data": "Inspect the evidence diagnostics and repair the referenced durable record.",
|
|
511
|
+
"none": "No action is needed."
|
|
512
|
+
},
|
|
513
|
+
"attention": {
|
|
514
|
+
"approval_pending": "Approval pending",
|
|
515
|
+
"task_failed": "Current Runtime task failed",
|
|
516
|
+
"human_review_required": "Runtime requested human recovery review",
|
|
517
|
+
"revision_not_materialized": "Requested revision was not materialized",
|
|
518
|
+
"verdict_missing": "Automated review finished without a durable verdict"
|
|
519
|
+
},
|
|
520
|
+
"issue": {
|
|
521
|
+
"lineage_not_available": "Canonical lineage is not available yet.",
|
|
522
|
+
"lease_expired_unrecovered": "The current task lease is missing or expired.",
|
|
523
|
+
"ledger_activation_mismatch": "Ledger and activation records disagree.",
|
|
524
|
+
"weak_fact_ignored": "A weak fact was excluded from current authority.",
|
|
525
|
+
"lineage_conflict": "Conflicting lineage evidence was excluded.",
|
|
526
|
+
"lineage_cycle": "A lineage cycle prevents authoritative projection.",
|
|
527
|
+
"lineage_limit_exceeded": "The lineage exceeded the safe projection bound.",
|
|
528
|
+
"metadata_malformed": "A durable record is malformed and was excluded.",
|
|
529
|
+
"timestamp_invalid": "A durable record has an invalid timestamp.",
|
|
530
|
+
"source_unavailable": "The Runtime governance source is unavailable."
|
|
531
|
+
},
|
|
532
|
+
"timelineCode": {
|
|
533
|
+
"pain_created": "Pain evidence recorded",
|
|
534
|
+
"candidate_generated": "Candidate generated",
|
|
535
|
+
"review_started": "Automated review started",
|
|
536
|
+
"revision_requested": "Revision requested",
|
|
537
|
+
"revision_reopened": "Revision task reopened",
|
|
538
|
+
"approved": "Owner approved",
|
|
539
|
+
"rejected": "Owner rejected",
|
|
540
|
+
"activated": "Channel activated",
|
|
541
|
+
"deactivated": "Channel deactivated",
|
|
542
|
+
"failed": "Runtime task failed",
|
|
543
|
+
"human_review": "Human recovery review requested"
|
|
544
|
+
}
|
|
545
|
+
}
|
|
465
546
|
}
|
|
466
547
|
},
|
|
467
548
|
"activation": {
|
|
@@ -461,7 +461,88 @@
|
|
|
461
461
|
"reasonAlreadyHandled": "已处理",
|
|
462
462
|
"reasonNoRecords": "暂无待审批记录",
|
|
463
463
|
"reasonUnsupportedChannel": "当前版本暂不支持该通道",
|
|
464
|
-
"unactionableReasonPrefix": "不可操作原因: "
|
|
464
|
+
"unactionableReasonPrefix": "不可操作原因: ",
|
|
465
|
+
"governance": {
|
|
466
|
+
"title": "治理状态",
|
|
467
|
+
"principleState": "原则状态",
|
|
468
|
+
"process": "当前阶段",
|
|
469
|
+
"automation": "自动化状态",
|
|
470
|
+
"nextAction": "下一步安全动作",
|
|
471
|
+
"blockers": "需要关注",
|
|
472
|
+
"uncertainty": "证据不确定性",
|
|
473
|
+
"provenance": "规范证据引用",
|
|
474
|
+
"timeline": "治理时间线",
|
|
475
|
+
"timelineEmpty": "暂时没有可用的治理事件。",
|
|
476
|
+
"unavailable": "治理视图暂不可用",
|
|
477
|
+
"unavailableReason": "治理证据无法通过校验或安全加载。",
|
|
478
|
+
"unavailableNextAction": "请刷新一次;若问题持续,在执行审批动作前先检查控制台诊断信息。",
|
|
479
|
+
"none": "无",
|
|
480
|
+
"fact": "事实",
|
|
481
|
+
"derived": "推导",
|
|
482
|
+
"actionsNotAuthorized": "当前不需要拥有者决策。",
|
|
483
|
+
"confidence": { "strong": "有来源支撑", "degraded": "证据不完整" },
|
|
484
|
+
"state": { "candidate": "候选", "active": "已生效", "archived": "已归档", "deprecated": "已弃用", "probation": "观察中" },
|
|
485
|
+
"stage": { "generating": "生成中", "reviewing": "审查中", "revising": "修订中", "approval": "待审批", "activation": "激活中" },
|
|
486
|
+
"automationState": { "idle": "空闲", "queued": "已排队", "running": "运行中", "retry_scheduled": "已安排重试", "stalled": "已停滞" },
|
|
487
|
+
"headline": {
|
|
488
|
+
"owner_decision": "需要你的决策",
|
|
489
|
+
"recovery": "需要恢复 Runtime",
|
|
490
|
+
"revision": "PD 正在修订这条原则",
|
|
491
|
+
"processing": "PD 正在处理这条原则",
|
|
492
|
+
"active": "这条原则正在生效",
|
|
493
|
+
"unavailable": "治理证据不完整",
|
|
494
|
+
"recorded": "原则已记录"
|
|
495
|
+
},
|
|
496
|
+
"reason": {
|
|
497
|
+
"approval_pending": "一项有来源支撑的审批正在等待你审查。",
|
|
498
|
+
"recovery_required": "当前处理前沿无法自动继续。",
|
|
499
|
+
"automatic_revision": "修订或重试已经在进行中。",
|
|
500
|
+
"processing": "当前有来源支撑的任务仍在运行或排队。",
|
|
501
|
+
"activation_active": "至少一个已验证的激活通道正在生效。",
|
|
502
|
+
"data_incomplete": "现有记录无法建立完整的治理视图。",
|
|
503
|
+
"no_current_process": "当前没有已记录的处理或拥有者动作。"
|
|
504
|
+
},
|
|
505
|
+
"next": {
|
|
506
|
+
"review": "使用下方现有审批操作完成审查。",
|
|
507
|
+
"inspect_recovery": "先检查阻塞证据;Runtime 恢复前不要批准。",
|
|
508
|
+
"wait": "当前无需操作,等待 PD 完成正在进行的工作。",
|
|
509
|
+
"monitor": "当前无需操作,继续观察生效通道。",
|
|
510
|
+
"inspect_data": "检查证据诊断,并修复所引用的持久化记录。",
|
|
511
|
+
"none": "当前无需操作。"
|
|
512
|
+
},
|
|
513
|
+
"attention": {
|
|
514
|
+
"approval_pending": "审批待处理",
|
|
515
|
+
"task_failed": "当前 Runtime 任务失败",
|
|
516
|
+
"human_review_required": "Runtime 请求人工恢复审查",
|
|
517
|
+
"revision_not_materialized": "请求的修订尚未物化",
|
|
518
|
+
"verdict_missing": "自动审查已结束,但缺少持久化结论"
|
|
519
|
+
},
|
|
520
|
+
"issue": {
|
|
521
|
+
"lineage_not_available": "规范血缘尚不可用。",
|
|
522
|
+
"lease_expired_unrecovered": "当前任务租约缺失或已过期。",
|
|
523
|
+
"ledger_activation_mismatch": "Ledger 与激活记录不一致。",
|
|
524
|
+
"weak_fact_ignored": "弱事实已从当前权威结论中排除。",
|
|
525
|
+
"lineage_conflict": "冲突血缘证据已被排除。",
|
|
526
|
+
"lineage_cycle": "血缘环路阻止形成权威投影。",
|
|
527
|
+
"lineage_limit_exceeded": "血缘超过安全投影上限。",
|
|
528
|
+
"metadata_malformed": "一条持久化记录格式异常,已被排除。",
|
|
529
|
+
"timestamp_invalid": "一条持久化记录包含无效时间。",
|
|
530
|
+
"source_unavailable": "Runtime 治理数据源当前不可用。"
|
|
531
|
+
},
|
|
532
|
+
"timelineCode": {
|
|
533
|
+
"pain_created": "痛点证据已记录",
|
|
534
|
+
"candidate_generated": "候选原则已生成",
|
|
535
|
+
"review_started": "自动审查已开始",
|
|
536
|
+
"revision_requested": "已请求修订",
|
|
537
|
+
"revision_reopened": "修订任务已重新打开",
|
|
538
|
+
"approved": "拥有者已批准",
|
|
539
|
+
"rejected": "拥有者已拒绝",
|
|
540
|
+
"activated": "通道已激活",
|
|
541
|
+
"deactivated": "通道已停用",
|
|
542
|
+
"failed": "Runtime 任务失败",
|
|
543
|
+
"human_review": "已请求人工恢复审查"
|
|
544
|
+
}
|
|
545
|
+
}
|
|
465
546
|
}
|
|
466
547
|
},
|
|
467
548
|
"activation": {
|
|
@@ -7,7 +7,7 @@ import { PageShell } from "../../components/layout/page-shell.js";
|
|
|
7
7
|
import { PageLoading } from "../../components/layout/page-loading.js";
|
|
8
8
|
import { SectionTitle } from "../../components/layout/section-title.js";
|
|
9
9
|
import { Button } from "../../components/ui/button.js";
|
|
10
|
-
import { fetchPrincipleDetail, fetchApprovalsGrouped, fetchLifecycleMetrics, fetchPrincipleTrajectory, approveApproval, rejectApproval, editApproval, } from "../../api.js";
|
|
10
|
+
import { fetchPrincipleDetail, fetchApprovalsGrouped, fetchLifecycleMetrics, fetchPrincipleTrajectory, fetchPrincipleGovernance, approveApproval, rejectApproval, editApproval, } from "../../api.js";
|
|
11
11
|
// ── Runtime validation (H section) ──────────────────────────────────────────
|
|
12
12
|
function isString(v) {
|
|
13
13
|
return typeof v === "string";
|
|
@@ -115,6 +115,8 @@ export function PrincipleDetailPage() {
|
|
|
115
115
|
const [approvalGroup, setApprovalGroup] = useState(null);
|
|
116
116
|
const [lifecycle, setLifecycle] = useState(null);
|
|
117
117
|
const [trajectory, setTrajectory] = useState(null);
|
|
118
|
+
const [governance, setGovernance] = useState(null);
|
|
119
|
+
const [governanceUnavailable, setGovernanceUnavailable] = useState(null);
|
|
118
120
|
const [loading, setLoading] = useState(true);
|
|
119
121
|
const [error, setError] = useState(null);
|
|
120
122
|
// Decision state
|
|
@@ -135,12 +137,15 @@ export function PrincipleDetailPage() {
|
|
|
135
137
|
setLoading(true);
|
|
136
138
|
setError(null);
|
|
137
139
|
setApprovalGroup(null); // Clear previous approval group to prevent stale actionability (P1)
|
|
140
|
+
setGovernance(null);
|
|
141
|
+
setGovernanceUnavailable(null);
|
|
138
142
|
try {
|
|
139
|
-
const [pResult, aResult, lResult, tResult] = await Promise.all([
|
|
143
|
+
const [pResult, aResult, lResult, tResult, gResult] = await Promise.all([
|
|
140
144
|
fetchPrincipleDetail(id),
|
|
141
145
|
fetchApprovalsGrouped(),
|
|
142
146
|
fetchLifecycleMetrics(id),
|
|
143
147
|
fetchPrincipleTrajectory(id),
|
|
148
|
+
fetchPrincipleGovernance(id),
|
|
144
149
|
]);
|
|
145
150
|
if (!pResult.success) {
|
|
146
151
|
setError(pResult.error ?? "Failed to load principle");
|
|
@@ -169,6 +174,12 @@ export function PrincipleDetailPage() {
|
|
|
169
174
|
else {
|
|
170
175
|
setTrajectory(null);
|
|
171
176
|
}
|
|
177
|
+
if (gResult.success && gResult.data) {
|
|
178
|
+
setGovernance(gResult.data);
|
|
179
|
+
}
|
|
180
|
+
else if (!gResult.success && gResult.reason !== 'feature_disabled') {
|
|
181
|
+
setGovernanceUnavailable({ reason: gResult.error, ...(gResult.nextAction === undefined ? {} : { nextAction: gResult.nextAction }) });
|
|
182
|
+
}
|
|
172
183
|
}
|
|
173
184
|
catch (err) {
|
|
174
185
|
setError(err instanceof Error ? err.message : "Unknown error");
|
|
@@ -208,6 +219,13 @@ export function PrincipleDetailPage() {
|
|
|
208
219
|
isActionable = true;
|
|
209
220
|
}
|
|
210
221
|
}
|
|
222
|
+
const governanceOwnerRequired = governance !== null && governance.attention.primary === 'owner_required';
|
|
223
|
+
const showDecisionControls = governance === null ? governanceUnavailable === null : governanceOwnerRequired;
|
|
224
|
+
if (!showDecisionControls) {
|
|
225
|
+
isActionable = false;
|
|
226
|
+
reasonKey = 'principles.detail.governance.actionsNotAuthorized';
|
|
227
|
+
defaultReason = 'No current Owner decision is required.';
|
|
228
|
+
}
|
|
211
229
|
const handleApprove = () => {
|
|
212
230
|
if (!isActionable)
|
|
213
231
|
return;
|
|
@@ -383,7 +401,7 @@ export function PrincipleDetailPage() {
|
|
|
383
401
|
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsxs(Button, { variant: "ghost", onClick: () => navigate("/principles"), className: "mb-4 -ml-2", children: ["\u2190 ", t("principles.detail.backToList")] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.conclusion") }), _jsx("h1", { className: "text-[22px] font-semibold text-ink leading-snug mb-3", children: principle.text }), _jsx("p", { className: "text-ink-3 text-[14px] leading-relaxed mb-3", children: t("principles.detail.policyNote") }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Button, { variant: "outline", size: "sm", disabled: true, children: t("principles.detail.modifyWording") }), _jsx("span", { className: "text-ink-4 text-[13px]", children: t("principles.detail.modifyWordingNote") }), _jsx(Button, { variant: "ghost", size: "sm", className: "ml-auto", "data-testid": "principle-feedback", onClick: () => {
|
|
384
402
|
const params = new URLSearchParams({ source: "principle_page", principleId: id ?? "" });
|
|
385
403
|
navigate(`/report-problem?${params.toString()}`);
|
|
386
|
-
}, children: t("reportProblem.entryFeedback") })] })] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.channel") }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.channelPromptReversible") })] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.whyExists") }), _jsxs("div", { className: "space-y-3 mb-6", children: [_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.applicable", { defaultValue: "适用场景" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.triggerPattern || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] }), _jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.expectedBehavior", { defaultValue: "预期行为" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.action || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] })] }), principle.derivedFromPainIds.length > 0 && (_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.evidence") }), _jsxs("div", { className: "mt-2 flex items-center gap-3 flex-wrap", children: [_jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.evidenceCount", {
|
|
404
|
+
}, children: t("reportProblem.entryFeedback") })] })] }), (governance !== null || governanceUnavailable !== null) && (_jsxs("section", { className: "mb-8", "aria-labelledby": "governance-summary-title", children: [_jsx(SectionTitle, { children: t('principles.detail.governance.title') }), governance !== null ? (_jsxs("div", { "data-testid": "governance-summary", className: `rounded-[var(--radius-md)] border p-4 ${governance.dataQuality.degraded ? 'border-amber/30 bg-amber/5' : 'border-gov/25 bg-gov/5'}`, children: [_jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between", children: [_jsxs("div", { children: [_jsx("h2", { id: "governance-summary-title", className: "text-[18px] font-semibold text-ink", children: t(`principles.detail.${governance.summary.headlineCode}`, { defaultValue: governance.summary.headlineCode }) }), _jsx("p", { className: "mt-1 text-[13px] leading-relaxed text-ink-2", children: t(`principles.detail.${governance.summary.reasonCode}`, { defaultValue: governance.summary.reasonCode }) })] }), _jsx("span", { className: "w-fit rounded-full border border-line px-2 py-1 font-mono text-[11px] text-ink-3", children: t(`principles.detail.governance.confidence.${governance.dataQuality.degraded ? 'degraded' : 'strong'}`) })] }), _jsxs("dl", { className: "mt-4 grid grid-cols-1 gap-3 sm:grid-cols-3", children: [_jsxs("div", { children: [_jsx("dt", { className: "font-mono text-[11px] text-ink-4", children: t('principles.detail.governance.principleState') }), _jsx("dd", { className: "text-[13px] text-ink-2", children: t(`principles.detail.governance.state.${governance.principleState.value}`) })] }), _jsxs("div", { children: [_jsx("dt", { className: "font-mono text-[11px] text-ink-4", children: t('principles.detail.governance.process') }), _jsx("dd", { className: "text-[13px] text-ink-2", children: governance.process.stage === undefined ? t('principles.detail.governance.none') : t(`principles.detail.governance.stage.${governance.process.stage}`) })] }), _jsxs("div", { children: [_jsx("dt", { className: "font-mono text-[11px] text-ink-4", children: t('principles.detail.governance.automation') }), _jsx("dd", { className: "text-[13px] text-ink-2", children: t(`principles.detail.governance.automationState.${governance.automation.state}`) })] })] }), _jsxs("div", { "data-testid": "governance-next-action", className: "mt-4 border-l-2 border-l-gov pl-3", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.governance.nextAction') }), _jsx("p", { className: "text-[13px] text-ink-2", children: t(`principles.detail.${governance.summary.nextActionCode}`, { defaultValue: governance.summary.nextActionCode }) })] }), governance.attention.items.length > 0 && (_jsxs("div", { className: "mt-4", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4", children: t('principles.detail.governance.blockers') }), _jsx("ul", { className: "mt-1 space-y-1 text-[13px] text-ink-2", children: governance.attention.items.map(item => _jsx("li", { children: t(`principles.detail.governance.attention.${item.reasonCode}`, { defaultValue: item.reasonCode }) }, `${item.kind}-${item.sourceRef.type}-${item.sourceRef.id}`)) })] })), governance.dataQuality.degraded && (_jsxs("div", { "data-testid": "governance-data-quality", className: "mt-4 rounded-[var(--radius-sm)] border border-amber/20 p-3", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-amber", children: t('principles.detail.governance.uncertainty') }), _jsx("ul", { className: "mt-1 space-y-1 text-[12px] text-ink-3", children: governance.dataQuality.issues.map((item, index) => _jsx("li", { children: t(`principles.detail.governance.issue.${item.reasonCode}`, { defaultValue: item.reasonCode }) }, `${item.source}-${item.reasonCode}-${index}`)) })] }))] })) : (_jsxs("div", { "data-testid": "governance-data-quality", className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("h2", { id: "governance-summary-title", className: "text-[16px] font-semibold text-ink", children: t('principles.detail.governance.unavailable') }), _jsx("p", { className: "mt-1 text-[13px] text-ink-2", children: t('principles.detail.governance.unavailableReason') }), _jsx("p", { className: "mt-2 text-[12px] text-ink-3", children: t('principles.detail.governance.unavailableNextAction') })] }))] })), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.channel") }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.channelPromptReversible") })] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.whyExists") }), _jsxs("div", { className: "space-y-3 mb-6", children: [_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.applicable", { defaultValue: "适用场景" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.triggerPattern || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] }), _jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.expectedBehavior", { defaultValue: "预期行为" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.action || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] })] }), principle.derivedFromPainIds.length > 0 && (_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.evidence") }), _jsxs("div", { className: "mt-2 flex items-center gap-3 flex-wrap", children: [_jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.evidenceCount", {
|
|
387
405
|
defaultValue: "已关联 {{count}} 条证据记录",
|
|
388
406
|
count: principle.derivedFromPainIds.length,
|
|
389
407
|
}) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: async () => {
|
|
@@ -406,9 +424,12 @@ export function PrincipleDetailPage() {
|
|
|
406
424
|
: 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: "/evidence", 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", {
|
|
407
425
|
defaultValue: "证据 {{n}} ID",
|
|
408
426
|
n: idx + 1,
|
|
409
|
-
}) }), _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: [
|
|
427
|
+
}) }), _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) => {
|
|
428
|
+
const derived = event.code === 'revision_requested' || event.code === 'revision_reopened';
|
|
429
|
+
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}`);
|
|
430
|
+
}) }))] })), 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)))) : (
|
|
410
431
|
// Fallback: show loading state or no-data message
|
|
411
432
|
['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
|
|
412
433
|
? t("principles.detail.trajectoryLoadFailed", { defaultValue: "无法加载轨迹数据" })
|
|
413
|
-
: "—" }) })] }, 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: "无法加载生命周期指标。你可以稍后重试。" }) }) }))] })] }), _jsxs("div", { className: "border-t border-line pt-6 mt-6", children: [_jsx(SectionTitle, { children: t("principles.detail.decisionTitle", { defaultValue: "决策操作" }) }), _jsxs("div", { className: "flex gap-3 flex-wrap items-center", children: [_jsx(Button, { variant: "default", onClick: handleApprove, disabled: !isActionable || actionLoading, children: t("principles.detail.approve") }), _jsx(Button, { variant: "outline", onClick: handleEdit, disabled: !isActionable || actionLoading, children: t("principles.detail.editAction", { defaultValue: "编辑" }) }), _jsx(Button, { variant: "outline", onClick: handlePark, disabled: true, children: t("principles.detail.park") }), _jsx(Button, { variant: "destructive", onClick: handleReject, disabled: !isActionable || actionLoading, children: t("principles.detail.reject") }), _jsxs("span", { className: "text-ink-4 text-[13px]", children: ["(", t("principles.detail.parkUnavailable", { defaultValue: "暂存尚未可用" }), ")"] })] }), !isActionable && (_jsxs("p", { className: "text-danger text-[13px] mt-3 font-mono", children: [t("principles.detail.unactionableReasonPrefix", { defaultValue: "不可操作原因: " }), t(reasonKey, { defaultValue: defaultReason })] })), isActionable && showConfirm && (_jsxs("div", { className: "mt-4 p-3 bg-gov/5 border border-gov/20 rounded-[var(--radius-md)]", children: [_jsx("p", { className: "text-ink-2 text-[13px] mb-3", children: t("principles.detail.confirmApprove") }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "default", size: "sm", onClick: confirmApprove, disabled: actionLoading, children: t("principles.detail.confirm") }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelConfirm, children: t("principles.detail.cancel") })] })] })), isActionable && showRejectInput && (_jsxs("div", { className: "mt-4 p-3 border border-danger/20 rounded-[var(--radius-md)]", 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") }), _jsxs("div", { className: "flex gap-2 mt-2", children: [_jsx(Button, { variant: "destructive", size: "sm", onClick: confirmReject, disabled: !rejectReason.trim() || actionLoading, children: t("principles.detail.confirmReject") }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelReject, children: t("principles.detail.cancel") })] })] })), isActionable && showEditInput && (_jsxs("div", { className: "mt-4 p-3 border border-gov/20 rounded-[var(--radius-md)]", children: [_jsx("label", { className: "block font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("principles.detail.editReasonLabel", { defaultValue: "编辑原因" }) }), _jsxs("div", { className: "mb-2 text-ink-4 text-[12px] font-mono", children: [t("principles.detail.currentArtifactLabel", { defaultValue: "当前工件" }), ": ", currentArtifactId] }), _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 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": t("principles.detail.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }) }), _jsx("textarea", { value: editReason, onChange: (e) => setEditReason(e.target.value), placeholder: t("principles.detail.editReasonPlaceholder", { 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" }), _jsxs("div", { className: "flex gap-2 mt-2", children: [_jsx(Button, { variant: "default", size: "sm", onClick: confirmEdit, disabled: !editReason.trim() || !newArtifactId.trim() || actionLoading, children: t("principles.detail.confirmEdit", { defaultValue: "确认编辑" }) }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelEdit, children: t("principles.detail.cancel") })] })] }))] })] }) }));
|
|
434
|
+
: "—" }) })] }, 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: "无法加载生命周期指标。你可以稍后重试。" }) }) }))] })] }), showDecisionControls && (_jsxs("div", { className: "border-t border-line pt-6 mt-6", children: [_jsx(SectionTitle, { children: t("principles.detail.decisionTitle", { defaultValue: "决策操作" }) }), _jsxs("div", { className: "flex gap-3 flex-wrap items-center", children: [_jsx(Button, { variant: "default", onClick: handleApprove, disabled: !isActionable || actionLoading, children: t("principles.detail.approve") }), _jsx(Button, { variant: "outline", onClick: handleEdit, disabled: !isActionable || actionLoading, children: t("principles.detail.editAction", { defaultValue: "编辑" }) }), _jsx(Button, { variant: "outline", onClick: handlePark, disabled: true, children: t("principles.detail.park") }), _jsx(Button, { variant: "destructive", onClick: handleReject, disabled: !isActionable || actionLoading, children: t("principles.detail.reject") }), _jsxs("span", { className: "text-ink-4 text-[13px]", children: ["(", t("principles.detail.parkUnavailable", { defaultValue: "暂存尚未可用" }), ")"] })] }), !isActionable && (_jsxs("p", { className: "text-danger text-[13px] mt-3 font-mono", children: [t("principles.detail.unactionableReasonPrefix", { defaultValue: "不可操作原因: " }), t(reasonKey, { defaultValue: defaultReason })] })), isActionable && showConfirm && (_jsxs("div", { className: "mt-4 p-3 bg-gov/5 border border-gov/20 rounded-[var(--radius-md)]", children: [_jsx("p", { className: "text-ink-2 text-[13px] mb-3", children: t("principles.detail.confirmApprove") }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "default", size: "sm", onClick: confirmApprove, disabled: actionLoading, children: t("principles.detail.confirm") }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelConfirm, children: t("principles.detail.cancel") })] })] })), isActionable && showRejectInput && (_jsxs("div", { className: "mt-4 p-3 border border-danger/20 rounded-[var(--radius-md)]", 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") }), _jsxs("div", { className: "flex gap-2 mt-2", children: [_jsx(Button, { variant: "destructive", size: "sm", onClick: confirmReject, disabled: !rejectReason.trim() || actionLoading, children: t("principles.detail.confirmReject") }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelReject, children: t("principles.detail.cancel") })] })] })), isActionable && showEditInput && (_jsxs("div", { className: "mt-4 p-3 border border-gov/20 rounded-[var(--radius-md)]", children: [_jsx("label", { className: "block font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("principles.detail.editReasonLabel", { defaultValue: "编辑原因" }) }), _jsxs("div", { className: "mb-2 text-ink-4 text-[12px] font-mono", children: [t("principles.detail.currentArtifactLabel", { defaultValue: "当前工件" }), ": ", currentArtifactId] }), _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 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": t("principles.detail.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }) }), _jsx("textarea", { value: editReason, onChange: (e) => setEditReason(e.target.value), placeholder: t("principles.detail.editReasonPlaceholder", { 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" }), _jsxs("div", { className: "flex gap-2 mt-2", children: [_jsx(Button, { variant: "default", size: "sm", onClick: confirmEdit, disabled: !editReason.trim() || !newArtifactId.trim() || actionLoading, children: t("principles.detail.confirmEdit", { defaultValue: "确认编辑" }) }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelEdit, children: t("principles.detail.cancel") })] })] }))] }))] }) }));
|
|
414
435
|
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* - Uses `Object.hasOwn()` for untrusted object keys (Rule 5)
|
|
9
9
|
* - Graceful degradation includes a reason (Rule 9)
|
|
10
10
|
*/
|
|
11
|
+
import type { OwnerGovernanceView } from '@principles/core/runtime-v2';
|
|
12
|
+
export declare function validateOwnerGovernanceView(value: unknown): OwnerGovernanceView | null;
|
|
11
13
|
/**
|
|
12
14
|
* Best-effort error envelope validator.
|
|
13
15
|
*
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runtime validators for untrusted API response data.
|
|
3
|
-
*
|
|
4
|
-
* These validators follow the Runtime Contract Rules (ERR-001/005/009/013):
|
|
5
|
-
* - All input is treated as `unknown` (Rule 1)
|
|
6
|
-
* - No `as` type assertions to bypass validation (Rule 2)
|
|
7
|
-
* - Required fields fail loud when missing (Rule 3)
|
|
8
|
-
* - Uses `Object.hasOwn()` for untrusted object keys (Rule 5)
|
|
9
|
-
* - Graceful degradation includes a reason (Rule 9)
|
|
10
|
-
*/
|
|
11
1
|
// ── Primitive guards ──────────────────────────────────────────────────────────
|
|
12
2
|
function isString(v) {
|
|
13
3
|
return typeof v === 'string';
|
|
@@ -52,6 +42,88 @@ function validateArray(v, validateElement) {
|
|
|
52
42
|
}
|
|
53
43
|
return result;
|
|
54
44
|
}
|
|
45
|
+
const governanceSourceTypes = new Set(['principle', 'artifact', 'task', 'run', 'approval', 'activation', 'trajectory']);
|
|
46
|
+
const governanceChannels = new Set(['prompt', 'code_tool_hook', 'defer_archive']);
|
|
47
|
+
const governanceHeadlineCodes = new Set(['governance.headline.owner_decision', 'governance.headline.recovery', 'governance.headline.revision', 'governance.headline.processing', 'governance.headline.active', 'governance.headline.unavailable', 'governance.headline.recorded']);
|
|
48
|
+
const governanceReasonCodes = new Set(['governance.reason.approval_pending', 'governance.reason.recovery_required', 'governance.reason.automatic_revision', 'governance.reason.processing', 'governance.reason.activation_active', 'governance.reason.data_incomplete', 'governance.reason.no_current_process']);
|
|
49
|
+
const governanceNextActionCodes = new Set(['governance.next.review', 'governance.next.inspect_recovery', 'governance.next.wait', 'governance.next.monitor', 'governance.next.inspect_data', 'governance.next.none']);
|
|
50
|
+
const lineageConfidences = new Set(['strong', 'weak', 'unknown']);
|
|
51
|
+
const timestampPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/;
|
|
52
|
+
function isGovernanceTimestamp(value) {
|
|
53
|
+
if (typeof value !== 'string' || !timestampPattern.test(value))
|
|
54
|
+
return false;
|
|
55
|
+
const parsed = new Date(value);
|
|
56
|
+
if (!Number.isFinite(parsed.getTime()))
|
|
57
|
+
return false;
|
|
58
|
+
return parsed.toISOString() === (value.includes('.') ? value : value.replace('Z', '.000Z'));
|
|
59
|
+
}
|
|
60
|
+
function hasOwnFields(value, fields) {
|
|
61
|
+
return fields.every(field => Object.hasOwn(value, field));
|
|
62
|
+
}
|
|
63
|
+
function isStringEnum(value, allowed) {
|
|
64
|
+
return typeof value === 'string' && allowed.has(value);
|
|
65
|
+
}
|
|
66
|
+
function isGovernanceSourceRef(value) {
|
|
67
|
+
return isObject(value) && hasOwnFields(value, ['type', 'id'])
|
|
68
|
+
&& isStringEnum(value.type, governanceSourceTypes) && typeof value.id === 'string' && value.id.length > 0;
|
|
69
|
+
}
|
|
70
|
+
function isGovernanceSourceRefs(value) {
|
|
71
|
+
return Array.isArray(value) && value.every(isGovernanceSourceRef);
|
|
72
|
+
}
|
|
73
|
+
function isDataQualityIssue(value) {
|
|
74
|
+
return isObject(value) && hasOwnFields(value, ['source', 'reasonCode', 'nextActionCode'])
|
|
75
|
+
&& isStringEnum(value.source, new Set(['ledger', 'artifact', 'task', 'approval', 'activation', 'trajectory', 'lineage']))
|
|
76
|
+
&& typeof value.reasonCode === 'string' && value.reasonCode.length > 0
|
|
77
|
+
&& typeof value.nextActionCode === 'string' && value.nextActionCode.length > 0
|
|
78
|
+
&& (!Object.hasOwn(value, 'sourceRef') || isGovernanceSourceRef(value.sourceRef));
|
|
79
|
+
}
|
|
80
|
+
function isTimelineEvent(value) {
|
|
81
|
+
return isObject(value) && hasOwnFields(value, ['code', 'recordedAt', 'summaryCode', 'sourceRef', 'lineageConfidence'])
|
|
82
|
+
&& isStringEnum(value.code, new Set(['pain_created', 'candidate_generated', 'review_started', 'revision_requested', 'revision_reopened', 'approved', 'rejected', 'activated', 'deactivated', 'failed', 'human_review']))
|
|
83
|
+
&& isGovernanceTimestamp(value.recordedAt)
|
|
84
|
+
&& (!Object.hasOwn(value, 'occurredAt') || isGovernanceTimestamp(value.occurredAt))
|
|
85
|
+
&& typeof value.summaryCode === 'string' && value.summaryCode.length > 0
|
|
86
|
+
&& isGovernanceSourceRef(value.sourceRef) && isStringEnum(value.lineageConfidence, lineageConfidences);
|
|
87
|
+
}
|
|
88
|
+
function isOwnerGovernanceView(value) {
|
|
89
|
+
if (!isObject(value) || !hasOwnFields(value, ['schemaVersion', 'principleId', 'asOf', 'summary', 'principleState', 'process', 'automation', 'attention', 'activationSummary', 'timeline', 'sourceRefs', 'dataQuality']))
|
|
90
|
+
return false;
|
|
91
|
+
if (value.schemaVersion !== '1' || typeof value.principleId !== 'string' || value.principleId.length === 0 || !isGovernanceTimestamp(value.asOf))
|
|
92
|
+
return false;
|
|
93
|
+
const { summary, principleState: principle, process, automation, attention, activationSummary: activation, dataQuality: quality, } = value;
|
|
94
|
+
if (!isObject(summary) || !hasOwnFields(summary, ['headlineCode', 'reasonCode', 'nextActionCode', 'ownerActionRequired', 'sourceRefs'])
|
|
95
|
+
|| !isStringEnum(summary.headlineCode, governanceHeadlineCodes) || !isStringEnum(summary.reasonCode, governanceReasonCodes) || !isStringEnum(summary.nextActionCode, governanceNextActionCodes)
|
|
96
|
+
|| typeof summary.ownerActionRequired !== 'boolean' || !isGovernanceSourceRefs(summary.sourceRefs)
|
|
97
|
+
|| (Object.hasOwn(summary, 'safeReasonSummary') && (typeof summary.safeReasonSummary !== 'string' || summary.safeReasonSummary.length === 0)))
|
|
98
|
+
return false;
|
|
99
|
+
if (!isObject(principle) || !hasOwnFields(principle, ['value', 'sourceRefs'])
|
|
100
|
+
|| !isStringEnum(principle.value, new Set(['candidate', 'active', 'archived', 'deprecated', 'probation'])) || !isGovernanceSourceRefs(principle.sourceRefs))
|
|
101
|
+
return false;
|
|
102
|
+
if (!isObject(process) || !hasOwnFields(process, ['sourceRefs']) || !isGovernanceSourceRefs(process.sourceRefs)
|
|
103
|
+
|| (Object.hasOwn(process, 'stage') && !isStringEnum(process.stage, new Set(['generating', 'reviewing', 'revising', 'approval', 'activation'])))
|
|
104
|
+
|| (Object.hasOwn(process, 'currentTaskKind') && !isStringEnum(process.currentTaskKind, new Set(['dreamer', 'philosopher', 'scribe', 'artificer', 'evaluator', 'rollout_reviewer']))))
|
|
105
|
+
return false;
|
|
106
|
+
if (!isObject(automation) || !hasOwnFields(automation, ['state', 'sourceRefs'])
|
|
107
|
+
|| !isStringEnum(automation.state, new Set(['idle', 'queued', 'running', 'retry_scheduled', 'stalled'])) || !isGovernanceSourceRefs(automation.sourceRefs))
|
|
108
|
+
return false;
|
|
109
|
+
if (!isObject(attention) || !hasOwnFields(attention, ['primary', 'items'])
|
|
110
|
+
|| !isStringEnum(attention.primary, new Set(['none', 'owner_required', 'recovery_required'])) || !Array.isArray(attention.items)
|
|
111
|
+
|| !attention.items.every(item => isObject(item) && hasOwnFields(item, ['kind', 'reasonCode', 'sourceRef'])
|
|
112
|
+
&& isStringEnum(item.kind, new Set(['owner_decision', 'recovery'])) && typeof item.reasonCode === 'string' && item.reasonCode.length > 0 && isGovernanceSourceRef(item.sourceRef)))
|
|
113
|
+
return false;
|
|
114
|
+
if (!isObject(activation) || !hasOwnFields(activation, ['state', 'channels', 'observedChannels', 'sourceRefs'])
|
|
115
|
+
|| !isStringEnum(activation.state, new Set(['none', 'active', 'partially_active', 'deactivated']))
|
|
116
|
+
|| !Array.isArray(activation.channels) || !activation.channels.every(channel => isStringEnum(channel, governanceChannels))
|
|
117
|
+
|| !Array.isArray(activation.observedChannels) || !activation.observedChannels.every(channel => isStringEnum(channel, governanceChannels))
|
|
118
|
+
|| !isGovernanceSourceRefs(activation.sourceRefs))
|
|
119
|
+
return false;
|
|
120
|
+
return Array.isArray(value.timeline) && value.timeline.every(isTimelineEvent) && isGovernanceSourceRefs(value.sourceRefs)
|
|
121
|
+
&& isObject(quality) && hasOwnFields(quality, ['degraded', 'issues']) && typeof quality.degraded === 'boolean'
|
|
122
|
+
&& Array.isArray(quality.issues) && quality.issues.every(isDataQualityIssue);
|
|
123
|
+
}
|
|
124
|
+
export function validateOwnerGovernanceView(value) {
|
|
125
|
+
return isOwnerGovernanceView(value) ? value : null;
|
|
126
|
+
}
|
|
55
127
|
export function validateErrorResponse(v) {
|
|
56
128
|
if (!isObject(v))
|
|
57
129
|
return null;
|
|
@@ -736,6 +736,10 @@
|
|
|
736
736
|
.w-\[256px\] {
|
|
737
737
|
width: 256px;
|
|
738
738
|
}
|
|
739
|
+
.w-fit {
|
|
740
|
+
width: -moz-fit-content;
|
|
741
|
+
width: fit-content;
|
|
742
|
+
}
|
|
739
743
|
.w-full {
|
|
740
744
|
width: 100%;
|
|
741
745
|
}
|
|
@@ -1280,6 +1284,12 @@
|
|
|
1280
1284
|
border-color: color-mix(in oklab, var(--color-gov) 22%, transparent);
|
|
1281
1285
|
}
|
|
1282
1286
|
}
|
|
1287
|
+
.border-gov\/25 {
|
|
1288
|
+
border-color: color-mix(in srgb, #1e3a5f 25%, transparent);
|
|
1289
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1290
|
+
border-color: color-mix(in oklab, var(--color-gov) 25%, transparent);
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1283
1293
|
.border-gov\/30 {
|
|
1284
1294
|
border-color: color-mix(in srgb, #1e3a5f 30%, transparent);
|
|
1285
1295
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -2691,6 +2701,12 @@
|
|
|
2691
2701
|
.sm\:flex-row {
|
|
2692
2702
|
flex-direction: row;
|
|
2693
2703
|
}
|
|
2704
|
+
.sm\:items-start {
|
|
2705
|
+
align-items: flex-start;
|
|
2706
|
+
}
|
|
2707
|
+
.sm\:justify-between {
|
|
2708
|
+
justify-content: space-between;
|
|
2709
|
+
}
|
|
2694
2710
|
.sm\:justify-end {
|
|
2695
2711
|
justify-content: flex-end;
|
|
2696
2712
|
}
|