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.
Files changed (162) hide show
  1. package/console/dist/server/index.js +9 -4
  2. package/console/dist/server/models/OwnerDecisionConsoleModel.d.ts +5 -0
  3. package/console/dist/server/models/OwnerDecisionConsoleModel.js +92 -18
  4. package/console/dist/server/routes/governance.js +6 -1
  5. package/console/dist/server/routes/health.d.ts +4 -1
  6. package/console/dist/server/routes/health.js +3 -3
  7. package/console/dist/server/routes/owner-decisions.d.ts +3 -3
  8. package/console/dist/server/routes/owner-decisions.js +41 -3
  9. package/console/dist/ui/api.d.ts +5 -0
  10. package/console/dist/ui/i18n/en.json +22 -1
  11. package/console/dist/ui/i18n/zh-CN.json +22 -1
  12. package/console/dist/ui/pages/focus/FocusPage.js +17 -30
  13. package/console/dist/ui/pages/focus/OwnerDecisionCard.d.ts +2 -1
  14. package/console/dist/ui/pages/focus/OwnerDecisionCard.js +11 -6
  15. package/console/dist/ui/pages/settings/SettingsPage.js +3 -3
  16. package/console/dist/ui/utils/validators.d.ts +45 -1
  17. package/console/dist/ui/utils/validators.js +112 -4
  18. package/console/dist/web/assets/app.css +0 -9
  19. package/console/dist/web/assets/app.js +226 -417
  20. package/core/dist/runtime-v2/__tests__/adversarial-loop.test.js +22 -0
  21. package/core/dist/runtime-v2/__tests__/adversarial-loop.test.js.map +1 -1
  22. package/core/dist/runtime-v2/__tests__/governance-experience.test.js +19 -0
  23. package/core/dist/runtime-v2/__tests__/governance-experience.test.js.map +1 -1
  24. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.d.ts +2 -0
  25. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.d.ts.map +1 -0
  26. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.js +106 -0
  27. package/core/dist/runtime-v2/__tests__/pain-signal-bridge-execute-pending.test.js.map +1 -0
  28. package/core/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.d.ts +2 -0
  29. package/core/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.d.ts.map +1 -0
  30. package/core/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.js +243 -0
  31. package/core/dist/runtime-v2/__tests__/rollout-rule-candidate-contract.test.js.map +1 -0
  32. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +2 -2
  33. package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -1
  34. package/core/dist/runtime-v2/governance-experience-contract.d.ts +16 -16
  35. package/core/dist/runtime-v2/governance-experience-contract.d.ts.map +1 -1
  36. package/core/dist/runtime-v2/governance-experience-contract.js +4 -1
  37. package/core/dist/runtime-v2/governance-experience-contract.js.map +1 -1
  38. package/core/dist/runtime-v2/governance-experience.d.ts.map +1 -1
  39. package/core/dist/runtime-v2/governance-experience.js +30 -8
  40. package/core/dist/runtime-v2/governance-experience.js.map +1 -1
  41. package/core/dist/runtime-v2/index.d.ts +5 -3
  42. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  43. package/core/dist/runtime-v2/index.js +4 -3
  44. package/core/dist/runtime-v2/index.js.map +1 -1
  45. package/core/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.d.ts +2 -0
  46. package/core/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.d.ts.map +1 -0
  47. package/core/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.js +114 -0
  48. package/core/dist/runtime-v2/internalization/__tests__/artificer-code-bearing.test.js.map +1 -0
  49. package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.d.ts +2 -0
  50. package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.d.ts.map +1 -0
  51. package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js +256 -0
  52. package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js.map +1 -0
  53. package/core/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.d.ts +2 -0
  54. package/core/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.d.ts.map +1 -0
  55. package/core/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.js +229 -0
  56. package/core/dist/runtime-v2/internalization/__tests__/owner-decision-review.test.js.map +1 -0
  57. package/core/dist/runtime-v2/internalization/__tests__/owner-decision.test.js +172 -1
  58. package/core/dist/runtime-v2/internalization/__tests__/owner-decision.test.js.map +1 -1
  59. package/core/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.d.ts +2 -0
  60. package/core/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.d.ts.map +1 -0
  61. package/core/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.js +187 -0
  62. package/core/dist/runtime-v2/internalization/__tests__/rule-activation-contract.test.js.map +1 -0
  63. package/core/dist/runtime-v2/internalization/artificer-code-bearing.d.ts +39 -0
  64. package/core/dist/runtime-v2/internalization/artificer-code-bearing.d.ts.map +1 -0
  65. package/core/dist/runtime-v2/internalization/artificer-code-bearing.js +33 -0
  66. package/core/dist/runtime-v2/internalization/artificer-code-bearing.js.map +1 -0
  67. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts +11 -8
  68. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
  69. package/core/dist/runtime-v2/internalization/evaluator-runner.js +170 -31
  70. package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
  71. package/core/dist/runtime-v2/internalization/index.d.ts +2 -0
  72. package/core/dist/runtime-v2/internalization/index.d.ts.map +1 -1
  73. package/core/dist/runtime-v2/internalization/index.js +1 -0
  74. package/core/dist/runtime-v2/internalization/index.js.map +1 -1
  75. package/core/dist/runtime-v2/internalization/internalization-task-guards.d.ts +5 -8
  76. package/core/dist/runtime-v2/internalization/internalization-task-guards.d.ts.map +1 -1
  77. package/core/dist/runtime-v2/internalization/internalization-task-guards.js +11 -12
  78. package/core/dist/runtime-v2/internalization/internalization-task-guards.js.map +1 -1
  79. package/core/dist/runtime-v2/internalization/owner-decision-review.d.ts +98 -0
  80. package/core/dist/runtime-v2/internalization/owner-decision-review.d.ts.map +1 -0
  81. package/core/dist/runtime-v2/internalization/owner-decision-review.js +287 -0
  82. package/core/dist/runtime-v2/internalization/owner-decision-review.js.map +1 -0
  83. package/core/dist/runtime-v2/internalization/owner-resolution-service.d.ts +11 -0
  84. package/core/dist/runtime-v2/internalization/owner-resolution-service.d.ts.map +1 -1
  85. package/core/dist/runtime-v2/internalization/owner-resolution-service.js +117 -4
  86. package/core/dist/runtime-v2/internalization/owner-resolution-service.js.map +1 -1
  87. package/core/dist/runtime-v2/internalization/owner-review.d.ts +4 -0
  88. package/core/dist/runtime-v2/internalization/owner-review.d.ts.map +1 -1
  89. package/core/dist/runtime-v2/internalization/owner-review.js.map +1 -1
  90. package/core/dist/runtime-v2/internalization/pitask-metadata.d.ts +16 -0
  91. package/core/dist/runtime-v2/internalization/pitask-metadata.d.ts.map +1 -1
  92. package/core/dist/runtime-v2/internalization/pitask-metadata.js +62 -0
  93. package/core/dist/runtime-v2/internalization/pitask-metadata.js.map +1 -1
  94. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts +13 -0
  95. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts.map +1 -1
  96. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js +59 -11
  97. package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js.map +1 -1
  98. package/core/dist/runtime-v2/internalization/rule-activation-contract.d.ts +35 -0
  99. package/core/dist/runtime-v2/internalization/rule-activation-contract.d.ts.map +1 -0
  100. package/core/dist/runtime-v2/internalization/rule-activation-contract.js +36 -0
  101. package/core/dist/runtime-v2/internalization/rule-activation-contract.js.map +1 -0
  102. package/core/dist/runtime-v2/pain-signal-bridge.d.ts +40 -0
  103. package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
  104. package/core/dist/runtime-v2/pain-signal-bridge.js +95 -0
  105. package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
  106. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts +10 -4
  107. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
  108. package/core/dist/runtime-v2/pain-signal-runtime-factory.js +86 -51
  109. package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
  110. package/core/dist/runtime-v2/store/runtime-state-manager.d.ts +6 -0
  111. package/core/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
  112. package/core/dist/runtime-v2/store/runtime-state-manager.js +8 -0
  113. package/core/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
  114. package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store-cas.test.js +36 -0
  115. package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store-cas.test.js.map +1 -1
  116. package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts +19 -0
  117. package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts.map +1 -1
  118. package/core/dist/runtime-v2/store/task/sqlite-task-store.js +30 -1
  119. package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
  120. package/dist/installer.d.ts.map +1 -1
  121. package/dist/installer.js +65 -4
  122. package/dist/installer.js.map +1 -1
  123. package/host-runtime/dist/governance-observation-store.d.ts +17 -0
  124. package/host-runtime/dist/governance-observation-store.js +38 -0
  125. package/host-runtime/dist/governance-signal-admission.js +55 -43
  126. package/host-runtime/dist/index.d.ts +3 -0
  127. package/host-runtime/dist/index.js +7 -0
  128. package/host-runtime/dist/internalization-consumer-cycle.d.ts +43 -0
  129. package/host-runtime/dist/internalization-consumer-cycle.js +468 -0
  130. package/host-runtime/dist/internalization-consumer-governance.d.ts +39 -0
  131. package/host-runtime/dist/internalization-consumer-governance.js +152 -0
  132. package/host-runtime/dist/workspace-telemetry-emitter.d.ts +15 -0
  133. package/host-runtime/dist/workspace-telemetry-emitter.js +74 -0
  134. package/install-layout/dist/index.d.ts +10 -0
  135. package/install-layout/dist/index.js +34 -1
  136. package/install-layout/dist/index.test.js +36 -1
  137. package/package.json +2 -2
  138. package/pd-cli/dist/commands/codex-ingest-catchup.d.ts +20 -0
  139. package/pd-cli/dist/commands/codex-ingest-catchup.d.ts.map +1 -0
  140. package/pd-cli/dist/commands/codex-ingest-catchup.js +95 -0
  141. package/pd-cli/dist/commands/codex-ingest-catchup.js.map +1 -0
  142. package/pd-cli/dist/commands/codex-worker.d.ts +20 -0
  143. package/pd-cli/dist/commands/codex-worker.d.ts.map +1 -0
  144. package/pd-cli/dist/commands/codex-worker.js +156 -0
  145. package/pd-cli/dist/commands/codex-worker.js.map +1 -0
  146. package/pd-cli/dist/commands/console.d.ts.map +1 -1
  147. package/pd-cli/dist/commands/console.js +34 -1
  148. package/pd-cli/dist/commands/console.js.map +1 -1
  149. package/pd-cli/dist/index.js +47 -0
  150. package/pd-cli/dist/index.js.map +1 -1
  151. package/pd-cli/dist/services/console-launcher.d.ts +8 -2
  152. package/pd-cli/dist/services/console-launcher.d.ts.map +1 -1
  153. package/pd-cli/dist/services/console-launcher.js +34 -4
  154. package/pd-cli/dist/services/console-launcher.js.map +1 -1
  155. package/pd-cli/package.json +1 -1
  156. package/plugin/dist/bundle.js +534 -524
  157. package/plugin/dist/governance-audit.js +132 -132
  158. package/plugin/dist/rulehost-evidence.js +148 -148
  159. package/plugin/dist/service/internalization-auto-consumer-service.d.ts +11 -0
  160. package/plugin/openclaw.plugin.json +1 -1
  161. package/plugin/package.json +1 -1
  162. 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 ownerGuide = deriveOwnerConfigureGuide(snapshot.readiness.ownerIdentityConfiguration);
