create-principles-disciple 1.122.3 → 1.124.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 +9 -4
- package/console/dist/server/models/OwnerDecisionConsoleModel.d.ts +5 -0
- package/console/dist/server/models/OwnerDecisionConsoleModel.js +92 -18
- package/console/dist/server/routes/governance.js +6 -1
- package/console/dist/server/routes/health.d.ts +4 -1
- package/console/dist/server/routes/health.js +3 -3
- package/console/dist/server/routes/owner-decisions.d.ts +3 -3
- package/console/dist/server/routes/owner-decisions.js +41 -3
- package/console/dist/ui/api.d.ts +5 -0
- package/console/dist/ui/i18n/en.json +22 -1
- package/console/dist/ui/i18n/zh-CN.json +22 -1
- package/console/dist/ui/pages/focus/FocusPage.js +17 -30
- package/console/dist/ui/pages/focus/OwnerDecisionCard.d.ts +2 -1
- package/console/dist/ui/pages/focus/OwnerDecisionCard.js +11 -6
- package/console/dist/ui/pages/settings/SettingsPage.js +3 -3
- package/console/dist/ui/utils/validators.d.ts +45 -1
- package/console/dist/ui/utils/validators.js +112 -4
- package/console/dist/web/assets/app.css +0 -9
- package/console/dist/web/assets/app.js +226 -417
- package/core/dist/runtime-v2/__tests__/adversarial-loop.test.js +22 -0
- package/core/dist/runtime-v2/__tests__/adversarial-loop.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/governance-experience.test.js +19 -0
- package/core/dist/runtime-v2/__tests__/governance-experience.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.js +106 -0
- package/core/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.js +243 -0
- package/core/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +2 -2
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -1
- package/core/dist/runtime-v2/governance-experience-contract.d.ts +16 -16
- package/core/dist/runtime-v2/governance-experience-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/governance-experience-contract.js +4 -1
- package/core/dist/runtime-v2/governance-experience-contract.js.map +1 -1
- package/core/dist/runtime-v2/governance-experience.d.ts.map +1 -1
- package/core/dist/runtime-v2/governance-experience.js +30 -8
- package/core/dist/runtime-v2/governance-experience.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +5 -3
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +4 -3
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.js +114 -0
- package/core/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js +256 -0
- package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.js +229 -0
- package/core/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/owner-decision.test.js +172 -1
- package/core/dist/runtime-v2/internalization/__tests__/owner-decision.test.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.js +187 -0
- package/core/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/artificer-code-bearing.d.ts +39 -0
- package/core/dist/runtime-v2/internalization/artificer-code-bearing.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/artificer-code-bearing.js +33 -0
- package/core/dist/runtime-v2/internalization/artificer-code-bearing.js.map +1 -0
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts +11 -8
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js +170 -31
- package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/index.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/index.js +1 -0
- package/core/dist/runtime-v2/internalization/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/internalization-task-guards.d.ts +5 -8
- package/core/dist/runtime-v2/internalization/internalization-task-guards.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/internalization-task-guards.js +11 -12
- package/core/dist/runtime-v2/internalization/internalization-task-guards.js.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-decision-review.d.ts +98 -0
- package/core/dist/runtime-v2/internalization/owner-decision-review.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/owner-decision-review.js +287 -0
- package/core/dist/runtime-v2/internalization/owner-decision-review.js.map +1 -0
- package/core/dist/runtime-v2/internalization/owner-resolution-service.d.ts +11 -0
- package/core/dist/runtime-v2/internalization/owner-resolution-service.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-resolution-service.js +117 -4
- package/core/dist/runtime-v2/internalization/owner-resolution-service.js.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-review.d.ts +4 -0
- package/core/dist/runtime-v2/internalization/owner-review.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-review.js.map +1 -1
- package/core/dist/runtime-v2/internalization/pitask-metadata.d.ts +16 -0
- package/core/dist/runtime-v2/internalization/pitask-metadata.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/pitask-metadata.js +62 -0
- package/core/dist/runtime-v2/internalization/pitask-metadata.js.map +1 -1
- package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts +13 -0
- package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js +59 -11
- package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/rule-activation-contract.d.ts +35 -0
- package/core/dist/runtime-v2/internalization/rule-activation-contract.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/rule-activation-contract.js +36 -0
- package/core/dist/runtime-v2/internalization/rule-activation-contract.js.map +1 -0
- package/core/dist/runtime-v2/pain-signal-bridge.d.ts +40 -0
- package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-bridge.js +95 -0
- package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts +10 -4
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js +86 -51
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.d.ts +6 -0
- package/core/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.js +8 -0
- package/core/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
- package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store-cas.test.js +36 -0
- package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store-cas.test.js.map +1 -1
- package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts +19 -0
- package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/task/sqlite-task-store.js +30 -1
- package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +65 -4
- package/dist/installer.js.map +1 -1
- package/host-runtime/dist/governance-observation-store.d.ts +17 -0
- package/host-runtime/dist/governance-observation-store.js +38 -0
- package/host-runtime/dist/governance-signal-admission.js +55 -43
- package/host-runtime/dist/index.d.ts +3 -0
- package/host-runtime/dist/index.js +7 -0
- package/host-runtime/dist/internalization-consumer-cycle.d.ts +43 -0
- package/host-runtime/dist/internalization-consumer-cycle.js +468 -0
- package/host-runtime/dist/internalization-consumer-governance.d.ts +39 -0
- package/host-runtime/dist/internalization-consumer-governance.js +152 -0
- package/host-runtime/dist/workspace-telemetry-emitter.d.ts +15 -0
- package/host-runtime/dist/workspace-telemetry-emitter.js +74 -0
- package/install-layout/dist/index.d.ts +10 -0
- package/install-layout/dist/index.js +34 -1
- package/install-layout/dist/index.test.js +36 -1
- package/package.json +2 -2
- package/pd-cli/dist/commands/codex-ingest-catchup.d.ts +20 -0
- package/pd-cli/dist/commands/codex-ingest-catchup.d.ts.map +1 -0
- package/pd-cli/dist/commands/codex-ingest-catchup.js +95 -0
- package/pd-cli/dist/commands/codex-ingest-catchup.js.map +1 -0
- package/pd-cli/dist/commands/codex-worker.d.ts +20 -0
- package/pd-cli/dist/commands/codex-worker.d.ts.map +1 -0
- package/pd-cli/dist/commands/codex-worker.js +156 -0
- package/pd-cli/dist/commands/codex-worker.js.map +1 -0
- package/pd-cli/dist/commands/console.d.ts.map +1 -1
- package/pd-cli/dist/commands/console.js +34 -1
- package/pd-cli/dist/commands/console.js.map +1 -1
- package/pd-cli/dist/index.js +47 -0
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/services/console-launcher.d.ts +8 -2
- package/pd-cli/dist/services/console-launcher.d.ts.map +1 -1
- package/pd-cli/dist/services/console-launcher.js +34 -4
- package/pd-cli/dist/services/console-launcher.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/dist/bundle.js +534 -524
- package/plugin/dist/governance-audit.js +132 -132
- package/plugin/dist/rulehost-evidence.js +148 -148
- package/plugin/dist/service/internalization-auto-consumer-service.d.ts +11 -0
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
- package/plugin/dist/service/auto-consumer-governance-wiring.d.ts +0 -34
|
@@ -384,6 +384,8 @@ export const EXPERIENCE_ATTENTION = {
|
|
|
384
384
|
};
|
|
385
385
|
export const EXPERIENCE_REASON = {
|
|
386
386
|
"governance.exp.reason.owner_identity_missing": "pages.focus.experience.reason.ownerIdentityMissing",
|
|
387
|
+
"governance.exp.reason.owner_identity_invalid": "pages.focus.experience.reason.ownerIdentityInvalid",
|
|
388
|
+
"governance.exp.reason.owner_authentication_missing": "pages.focus.experience.reason.ownerAuthenticationMissing",
|
|
387
389
|
"governance.exp.reason.approval_pending": "pages.focus.experience.reason.approvalPending",
|
|
388
390
|
"governance.exp.reason.rulecode_owner_decision": "pages.focus.experience.reason.rulecodeOwnerDecision",
|
|
389
391
|
"governance.exp.reason.no_pending_decision": "pages.focus.experience.reason.noPendingDecision",
|
|
@@ -398,6 +400,7 @@ export const EXPERIENCE_REASON = {
|
|
|
398
400
|
};
|
|
399
401
|
export const EXPERIENCE_NEXT_ACTION = {
|
|
400
402
|
"governance.exp.next.configure_owner": "pages.focus.experience.next.configureOwner",
|
|
403
|
+
"governance.exp.next.authenticate_console": "pages.focus.experience.next.authenticateConsole",
|
|
401
404
|
"governance.exp.next.review_approvals": "pages.focus.experience.next.reviewApprovals",
|
|
402
405
|
"governance.exp.next.inspect_recovery": "pages.focus.experience.next.inspectRecovery",
|
|
403
406
|
"governance.exp.next.inspect_sources": "pages.focus.experience.next.inspectSources",
|
|
@@ -414,31 +417,21 @@ const EXPERIENCE_ENVIRONMENT = {
|
|
|
414
417
|
};
|
|
415
418
|
function ExperienceSummaryCard({ snapshot }) {
|
|
416
419
|
const { t } = useTranslation();
|
|
417
|
-
const [copiedCommandIdx, setCopiedCommandIdx] = useState(null);
|
|
418
420
|
const attention = EXPERIENCE_ATTENTION[snapshot.summary.primaryAttention];
|
|
419
421
|
const categoryOf = (category) => snapshot.activity.categories.find(entry => entry.category === category);
|
|
420
422
|
const decision = categoryOf("needs_decision");
|
|
421
423
|
const recovery = categoryOf("needs_recovery");
|
|
422
424
|
const blocked = categoryOf("blocked");
|
|
423
425
|
const processing = categoryOf("processing");
|
|
424
|
-
const actionOf = (kind) => snapshot.readiness.governanceActions.find(action => action.kind === kind);
|
|
425
|
-
const rulecodeAction = actionOf("rulecode_owner_decision");
|
|
426
|
-
const pauseAction = actionOf("emergency_pause");
|
|
427
426
|
const firstIssue = snapshot.dataQuality.issueGroups[0];
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
// clipboard unavailable — keep the command visible as fallback
|
|
437
|
-
console.warn("Owner configure command copy failed.", error);
|
|
438
|
-
}
|
|
439
|
-
}, className: "font-mono text-[11px] text-gov hover:text-gov-2", children: copiedCommandIdx === idx
|
|
440
|
-
? t("pages.focus.experience.ownerGuide.copied")
|
|
441
|
-
: t("pages.focus.experience.ownerGuide.copy") })] }), _jsx("pre", { className: "px-2.5 pb-2 pt-0.5 text-[11px] font-mono text-ink-2 leading-relaxed overflow-x-auto whitespace-pre-wrap", children: cmd.command })] }, cmd.labelKey))) }), _jsx("p", { className: "mt-2 text-[12px] text-amber leading-relaxed", "data-testid": "owner-guide-token-auth-hint", children: t("pages.focus.experience.ownerGuide.tokenAuthHint") }), _jsx("a", { href: ownerGuide.docUrl, target: "_blank", rel: "noreferrer", className: "mt-2 inline-block text-[12px] text-gov underline hover:text-gov-2", children: t("pages.focus.experience.ownerGuide.docLink") })] })), _jsxs("div", { className: "mt-1 text-[12px] text-ink-4", "data-testid": "experience-trust", children: [t(EXPERIENCE_ENVIRONMENT[snapshot.trustContext.environmentContext.environment]), " · ", t(`pages.focus.experience.trust.lineage.${snapshot.trustContext.lineageTransparency.confidence}`)] }), snapshot.dataQuality.degraded && (_jsx("div", { className: "mt-2 text-[12px] text-amber leading-relaxed", "data-testid": "experience-data-quality", children: t("pages.focus.experience.dataQuality.degraded", { count: firstIssue?.count ?? 0, reasonCode: firstIssue?.reasonCode ?? "" }) }))] }));
|
|
427
|
+
const governanceBlocked = snapshot.readiness.ownerIdentityConfiguration !== "configured"
|
|
428
|
+
|| snapshot.readiness.authenticationMode !== "authenticated";
|
|
429
|
+
const blockerKey = snapshot.readiness.ownerIdentityConfiguration === "invalid"
|
|
430
|
+
? "pages.focus.experience.blocker.identityInvalid"
|
|
431
|
+
: snapshot.readiness.ownerIdentityConfiguration === "missing"
|
|
432
|
+
? "pages.focus.experience.blocker.identityMissing"
|
|
433
|
+
: "pages.focus.experience.blocker.authenticationMissing";
|
|
434
|
+
return (_jsxs("div", { className: "mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", "data-testid": "experience-summary", children: [_jsx("div", { className: "flex items-center gap-2 mb-1", children: _jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${attention.badgeClass}`, role: "status", children: t(attention.labelKey) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", "data-testid": "experience-reason", children: t(EXPERIENCE_REASON[snapshot.summary.reasonCode]) }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", t(EXPERIENCE_NEXT_ACTION[snapshot.summary.nextActionCode])] }), (decision !== undefined || recovery !== undefined || blocked !== undefined || processing !== undefined) && (_jsxs("div", { className: "text-[13px] text-ink-3 mt-2 leading-relaxed", "data-testid": "experience-activity", children: [decision !== undefined && (_jsx("span", { className: "mr-4", children: t("pages.focus.experience.activity.needsDecision", { count: decision.count }) })), recovery !== undefined && (_jsx("span", { className: "mr-4", children: t("pages.focus.experience.activity.needsRecovery", { count: recovery.count }) })), blocked !== undefined && _jsx("span", { className: "mr-4", children: t("pages.focus.experience.activity.blocked") }), processing !== undefined && (_jsx("span", { children: t("pages.focus.experience.activity.processing", { count: processing.count }) }))] })), governanceBlocked && (_jsxs("div", { className: "mt-3 flex items-center justify-between gap-3 border border-amber/30 rounded-[6px] bg-surface px-3 py-2.5", "data-testid": "owner-configure-guide", children: [_jsx("p", { className: "text-[12px] text-ink-3 leading-relaxed", children: t(blockerKey) }), _jsx(Link, { to: "/settings", className: "shrink-0 text-[12px] text-gov underline hover:text-gov-2", children: t("pages.focus.experience.blocker.goSettings") })] })), _jsxs("div", { className: "mt-1 text-[12px] text-ink-4", "data-testid": "experience-trust", children: [t(EXPERIENCE_ENVIRONMENT[snapshot.trustContext.environmentContext.environment]), " · ", t(`pages.focus.experience.trust.lineage.${snapshot.trustContext.lineageTransparency.confidence}`)] }), snapshot.dataQuality.degraded && (_jsx("div", { className: "mt-2 text-[12px] text-amber leading-relaxed", "data-testid": "experience-data-quality", children: t("pages.focus.experience.dataQuality.degraded", { count: firstIssue?.count ?? 0, reasonCode: firstIssue?.reasonCode ?? "" }) }))] }));
|
|
442
435
|
}
|
|
443
436
|
export function FocusPage({ featureFlags }) {
|
|
444
437
|
const { t } = useTranslation();
|
|
@@ -560,19 +553,13 @@ export function FocusPage({ featureFlags }) {
|
|
|
560
553
|
const stateReasonCount = stateReasonCode === "tasks_need_human_review" ? humanReviewCount : pendingCount;
|
|
561
554
|
const stateReason = getStateReasonText(stateReasonCode, t, stateReasonCount);
|
|
562
555
|
const nextAction = getNextActionText(nextActionCode, t);
|
|
563
|
-
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.focus.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: pendingCount === 0, children: t("pages.focus.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.focus.subtitle") }),
|
|
564
|
-
? "bg-gov/10 text-gov border border-gov/20"
|
|
565
|
-
: governanceState === "degraded"
|
|
566
|
-
? "bg-amber/10 text-amber border border-amber/20"
|
|
567
|
-
: governanceState === "in_progress"
|
|
568
|
-
? "bg-green/10 text-green border border-green/20"
|
|
569
|
-
: "text-ink-4 border border-line bg-surface/80"}`, role: "status", children: t(`pages.focus.stateLabel.${governanceState}`) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", children: stateReason }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", nextAction] })] })) : null, _jsxs("section", { "aria-label": t("pages.focus.ownerDecision.sectionTitle"), className: "mb-7", "data-testid": "owner-decisions-section", children: [_jsxs("div", { className: "flex items-baseline gap-2 mb-3", children: [_jsx(SectionTitle, { children: t("pages.focus.ownerDecision.sectionTitle") }), _jsx("span", { className: "font-mono text-ink-4 text-[12px]", children: ownerDecisionError !== null
|
|
556
|
+
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.focus.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: pendingCount === 0, children: t("pages.focus.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.focus.subtitle") }), _jsxs("section", { "aria-label": t("pages.focus.ownerDecision.sectionTitle"), className: "mb-7", "data-testid": "owner-decisions-section", children: [_jsxs("div", { className: "flex items-baseline gap-2 mb-3", children: [_jsx(SectionTitle, { children: t("pages.focus.ownerDecision.sectionTitle") }), _jsx("span", { className: "font-mono text-ink-4 text-[12px]", children: ownerDecisionError !== null
|
|
570
557
|
? t("pages.focus.ownerDecision.unavailable")
|
|
571
|
-
: `· ${ownerDecisionItems.length}` })] }), ownerDecisionError !== null && (_jsx("p", { className: "text-ink-4 text-[12.5px]", children: t("pages.focus.ownerDecision.loadError") })), ownerDecisionError === null && ownerDecisionItems.length === 0 && (_jsx("p", { className: "text-ink-4 text-[13px]", children: t("pages.focus.ownerDecision.empty") })), ownerDecisionItems.map((item) => (_jsx(OwnerDecisionCard, { item: item,
|
|
572
|
-
? (
|
|
573
|
-
?
|
|
574
|
-
|
|
575
|
-
|
|
558
|
+
: `· ${ownerDecisionItems.length}` })] }), ownerDecisionError !== null && (_jsx("p", { className: "text-ink-4 text-[12.5px]", children: t("pages.focus.ownerDecision.loadError") })), ownerDecisionError === null && ownerDecisionItems.length === 0 && (_jsx("p", { className: "text-ink-4 text-[13px]", children: t("pages.focus.ownerDecision.empty") })), ownerDecisionItems.map((item) => (_jsx(OwnerDecisionCard, { item: item, governanceReady: experienceData === null || (experienceData.readiness.authenticationMode === "authenticated"
|
|
559
|
+
&& experienceData.readiness.ownerIdentityConfiguration === "configured"), onResolved: () => { void loadData(); } }, item.reviewKey)))] }), experienceMode && experienceData !== null ? (_jsx(ExperienceSummaryCard, { snapshot: experienceData })) : !experienceMode ? (_jsxs("div", { className: "mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", children: [_jsx("div", { className: "flex items-center gap-2 mb-1", children: _jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${governanceState === "owner_review_ready" ? "bg-gov/10 text-gov border border-gov/20"
|
|
560
|
+
: governanceState === "degraded" ? "bg-amber/10 text-amber border border-amber/20"
|
|
561
|
+
: governanceState === "in_progress" ? "bg-green/10 text-green border border-green/20"
|
|
562
|
+
: "text-ink-4 border border-line bg-surface/80"}`, role: "status", children: t(`pages.focus.stateLabel.${governanceState}`) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", children: stateReason }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", nextAction] })] })) : null, !experienceMode && (_jsxs(_Fragment, { children: [_jsx(ProseSummary, { pendingCount: pendingCount, deviationCount: deviationCount, stagnationCount: stagnationCount, evidenceCount: evidenceCount }), _jsx(FeedbackStratification, { gateBlocksToday: gateBlocksToday, inProgressCount: evidenceCount, pendingCount: pendingCount }), !experienceMode && governanceState === "none" && pendingCount === 0 && deviationCount === 0 && stagnationCount === 0 && (stateReasonCode === "state_db_missing" ? (_jsx(ZeroStateDbMissing, {})) : (_jsxs(_Fragment, { children: [_jsx(ZeroStateHealthy, {}), _jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })] }))), governanceState === "in_progress" && inProgressSummary && (_jsx(InProgressGuide, { summary: inProgressSummary })), degradedSignals && degradedSignals.length > 0 && (_jsx(DegradedSummary, { signals: degradedSignals }))] })), _jsx(DailyThoughtCard, {}), experienceMode && experienceData !== null && experienceData.summary.primaryAttention === "all_clear" && pendingGroups.length === 0 && (_jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })), !experienceMode && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-deviation", children: [_jsx(SectionTitle, { id: "section-deviation", children: evidenceCount > 0
|
|
576
563
|
? t("pages.focus.sectionEvidenceInProgress")
|
|
577
564
|
: t("pages.focus.sectionDeviation") }), deviationCount > 0 ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-ink-2 text-sm mb-3", children: [_jsx("span", { className: "font-mono font-semibold text-ink", children: deviationCount }), " ", t("pages.focus.deviationCount", { count: deviationCount })] }), _jsx("div", { className: "text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2 mb-4", children: t("pages.focus.deviationDisclaimer") }), _jsxs("details", { className: "group", children: [_jsx("summary", { className: "text-gov text-[13px] cursor-pointer hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.viewFullChain") }), _jsx("div", { className: "mt-2 pl-4 border-l-2 border-line text-ink-3 text-[13px]", children: t("pages.focus.deviationDetailPending") })] })] })) : evidenceCount > 0 ? (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.evidenceInProgress", { count: evidenceCount }) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptyDeviation") }))] })), !experienceMode && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-signals", children: [_jsx(SectionTitle, { id: "section-signals", children: t("pages.focus.sectionSignals") }), stagnationSignals.length > 0 ? (_jsx("div", { className: "space-y-[10px]", children: stagnationSignals.map((signal) => (_jsx(StagnationSignalCard, { signal: signal }, signal.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptySignals") }))] })), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.focus.footer") })] }) }));
|
|
578
565
|
}
|
|
@@ -2,5 +2,6 @@ import type { OwnerDecisionItemData } from "../../utils/validators.js";
|
|
|
2
2
|
export interface OwnerDecisionCardProps {
|
|
3
3
|
item: OwnerDecisionItemData;
|
|
4
4
|
onResolved: () => void;
|
|
5
|
+
governanceReady?: boolean;
|
|
5
6
|
}
|
|
6
|
-
export declare function OwnerDecisionCard({ item, onResolved }: OwnerDecisionCardProps): import("react").JSX.Element;
|
|
7
|
+
export declare function OwnerDecisionCard({ item, onResolved, governanceReady }: OwnerDecisionCardProps): import("react").JSX.Element;
|
|
@@ -12,16 +12,19 @@ import { Link } from "react-router-dom";
|
|
|
12
12
|
import { useTranslation } from "react-i18next";
|
|
13
13
|
import { toast } from "sonner";
|
|
14
14
|
import { resolveOwnerDecision } from "../../api.js";
|
|
15
|
-
export function OwnerDecisionCard({ item, onResolved }) {
|
|
15
|
+
export function OwnerDecisionCard({ item, onResolved, governanceReady = true }) {
|
|
16
16
|
const { t } = useTranslation();
|
|
17
17
|
const [actionLoading, setActionLoading] = useState(null);
|
|
18
18
|
const [instruction, setInstruction] = useState("");
|
|
19
19
|
const [showInstruction, setShowInstruction] = useState(false);
|
|
20
20
|
const [showAdvanced, setShowAdvanced] = useState(false);
|
|
21
|
+
const [partialEvidenceAcknowledged, setPartialEvidenceAcknowledged] = useState(false);
|
|
21
22
|
const isTaskDecision = item.kind === "evaluator_review" || item.kind === "rollout_review";
|
|
22
23
|
const canAccept = item.allowedActions.includes("accept_current");
|
|
23
24
|
const canRevise = item.allowedActions.includes("revise_once");
|
|
24
25
|
const canReject = item.allowedActions.includes("reject_current");
|
|
26
|
+
const requiresPartialAcknowledgement = item.review?.capability.acceptRequirement.kind === "acknowledge_partial_evidence";
|
|
27
|
+
const evidenceUnavailable = item.evidenceUnavailableReason !== undefined;
|
|
25
28
|
async function handleAction(action) {
|
|
26
29
|
if (action === "revise_once" && showInstruction && instruction.trim().length === 0) {
|
|
27
30
|
// 指导为空也可以提交 — instruction 是可选的;这里仅在展开输入后要求非空确认
|
|
@@ -38,6 +41,10 @@ export function OwnerDecisionCard({ item, onResolved }) {
|
|
|
38
41
|
expectedSourceRunId: item.expectedSourceRunId,
|
|
39
42
|
expectedSourceArtifactId: item.expectedSourceArtifactId,
|
|
40
43
|
expectedSourceArtifactHash: item.expectedSourceArtifactHash,
|
|
44
|
+
expectedEvidenceDigest: item.expectedEvidenceDigest ?? "",
|
|
45
|
+
...(action === "accept_current" && requiresPartialAcknowledgement && partialEvidenceAcknowledged
|
|
46
|
+
? { acknowledgement: { kind: "partial_evidence", acknowledged: true } }
|
|
47
|
+
: {}),
|
|
41
48
|
...(action === "revise_once" && instruction.trim().length > 0
|
|
42
49
|
? { ownerInstruction: instruction.trim() }
|
|
43
50
|
: { ownerInstruction: null }),
|
|
@@ -72,15 +79,13 @@ export function OwnerDecisionCard({ item, onResolved }) {
|
|
|
72
79
|
: item.kind === "rulecode_decision"
|
|
73
80
|
? t("pages.focus.ownerDecision.kindRulecode")
|
|
74
81
|
: t("pages.focus.ownerDecision.kindEvaluator");
|
|
75
|
-
return (_jsxs("article", { className: "bg-panel border border-line rounded-[6px] p-4 mb-3", "data-testid": `owner-decision-${item.taskId}`, children: [_jsxs("div", { className: "flex items-start justify-between gap-3 mb-2", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-ink text-[14px] font-medium leading-snug", children: item.title }), _jsx("div", { className: "mt-1 text-ink-4 text-[11px] font-mono uppercase tracking-[0.08em]", children: kindLabel })] }), item.legacy && (_jsx("span", { className: "shrink-0 text-ink-4 border border-line rounded-[2px] px-[7px] py-[3px] text-[10.5px] font-mono", children: t("pages.focus.ownerDecision.legacyBadge") }))] }), _jsx("p", { className: "text-ink-2 text-[13px] leading-relaxed mb-2", children: item.summary }), item.machineRecommendation && (_jsxs("p", { className: "text-ink-3 text-[12.5px] mb-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.ownerDecision.machineRecommendationLabel") }), " ", item.machineRecommendation, item.score !== undefined && _jsx("span", { className: "font-mono ml-1", children: item.score.toFixed(2) })] })), item.kind === "rollout_review" && (_jsx("p", { className: "text-ink-4 text-[12px] mb-1", children: t("pages.focus.ownerDecision.rolloutSafetyNote") })), isTaskDecision ? (_jsxs(_Fragment, { children: [showInstruction && (_jsxs("div", { className: "mt-2 mb-2", children: [_jsx("label", { className: "block font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("pages.focus.ownerDecision.instructionLabel") }), _jsx("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value.slice(0, 500)), "data-testid": `owner-instruction-${item.taskId}`, placeholder: t("pages.focus.ownerDecision.instructionPlaceholder"), className: "w-full border border-line rounded-[var(--radius-md)] bg-surface text-ink px-3 py-2 text-[13px] min-h-[64px] resize-y focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov" })] })), _jsxs("div", { className: "flex flex-wrap gap-2 mt-3", children: [canAccept && (_jsx("button", { type: "button", onClick: () => handleAction("accept_current"), disabled: actionLoading !== null, "data-testid": `owner-accept-${item.taskId}`, className: "inline-flex items-center border border-gov text-gov bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: actionLoading === "accept_current" ? t("common.loading") : t("pages.focus.ownerDecision.acceptCurrent") })), canRevise && (_jsx("button", { type: "button", onClick: () => {
|
|
82
|
+
return (_jsxs("article", { className: "bg-panel border border-line rounded-[6px] p-4 mb-3", "data-testid": `owner-decision-${item.taskId}`, children: [_jsxs("div", { className: "flex items-start justify-between gap-3 mb-2", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-ink text-[14px] font-medium leading-snug", children: item.title }), _jsx("div", { className: "mt-1 text-ink-4 text-[11px] font-mono uppercase tracking-[0.08em]", children: kindLabel })] }), item.legacy && (_jsx("span", { className: "shrink-0 text-ink-4 border border-line rounded-[2px] px-[7px] py-[3px] text-[10.5px] font-mono", children: t("pages.focus.ownerDecision.legacyBadge") }))] }), _jsx("p", { className: "text-ink-2 text-[13px] leading-relaxed mb-2", children: item.summary }), item.review?.brief.kind === "evaluator" && (_jsxs("div", { className: "mb-3 grid gap-2 text-[12.5px] leading-relaxed", children: [item.review.brief.principle?.statement && (_jsxs("p", { children: [_jsx("span", { className: "font-medium text-ink", children: t("pages.focus.ownerDecision.principleLabel") }), " ", item.review.brief.principle.statement] })), item.review.brief.implementation?.summary && (_jsxs("p", { children: [_jsx("span", { className: "font-medium text-ink", children: t("pages.focus.ownerDecision.implementationLabel") }), " ", item.review.brief.implementation.summary] })), (item.review.brief.concerns?.length ?? 0) > 0 && (_jsxs("p", { className: "text-amber", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.ownerDecision.concernLabel") }), " ", item.review.brief.concerns?.[0]] }))] })), item.review?.brief.kind === "rollout" && item.review.brief.summary && (_jsx("p", { className: "mb-3 text-[12.5px] text-ink-2", children: item.review.brief.summary })), item.review && (_jsxs("div", { className: "mb-2 flex flex-wrap gap-2 text-[10.5px] font-mono uppercase tracking-[0.06em]", children: [_jsx("span", { className: "rounded-[2px] border border-line px-2 py-1 text-ink-3", children: t(`pages.focus.ownerDecision.evidence.${item.review.evidence.completeness}`) }), item.review.evidence.deterministicChecks.map(check => (_jsxs("span", { className: "rounded-[2px] border border-line px-2 py-1 text-ink-3", children: [check.check, ": ", check.status] }, check.check)))] })), item.machineRecommendation && (_jsxs("p", { className: "text-ink-3 text-[12.5px] mb-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.ownerDecision.machineRecommendationLabel") }), " ", item.machineRecommendation, item.score !== undefined && _jsx("span", { className: "font-mono ml-1", children: item.score.toFixed(2) })] })), item.kind === "rollout_review" && (_jsx("p", { className: "text-ink-4 text-[12px] mb-1", children: t("pages.focus.ownerDecision.rolloutSafetyNote") })), evidenceUnavailable ? (_jsxs("div", { className: "mt-3 rounded-[3px] border border-amber/40 bg-amber/5 p-3", children: [_jsx("p", { className: "text-ink-2 text-[12.5px] leading-relaxed", children: t("pages.focus.ownerDecision.evidenceUnavailable") }), _jsx(Link, { to: "/failed", "data-testid": `owner-evidence-recover-${item.taskId}`, className: "mt-2 inline-flex items-center border border-line text-ink bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors", children: t("pages.focus.ownerDecision.goRecoverCta") })] })) : isTaskDecision ? (_jsxs(_Fragment, { children: [showInstruction && (_jsxs("div", { className: "mt-2 mb-2", children: [_jsx("label", { className: "block font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("pages.focus.ownerDecision.instructionLabel") }), _jsx("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value.slice(0, 500)), "data-testid": `owner-instruction-${item.taskId}`, placeholder: t("pages.focus.ownerDecision.instructionPlaceholder"), className: "w-full border border-line rounded-[var(--radius-md)] bg-surface text-ink px-3 py-2 text-[13px] min-h-[64px] resize-y focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov" })] })), requiresPartialAcknowledgement && (_jsxs("label", { className: "mt-2 mb-1 flex items-start gap-2 text-[12px] text-ink-3", children: [_jsx("input", { type: "checkbox", checked: partialEvidenceAcknowledged, onChange: (event) => setPartialEvidenceAcknowledged(event.target.checked), "data-testid": `owner-partial-evidence-ack-${item.taskId}`, className: "mt-0.5" }), _jsx("span", { children: t("pages.focus.ownerDecision.partialEvidenceAcknowledgement") })] })), _jsxs("div", { className: "flex flex-wrap gap-2 mt-3", children: [canAccept && (_jsx("button", { type: "button", onClick: () => handleAction("accept_current"), disabled: !governanceReady || actionLoading !== null || (requiresPartialAcknowledgement && !partialEvidenceAcknowledged), "data-testid": `owner-accept-${item.taskId}`, className: "inline-flex items-center border border-gov text-gov bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: actionLoading === "accept_current" ? t("common.loading") : t("pages.focus.ownerDecision.acceptCurrent") })), canRevise && (_jsx("button", { type: "button", onClick: () => {
|
|
76
83
|
if (!showInstruction) {
|
|
77
84
|
setShowInstruction(true);
|
|
78
85
|
return;
|
|
79
86
|
}
|
|
80
87
|
void handleAction("revise_once");
|
|
81
|
-
}, disabled: actionLoading !== null, "data-testid": `owner-revise-${item.taskId}`, className: "inline-flex items-center border border-line text-ink bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: actionLoading === "revise_once" ? t("common.loading") : t("pages.focus.ownerDecision.reviseOnce") })), canReject && (_jsx("button", { type: "button", onClick: () => handleAction("reject_current"), disabled: actionLoading !== null, "data-testid": `owner-reject-${item.taskId}`, className: "inline-flex items-center border border-danger text-danger bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-danger/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: actionLoading === "reject_current" ? t("common.loading") : t("pages.focus.ownerDecision.rejectCurrent") }))] }), _jsx("div", { className: "mt-2 text-ink-4 text-[11.5px] leading-relaxed", children: t("pages.focus.ownerDecision.actionConsequence") }), _jsxs("button", { type: "button", onClick: () => setShowAdvanced(!showAdvanced), className: "mt-2 text-ink-4 text-[11px] font-mono uppercase tracking-[0.08em] hover:text-ink-3", "data-testid": `owner-advanced-toggle-${item.taskId}`, children: [showAdvanced ? "▾" : "▸", " ", t("pages.focus.ownerDecision.advanced")] }), showAdvanced && (_jsxs("dl", { className: "mt-2 grid gap-1 text-[11.5px] font-mono text-ink-4", children: [_jsxs("div", { children: ["taskId: ", item.taskId] }), _jsxs("div", { children: ["reasonCode: ", item.reasonCode] }), _jsxs("div", { children: ["reviewKey: ", item.reviewKey.slice(0, 24), "\u2026"] }), _jsxs("div", { children: ["epoch: ", item.expectedRevisionEpoch] })] }))] })) : (_jsxs("div", { className: "mt-2", children: [_jsx("p", { className: "text-ink-4 text-[12px] mb-2", children: item.kind === "activation_approval"
|
|
88
|
+
}, disabled: !governanceReady || actionLoading !== null, "data-testid": `owner-revise-${item.taskId}`, className: "inline-flex items-center border border-line text-ink bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: actionLoading === "revise_once" ? t("common.loading") : t("pages.focus.ownerDecision.reviseOnce") })), canReject && (_jsx("button", { type: "button", onClick: () => handleAction("reject_current"), disabled: !governanceReady || actionLoading !== null, "data-testid": `owner-reject-${item.taskId}`, className: "inline-flex items-center border border-danger text-danger bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-danger/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: actionLoading === "reject_current" ? t("common.loading") : t("pages.focus.ownerDecision.rejectCurrent") }))] }), _jsx("div", { className: "mt-2 text-ink-4 text-[11.5px] leading-relaxed", children: t("pages.focus.ownerDecision.actionConsequence") }), _jsxs("button", { type: "button", onClick: () => setShowAdvanced(!showAdvanced), className: "mt-2 text-ink-4 text-[11px] font-mono uppercase tracking-[0.08em] hover:text-ink-3", "data-testid": `owner-advanced-toggle-${item.taskId}`, children: [showAdvanced ? "▾" : "▸", " ", t("pages.focus.ownerDecision.advanced")] }), showAdvanced && (_jsxs("dl", { className: "mt-2 grid gap-1 text-[11.5px] font-mono text-ink-4", children: [_jsxs("div", { children: ["taskId: ", item.taskId] }), _jsxs("div", { children: ["reasonCode: ", item.reasonCode] }), _jsxs("div", { children: ["reviewKey: ", item.reviewKey.slice(0, 24), "\u2026"] }), _jsxs("div", { children: ["epoch: ", item.expectedRevisionEpoch] }), item.review?.brief.requiredChanges.map((change, index) => (_jsxs("div", { children: ["requiredChange: ", change] }, `${change}-${index}`))), item.review?.evidence.items.map((evidence, index) => (_jsxs("div", { children: [evidence.evidenceClass, "/", evidence.label, ": ", evidence.value] }, `${evidence.label}-${index}`)))] }))] })) : (_jsxs("div", { className: "mt-2", children: [_jsx("p", { className: "text-ink-4 text-[12px] mb-2", children: item.kind === "activation_approval"
|
|
82
89
|
? t("pages.focus.ownerDecision.approvalHint")
|
|
83
|
-
: t("pages.focus.ownerDecision.rulecodeHint") }), item.kind === "activation_approval" ? (_jsx("
|
|
84
|
-
document.getElementById("approval-queue-section")?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
85
|
-
}, "data-testid": `go-approvals-${item.taskId}`, className: "inline-flex items-center border border-gov text-gov bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/5 transition-colors", children: t("pages.focus.ownerDecision.goApprovalsCta") })) : (_jsx(Link, { to: "/activation", "data-testid": `go-activation-${item.taskId}`, className: "inline-flex items-center border border-gov text-gov bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/5 transition-colors", children: t("pages.focus.ownerDecision.goActivationCta") }))] }))] }));
|
|
90
|
+
: t("pages.focus.ownerDecision.rulecodeHint") }), item.kind === "activation_approval" ? (_jsx(Link, { to: "/principles", "data-testid": `go-approvals-${item.taskId}`, className: "inline-flex items-center border border-gov text-gov bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/5 transition-colors", children: t("pages.focus.ownerDecision.goApprovalsCta") })) : (_jsx(Link, { to: "/activation", "data-testid": `go-activation-${item.taskId}`, className: "inline-flex items-center border border-gov text-gov bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/5 transition-colors", children: t("pages.focus.ownerDecision.goActivationCta") }))] }))] }));
|
|
86
91
|
}
|
|
@@ -319,11 +319,11 @@ export function SettingsPage() {
|
|
|
319
319
|
? t("pages.settings.ownerIdentity.statusMissing")
|
|
320
320
|
: ownerIdentity.resolved.source === "invalid_env"
|
|
321
321
|
? t("pages.settings.ownerIdentity.statusInvalid")
|
|
322
|
-
: t("pages.settings.ownerIdentity.statusConfigured") }), _jsxs("span", { className: "text-ink-3 text-[12px]", children: [ownerIdentity.resolved.source === "env" && t("pages.settings.ownerIdentity.sourceEnv"), ownerIdentity.resolved.source === "file" && t("pages.settings.ownerIdentity.sourceFile"), ownerIdentity.resolved.source === "invalid_env" && t("pages.settings.ownerIdentity.sourceInvalid"), ownerIdentity.resolved.source === "none" && t("pages.settings.ownerIdentity.sourceNone")] })] }), _jsxs("div", { className: "flex items-center gap-2 text-[13px] mb-2", "data-testid": "owner-governance-readiness", "data-ready": ownerIdentity.governance.ownerIdentityConfiguration === "configured" ? "true" : "false", children: [_jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${ownerIdentity.governance.ownerIdentityConfiguration === "configured" ? "bg-green text-ink" : "bg-amber text-ink"}`, role: "status", children: ownerIdentity.governance.ownerIdentityConfiguration === "configured"
|
|
322
|
+
: t("pages.settings.ownerIdentity.statusConfigured") }), _jsxs("span", { className: "text-ink-3 text-[12px]", children: [ownerIdentity.resolved.source === "env" && t("pages.settings.ownerIdentity.sourceEnv"), ownerIdentity.resolved.source === "file" && t("pages.settings.ownerIdentity.sourceFile"), ownerIdentity.resolved.source === "invalid_env" && t("pages.settings.ownerIdentity.sourceInvalid"), ownerIdentity.resolved.source === "none" && t("pages.settings.ownerIdentity.sourceNone")] })] }), _jsxs("div", { className: "flex items-center gap-2 text-[13px] mb-2", "data-testid": "owner-governance-readiness", "data-ready": ownerIdentity.governance.ownerIdentityConfiguration === "configured" && ownerIdentity.governance.authenticationMode === "authenticated" ? "true" : "false", children: [_jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${ownerIdentity.governance.ownerIdentityConfiguration === "configured" && ownerIdentity.governance.authenticationMode === "authenticated" ? "bg-green text-ink" : "bg-amber text-ink"}`, role: "status", children: ownerIdentity.governance.ownerIdentityConfiguration === "configured" && ownerIdentity.governance.authenticationMode === "authenticated"
|
|
323
323
|
? t("pages.settings.ownerIdentity.governanceReady")
|
|
324
|
-
: t("pages.settings.ownerIdentity.governanceNotReady") }), ownerIdentity.governance.ownerIdentityConfiguration !== "configured" && (_jsx("span", { className: "text-ink-3 text-[12px]", children: ownerIdentity.governance.authenticationMode === "no_auth"
|
|
324
|
+
: t("pages.settings.ownerIdentity.governanceNotReady") }), (ownerIdentity.governance.ownerIdentityConfiguration !== "configured" || ownerIdentity.governance.authenticationMode !== "authenticated") && (_jsx("span", { className: "text-ink-3 text-[12px]", children: ownerIdentity.governance.ownerIdentityConfiguration === "configured" && ownerIdentity.governance.authenticationMode === "no_auth"
|
|
325
325
|
? t("pages.settings.ownerIdentity.governanceReasonTokenAuth")
|
|
326
|
-
: t("pages.settings.ownerIdentity.governanceReasonIdentity") }))] }), ownerIdentity.governance.ownerIdentityConfiguration
|
|
326
|
+
: t("pages.settings.ownerIdentity.governanceReasonIdentity") }))] }), ownerIdentity.governance.ownerIdentityConfiguration === "configured" &&
|
|
327
327
|
ownerIdentity.governance.authenticationMode === "no_auth" && (_jsx("div", { className: "text-ink-4 text-[12px] mb-3", "data-testid": "owner-governance-next-action", children: t("pages.settings.ownerIdentity.governanceNextActionTokenAuth") })), ownerIdentity.resolved.error !== undefined && (_jsx("div", { className: "text-danger text-[12px] mb-3", "data-testid": "owner-identity-error", children: ownerIdentity.resolved.error })), ownerIdentity.resolved.source === "invalid_env" && (_jsx("div", { className: "text-ink-4 text-[12px] mb-3", "data-testid": "owner-identity-invalid-env-hint", children: t("pages.settings.ownerIdentity.invalidEnvHint") })), ownerIdentity.resolved.source === "file" && ownerIdentity.fileRecord !== null && (_jsxs("div", { className: "text-ink-4 text-[12px] mb-3 font-mono", children: [t("pages.settings.ownerIdentity.ownerIdLabel"), ": ", ownerIdentity.fileRecord.ownerId, " \u00B7", " ", t("pages.settings.ownerIdentity.registeredAt"), " ", ownerIdentity.fileRecord.registeredAt.slice(0, 10)] })), ownerIdentity.fileError !== undefined && (_jsx("div", { className: "text-danger text-[12px] mb-3", "data-testid": "owner-identity-file-error", children: ownerIdentity.fileError })), ownerIdentity.resolved.source === "env" ? (_jsx("div", { className: "text-ink-4 text-[12px]", children: t("pages.settings.ownerIdentity.envHint") })) : (_jsxs("div", { className: "mt-3", children: [_jsx("label", { htmlFor: "owner-id-input", className: "block text-sm font-medium text-ink mb-1", children: t("pages.settings.ownerIdentity.ownerIdLabel") }), _jsx("input", { id: "owner-id-input", type: "text", value: ownerIdInput, onChange: (e) => setOwnerIdInput(e.target.value), disabled: ownerActionPending, placeholder: "owner-alice", className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov disabled:opacity-50" }), _jsx("label", { htmlFor: "credential-id-input", className: "block text-sm font-medium text-ink mt-3 mb-1", children: t("pages.settings.ownerIdentity.credentialIdLabel") }), _jsx("input", { id: "credential-id-input", type: "text", value: credentialIdInput, onChange: (e) => setCredentialIdInput(e.target.value), disabled: ownerActionPending, placeholder: "cred-...", className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov disabled:opacity-50" }), _jsxs("div", { className: "flex items-center gap-2 mt-3", children: [_jsx("button", { type: "button", onClick: handleRegisterOwner, disabled: ownerActionPending, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.settings.ownerIdentity.register") }), ownerIdentity.resolved.source === "file" && (_jsx("button", { type: "button", onClick: handleUnregisterOwner, disabled: ownerActionPending, className: "border border-line text-ink-3 rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-surface transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: t("pages.settings.ownerIdentity.unregister") }))] })] }))] }))] })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-principle-language", children: [_jsx(SectionTitle, { id: "section-principle-language", children: t("pages.settings.principleLanguage") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-3", children: t("pages.settings.principleLanguageDescription") }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("label", { htmlFor: "output-language-select", className: "text-sm font-medium text-ink", children: [t("pages.settings.principleLanguage"), ":"] }), _jsxs("select", { id: "output-language-select", value: outputLanguage, onChange: (e) => handleOutputLanguageChange(e.target.value), className: "border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov", children: [_jsx("option", { value: "zh-CN", children: t("pages.settings.languageZhCN") }), _jsx("option", { value: "en", children: t("pages.settings.languageEn") })] })] })] })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-sound-alerts", children: [_jsx(SectionTitle, { id: "section-sound-alerts", children: t("pages.settings.notifications") }), _jsx("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "sound-alerts-toggle", className: "block text-sm font-medium text-ink", children: t("pages.settings.soundAlerts") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mt-1", children: t("pages.settings.soundAlertsDescription") })] }), _jsx("button", { id: "sound-alerts-toggle", type: "button", role: "switch", "aria-checked": soundEnabled, onClick: () => setSoundEnabled(!soundEnabled), className: cn("relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", soundEnabled ? "bg-gov" : "bg-line"), children: _jsx("span", { className: cn("inline-block h-4 w-4 transform rounded-full bg-paper transition-transform", soundEnabled ? "translate-x-6" : "translate-x-1") }) })] }) })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-workspaces", children: [_jsx(SectionTitle, { id: "section-workspaces", children: t("pages.settings.workspace") }), workspaces.length > 0 ? (_jsx("div", { className: "space-y-[10px] mb-5", children: workspaces.map((ws) => (_jsx("article", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-ink text-sm", children: ws.name }), _jsx("div", { className: "text-ink-3 text-[13px] mt-1 font-mono break-all", children: ws.path }), _jsxs("div", { className: "text-ink-4 text-[12px] mt-1", children: [t("pages.settings.lastSync"), ":", " ", ws.lastSync ?? "—"] })] }), _jsx("div", { className: "flex items-center gap-2 shrink-0", children: confirmRemove?.workspaceName === ws.name ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-ink-2 text-[12px]", children: t("pages.settings.confirmDeleteDescription", {
|
|
328
328
|
name: ws.name,
|
|
329
329
|
}) }), _jsx("button", { onClick: () => handleRemoveWorkspace(ws.name), className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("common.confirm") }), _jsx("button", { onClick: () => setConfirmRemove(null), className: "border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("common.cancel") })] })) : (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => handleSyncWorkspace(ws.name), className: "border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.settings.syncWorkspace") }), _jsx("button", { onClick: () => setConfirmRemove({ workspaceName: ws.name }), className: "border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.settings.removeWorkspace") })] })) })] }) }, ws.name))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3 mb-5", children: "\u2014" })), _jsx("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsxs("div", { className: "flex items-end gap-3", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("label", { htmlFor: "add-workspace-name", className: "block text-sm font-medium text-ink mb-2", children: t("pages.settings.name") }), _jsx("input", { id: "add-workspace-name", type: "text", value: addName, onChange: (e) => setAddName(e.target.value), placeholder: t("pages.settings.addNamePlaceholder"), className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov" })] }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("label", { htmlFor: "add-workspace-path", className: "block text-sm font-medium text-ink mb-2", children: t("pages.settings.path") }), _jsx("input", { id: "add-workspace-path", type: "text", value: addPath, onChange: (e) => setAddPath(e.target.value), placeholder: t("pages.settings.addPathPlaceholder"), className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov" })] }), _jsx("button", { onClick: handleAddWorkspace, disabled: addName.trim().length === 0 || addPath.trim().length === 0, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed shrink-0 focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.settings.addWorkspace") })] }) })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-onboarding-flag", children: [_jsx(SectionTitle, { id: "section-onboarding-flag", children: t("components.onboardingFlag.title") }), _jsx("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("label", { htmlFor: "onboarding-flag-toggle", className: "block text-sm font-medium text-ink", children: t("components.onboardingFlag.label") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mt-1", children: t("components.onboardingFlag.description") })] }), _jsx("button", { id: "onboarding-flag-toggle", type: "button", role: "switch", "aria-checked": onboardingFlagEnabled ?? false, "aria-label": t("components.onboardingFlag.toggleAriaLabel"), onClick: handleToggleOnboardingFlag, disabled: onboardingFlagEnabled === null, className: cn("relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed", onboardingFlagEnabled ? "bg-gov" : "bg-line"), children: _jsx("span", { className: cn("inline-block h-4 w-4 transform rounded-full bg-paper transition-transform", onboardingFlagEnabled ? "translate-x-6" : "translate-x-1") }) })] }) })] }), _jsxs("section", { "aria-labelledby": "section-onboarding-reset", children: [_jsx(SectionTitle, { id: "section-onboarding-reset", children: t("components.onboardingReset.title") }), _jsx("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsx("button", { onClick: handleResetOnboarding, className: "border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("components.onboardingReset.resetButton") }) })] })] }) }));
|
|
@@ -789,7 +789,7 @@ export interface OwnerIdentityRecordData {
|
|
|
789
789
|
/** Canonical governance readiness — mirrors core OwnerConfigSnapshot. */
|
|
790
790
|
export interface OwnerGovernanceReadinessData {
|
|
791
791
|
authenticationMode: 'authenticated' | 'no_auth';
|
|
792
|
-
ownerIdentityConfiguration: 'configured' | 'missing';
|
|
792
|
+
ownerIdentityConfiguration: 'configured' | 'missing' | 'invalid';
|
|
793
793
|
}
|
|
794
794
|
export interface OwnerIdentityViewData {
|
|
795
795
|
resolved: OwnerIdentityResolvedData;
|
|
@@ -823,11 +823,55 @@ export interface OwnerDecisionItemData {
|
|
|
823
823
|
expectedSourceRunId: string;
|
|
824
824
|
expectedSourceArtifactId: string;
|
|
825
825
|
expectedSourceArtifactHash: string;
|
|
826
|
+
expectedEvidenceDigest?: string;
|
|
827
|
+
review?: OwnerDecisionReviewData;
|
|
828
|
+
evidenceUnavailableReason?: string;
|
|
826
829
|
createdAt: string;
|
|
827
830
|
machineRecommendation?: string;
|
|
828
831
|
score?: number;
|
|
829
832
|
principleId?: string;
|
|
830
833
|
}
|
|
834
|
+
export interface OwnerDecisionReviewData {
|
|
835
|
+
brief: {
|
|
836
|
+
kind: 'evaluator' | 'rollout';
|
|
837
|
+
principle?: {
|
|
838
|
+
title?: string;
|
|
839
|
+
statement?: string;
|
|
840
|
+
rationale?: string;
|
|
841
|
+
scope: string[];
|
|
842
|
+
};
|
|
843
|
+
implementation?: {
|
|
844
|
+
summary?: string;
|
|
845
|
+
affectedTools: string[];
|
|
846
|
+
risks: string[];
|
|
847
|
+
};
|
|
848
|
+
summary?: string;
|
|
849
|
+
strengths?: string[];
|
|
850
|
+
concerns?: string[];
|
|
851
|
+
requiredChanges: string[];
|
|
852
|
+
risks?: string[];
|
|
853
|
+
score?: number;
|
|
854
|
+
};
|
|
855
|
+
evidence: {
|
|
856
|
+
completeness: 'complete' | 'partial' | 'insufficient';
|
|
857
|
+
deterministicChecks: {
|
|
858
|
+
check: string;
|
|
859
|
+
status: 'passed' | 'failed' | 'not_run' | 'unavailable';
|
|
860
|
+
}[];
|
|
861
|
+
items: {
|
|
862
|
+
evidenceClass: string;
|
|
863
|
+
label: string;
|
|
864
|
+
value: string;
|
|
865
|
+
}[];
|
|
866
|
+
digest: string;
|
|
867
|
+
};
|
|
868
|
+
capability: {
|
|
869
|
+
acceptRequirement: {
|
|
870
|
+
kind: 'none' | 'acknowledge_partial_evidence' | 'forbidden';
|
|
871
|
+
reasonCode?: string;
|
|
872
|
+
};
|
|
873
|
+
};
|
|
874
|
+
}
|
|
831
875
|
export interface OwnerDecisionsData {
|
|
832
876
|
items: OwnerDecisionItemData[];
|
|
833
877
|
total: number;
|
|
@@ -136,7 +136,8 @@ export function validateOwnerGovernanceView(value) {
|
|
|
136
136
|
// bundle free of the Node-oriented core barrel (ERR-100).
|
|
137
137
|
const governancePrimaryAttentions = new Set(['setup_required', 'owner_decision_required', 'recovery_required', 'degraded', 'background_processing', 'all_clear']);
|
|
138
138
|
const governanceExperienceReasonCodes = new Set([
|
|
139
|
-
'governance.exp.reason.owner_identity_missing', 'governance.exp.reason.
|
|
139
|
+
'governance.exp.reason.owner_identity_missing', 'governance.exp.reason.owner_identity_invalid',
|
|
140
|
+
'governance.exp.reason.owner_authentication_missing', 'governance.exp.reason.approval_pending',
|
|
140
141
|
'governance.exp.reason.rulecode_owner_decision', 'governance.exp.reason.no_pending_decision',
|
|
141
142
|
'governance.exp.reason.owner_decision_available', 'governance.exp.reason.break_glass_entry',
|
|
142
143
|
'governance.exp.reason.recovery_required', 'governance.exp.reason.source_unavailable',
|
|
@@ -144,7 +145,7 @@ const governanceExperienceReasonCodes = new Set([
|
|
|
144
145
|
'governance.exp.reason.workspace_clear', 'governance.exp.reason.workspace_empty',
|
|
145
146
|
]);
|
|
146
147
|
const governanceExperienceNextActionCodes = new Set([
|
|
147
|
-
'governance.exp.next.configure_owner', 'governance.exp.next.review_approvals',
|
|
148
|
+
'governance.exp.next.configure_owner', 'governance.exp.next.authenticate_console', 'governance.exp.next.review_approvals',
|
|
148
149
|
'governance.exp.next.inspect_recovery', 'governance.exp.next.inspect_sources',
|
|
149
150
|
'governance.exp.next.fix_config', 'governance.exp.next.monitor', 'governance.exp.next.none',
|
|
150
151
|
]);
|
|
@@ -189,7 +190,7 @@ function isGovernanceExperienceSnapshot(value) {
|
|
|
189
190
|
return false;
|
|
190
191
|
if (!isObject(readiness) || !hasOwnFields(readiness, ['authenticationMode', 'ownerIdentityConfiguration', 'governanceActions'])
|
|
191
192
|
|| !isStringEnum(readiness.authenticationMode, new Set(['authenticated', 'no_auth']))
|
|
192
|
-
|| !isStringEnum(readiness.ownerIdentityConfiguration, new Set(['configured', 'missing']))
|
|
193
|
+
|| !isStringEnum(readiness.ownerIdentityConfiguration, new Set(['configured', 'missing', 'invalid']))
|
|
193
194
|
|| !Array.isArray(readiness.governanceActions) || readiness.governanceActions.length !== 3
|
|
194
195
|
|| !readiness.governanceActions.every(isGovernanceActionReadiness))
|
|
195
196
|
return false;
|
|
@@ -2240,7 +2241,7 @@ function parseOwnerGovernanceReadiness(v) {
|
|
|
2240
2241
|
return null;
|
|
2241
2242
|
if (!Object.hasOwn(v, 'authenticationMode') || (v.authenticationMode !== 'authenticated' && v.authenticationMode !== 'no_auth'))
|
|
2242
2243
|
return null;
|
|
2243
|
-
if (!Object.hasOwn(v, 'ownerIdentityConfiguration') || (v.ownerIdentityConfiguration !== 'configured' && v.ownerIdentityConfiguration !== 'missing'))
|
|
2244
|
+
if (!Object.hasOwn(v, 'ownerIdentityConfiguration') || (v.ownerIdentityConfiguration !== 'configured' && v.ownerIdentityConfiguration !== 'missing' && v.ownerIdentityConfiguration !== 'invalid'))
|
|
2244
2245
|
return null;
|
|
2245
2246
|
return { authenticationMode: v.authenticationMode, ownerIdentityConfiguration: v.ownerIdentityConfiguration };
|
|
2246
2247
|
}
|
|
@@ -2329,6 +2330,91 @@ export function validateOwnerIdentityUnregister(v) {
|
|
|
2329
2330
|
// ── PRI-629: unified Owner Decision inbox (owner-decisions API) ──────────────
|
|
2330
2331
|
const OWNER_DECISION_KINDS = new Set(['evaluator_review', 'rollout_review', 'activation_approval', 'rulecode_decision']);
|
|
2331
2332
|
const OWNER_DECISION_ACTIONS = new Set(['accept_current', 'revise_once', 'reject_current', 'approve', 'reject', 'promote', 'reject_after_shadow']);
|
|
2333
|
+
function readOwnerStringArray(value) {
|
|
2334
|
+
if (!Array.isArray(value) || value.some(entry => typeof entry !== 'string'))
|
|
2335
|
+
return null;
|
|
2336
|
+
return value;
|
|
2337
|
+
}
|
|
2338
|
+
function validateOwnerDecisionReview(value) {
|
|
2339
|
+
if (!isObject(value) || !isObject(value.brief) || !isObject(value.evidence) || !isObject(value.capability))
|
|
2340
|
+
return null;
|
|
2341
|
+
const { brief, evidence, capability } = value;
|
|
2342
|
+
if (brief.kind !== 'evaluator' && brief.kind !== 'rollout')
|
|
2343
|
+
return null;
|
|
2344
|
+
const requiredChanges = readOwnerStringArray(brief.requiredChanges);
|
|
2345
|
+
if (requiredChanges === null)
|
|
2346
|
+
return null;
|
|
2347
|
+
const parsedBrief = { kind: brief.kind, requiredChanges };
|
|
2348
|
+
if (brief.kind === 'evaluator') {
|
|
2349
|
+
if (!isObject(brief.principle) || !isObject(brief.implementation))
|
|
2350
|
+
return null;
|
|
2351
|
+
const scope = readOwnerStringArray(brief.principle.scope);
|
|
2352
|
+
const affectedTools = readOwnerStringArray(brief.implementation.affectedTools);
|
|
2353
|
+
const risks = readOwnerStringArray(brief.implementation.risks);
|
|
2354
|
+
const strengths = readOwnerStringArray(brief.strengths);
|
|
2355
|
+
const concerns = readOwnerStringArray(brief.concerns);
|
|
2356
|
+
if (scope === null || affectedTools === null || risks === null || strengths === null || concerns === null)
|
|
2357
|
+
return null;
|
|
2358
|
+
parsedBrief.principle = { scope };
|
|
2359
|
+
for (const key of ['title', 'statement', 'rationale']) {
|
|
2360
|
+
const candidate = brief.principle[key];
|
|
2361
|
+
if (candidate !== undefined && !isString(candidate))
|
|
2362
|
+
return null;
|
|
2363
|
+
if (isString(candidate))
|
|
2364
|
+
parsedBrief.principle[key] = candidate;
|
|
2365
|
+
}
|
|
2366
|
+
parsedBrief.implementation = { affectedTools, risks };
|
|
2367
|
+
if (brief.implementation.summary !== undefined && !isString(brief.implementation.summary))
|
|
2368
|
+
return null;
|
|
2369
|
+
if (isString(brief.implementation.summary))
|
|
2370
|
+
parsedBrief.implementation.summary = brief.implementation.summary;
|
|
2371
|
+
parsedBrief.strengths = strengths;
|
|
2372
|
+
parsedBrief.concerns = concerns;
|
|
2373
|
+
if (brief.score !== undefined && !isNumber(brief.score))
|
|
2374
|
+
return null;
|
|
2375
|
+
if (isNumber(brief.score))
|
|
2376
|
+
parsedBrief.score = brief.score;
|
|
2377
|
+
}
|
|
2378
|
+
else {
|
|
2379
|
+
const risks = readOwnerStringArray(brief.risks);
|
|
2380
|
+
if (risks === null)
|
|
2381
|
+
return null;
|
|
2382
|
+
if (brief.summary !== undefined && !isString(brief.summary))
|
|
2383
|
+
return null;
|
|
2384
|
+
if (isString(brief.summary))
|
|
2385
|
+
parsedBrief.summary = brief.summary;
|
|
2386
|
+
parsedBrief.risks = risks;
|
|
2387
|
+
}
|
|
2388
|
+
if (evidence.completeness !== 'complete' && evidence.completeness !== 'partial' && evidence.completeness !== 'insufficient')
|
|
2389
|
+
return null;
|
|
2390
|
+
if (!isString(evidence.digest) || !Array.isArray(evidence.deterministicChecks) || !Array.isArray(evidence.items))
|
|
2391
|
+
return null;
|
|
2392
|
+
const deterministicChecks = [];
|
|
2393
|
+
for (const entry of evidence.deterministicChecks) {
|
|
2394
|
+
if (!isObject(entry) || !isString(entry.check)
|
|
2395
|
+
|| (entry.status !== 'passed' && entry.status !== 'failed' && entry.status !== 'not_run' && entry.status !== 'unavailable'))
|
|
2396
|
+
return null;
|
|
2397
|
+
deterministicChecks.push({ check: entry.check, status: entry.status });
|
|
2398
|
+
}
|
|
2399
|
+
const items = [];
|
|
2400
|
+
for (const entry of evidence.items) {
|
|
2401
|
+
if (!isObject(entry) || !isString(entry.evidenceClass) || !isString(entry.label) || !isString(entry.value))
|
|
2402
|
+
return null;
|
|
2403
|
+
items.push({ evidenceClass: entry.evidenceClass, label: entry.label, value: entry.value });
|
|
2404
|
+
}
|
|
2405
|
+
if (!isObject(capability.acceptRequirement))
|
|
2406
|
+
return null;
|
|
2407
|
+
const requirement = capability.acceptRequirement;
|
|
2408
|
+
if (requirement.kind !== 'none' && requirement.kind !== 'acknowledge_partial_evidence' && requirement.kind !== 'forbidden')
|
|
2409
|
+
return null;
|
|
2410
|
+
if (requirement.reasonCode !== undefined && !isString(requirement.reasonCode))
|
|
2411
|
+
return null;
|
|
2412
|
+
return {
|
|
2413
|
+
brief: parsedBrief,
|
|
2414
|
+
evidence: { completeness: evidence.completeness, deterministicChecks, items, digest: evidence.digest },
|
|
2415
|
+
capability: { acceptRequirement: { kind: requirement.kind, ...(isString(requirement.reasonCode) ? { reasonCode: requirement.reasonCode } : {}) } },
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2332
2418
|
export function validateOwnerDecisionItem(v) {
|
|
2333
2419
|
if (!isObject(v))
|
|
2334
2420
|
return null;
|
|
@@ -2375,6 +2461,28 @@ export function validateOwnerDecisionItem(v) {
|
|
|
2375
2461
|
expectedSourceArtifactHash,
|
|
2376
2462
|
createdAt,
|
|
2377
2463
|
};
|
|
2464
|
+
if (Object.hasOwn(v, 'expectedEvidenceDigest')) {
|
|
2465
|
+
if (!isString(v.expectedEvidenceDigest))
|
|
2466
|
+
return null;
|
|
2467
|
+
item.expectedEvidenceDigest = v.expectedEvidenceDigest;
|
|
2468
|
+
}
|
|
2469
|
+
if (Object.hasOwn(v, 'review')) {
|
|
2470
|
+
const review = validateOwnerDecisionReview(v.review);
|
|
2471
|
+
if (review === null)
|
|
2472
|
+
return null;
|
|
2473
|
+
if (item.expectedEvidenceDigest !== undefined && item.expectedEvidenceDigest !== review.evidence.digest)
|
|
2474
|
+
return null;
|
|
2475
|
+
item.review = review;
|
|
2476
|
+
}
|
|
2477
|
+
if (Object.hasOwn(v, 'evidenceUnavailableReason')) {
|
|
2478
|
+
if (!isString(v.evidenceUnavailableReason) || v.evidenceUnavailableReason.trim() === '')
|
|
2479
|
+
return null;
|
|
2480
|
+
item.evidenceUnavailableReason = v.evidenceUnavailableReason;
|
|
2481
|
+
}
|
|
2482
|
+
if ((kind === 'evaluator_review' || kind === 'rollout_review')
|
|
2483
|
+
&& item.evidenceUnavailableReason === undefined
|
|
2484
|
+
&& (item.expectedEvidenceDigest === undefined || item.review === undefined))
|
|
2485
|
+
return null;
|
|
2378
2486
|
if (Object.hasOwn(v, 'machineRecommendation')) {
|
|
2379
2487
|
if (!isString(v.machineRecommendation))
|
|
2380
2488
|
return null;
|
|
@@ -1785,9 +1785,6 @@
|
|
|
1785
1785
|
.pt-0 {
|
|
1786
1786
|
padding-top: 0px;
|
|
1787
1787
|
}
|
|
1788
|
-
.pt-0\.5 {
|
|
1789
|
-
padding-top: calc(var(--spacing) * 0.5);
|
|
1790
|
-
}
|
|
1791
1788
|
.pt-1 {
|
|
1792
1789
|
padding-top: var(--spacing);
|
|
1793
1790
|
}
|
|
@@ -2447,9 +2444,6 @@
|
|
|
2447
2444
|
.hover\:rotate-180:hover {
|
|
2448
2445
|
rotate: 180deg;
|
|
2449
2446
|
}
|
|
2450
|
-
.hover\:border-danger:hover {
|
|
2451
|
-
border-color: var(--color-danger);
|
|
2452
|
-
}
|
|
2453
2447
|
.hover\:border-danger\/30:hover {
|
|
2454
2448
|
border-color: color-mix(in srgb, #8b3a3a 30%, transparent);
|
|
2455
2449
|
}
|
|
@@ -2458,9 +2452,6 @@
|
|
|
2458
2452
|
border-color: color-mix(in oklab, var(--color-danger) 30%, transparent);
|
|
2459
2453
|
}
|
|
2460
2454
|
}
|
|
2461
|
-
.hover\:border-gov:hover {
|
|
2462
|
-
border-color: var(--color-gov);
|
|
2463
|
-
}
|
|
2464
2455
|
.hover\:border-line:hover {
|
|
2465
2456
|
border-color: var(--color-line);
|
|
2466
2457
|
}
|