429
- 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 }) }))] })), _jsxs("div", { className: "mt-2 text-[12px] text-ink-4 leading-relaxed", "data-testid": "experience-readiness", children: [t(`pages.focus.experience.readiness.identity.${snapshot.readiness.ownerIdentityConfiguration}`), " · ", t("pages.focus.experience.readiness.principleApproval"), t(`pages.focus.experience.readiness.rulecode.${rulecodeAction?.status === "blocked" ? "blocked" : "ready"}`), t(`pages.focus.experience.readiness.pause.${pauseAction?.observedAuthority === "break_glass" ? "breakGlass" : "owner"}`)] }), ownerGuide !== null && (_jsxs("div", { className: "mt-3 border border-line rounded-[6px] bg-panel px-3 py-2.5", "data-testid": "owner-configure-guide", children: [_jsx("div", { className: "text-[13px] font-medium", children: t("pages.focus.experience.ownerGuide.title") }), _jsx("div", { className: "mt-0.5 text-[12px] text-ink-3 leading-relaxed", children: t("pages.focus.experience.ownerGuide.intro") }), _jsx("div", { className: "mt-2 space-y-2", children: ownerGuide.commands.map((cmd, idx) => (_jsxs("div", { className: "border border-line rounded-[4px] overflow-hidden bg-surface", children: [_jsxs("div", { className: "flex items-center justify-between px-2.5 py-1", children: [_jsx("span", { className: "font-mono text-[11px] uppercase text-ink-3", children: t(cmd.labelKey) }), _jsx("button", { type: "button", onClick: async () => {
430
- try {
431
- await navigator.clipboard.writeText(cmd.command);
432
- setCopiedCommandIdx(idx);
433
- setTimeout(() => setCopiedCommandIdx(null), 2000);
434
- }
435
- catch (error) {
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") }), 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"
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, onResolved: () => { void loadData(); } }, item.reviewKey)))] }), !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, {}) })), (ruleCodeErrorReason || ruleCodePending.length > 0 || ruleCodeAlerts.length > 0) && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-rulecode-owner", children: [_jsx(SectionTitle, { id: "section-rulecode-owner", children: t("pages.focus.ruleCodeOwnerQueue") }), ruleCodeErrorReason && (_jsxs("div", { className: "mb-3 rounded border border-amber/30 bg-panel p-4 text-[12px] text-ink-3", children: [_jsx("div", { className: "font-medium text-amber", children: t("pages.focus.ruleCodeUnavailable") }), _jsx("div", { className: "mt-1 font-mono", children: ruleCodeErrorReason }), _jsx("div", { className: "mt-1", children: t("pages.focus.ruleCodeUnavailableNextAction") })] })), _jsxs("div", { className: "grid gap-3 md:grid-cols-2", children: [ruleCodePending.length > 0 && (_jsxs(Link, { to: "/activation", className: "rounded border border-gov/30 bg-panel p-4 hover:border-gov", children: [_jsx("div", { className: "font-medium text-ink", children: t("pages.focus.ruleCodePending") }), _jsx("div", { className: "mt-1 text-[12px] text-ink-3", children: t("pages.focus.ruleCodePendingCount", { count: ruleCodePending.length }) })] })), ruleCodeAlerts.length > 0 && (_jsxs(Link, { to: "/activation", className: "rounded border border-danger/30 bg-panel p-4 hover:border-danger", children: [_jsx("div", { className: "font-medium text-danger", children: t("pages.focus.ruleCodeAlerts") }), _jsx("div", { className: "mt-1 text-[12px] text-ink-3", children: t("pages.focus.ruleCodeAlertCount", { count: ruleCodeAlerts.length }) })] }))] })] })), _jsxs("section", { id: "approval-queue-section", className: "mt-8", "aria-labelledby": "section-pending", children: [_jsx(SectionTitle, { id: "section-pending", children: t("pages.focus.sectionPending") }), pendingGroups.length > 0 ? (_jsx("div", { className: "space-y-[14px]", children: pendingGroups.map((group) => (_jsx(PendingReviewCard, { group: group, onDecisionApplied: loadData }, group.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: approvalDataUnavailable
572
- ? (groupedErrorReason
573
- ? `${t("pages.focus.loadError")} (${groupedErrorReason})`
574
- : t("pages.focus.loadError"))
575
- : t("pages.focus.emptyPending") }))] }), !experienceMode && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-deviation", children: [_jsx(SectionTitle, { id: "section-deviation", children: evidenceCount > 0
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("button", { type: "button", onClick: () => {
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 !== "configured" &&
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.approval_pending',
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
  }