feat(governance): add AI agent version lifecycle proposals
Some checks failed
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / tests (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
Some checks failed
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / tests (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
This commit is contained in:
@@ -66,6 +66,7 @@ import {
|
||||
type AiAgentOperationPermissionModelSnapshot,
|
||||
type AiAgentPostWriteVerifierPackageSnapshot,
|
||||
type AiAgentProactiveOperationsContractSnapshot,
|
||||
type AiAgentVersionLifecycleUpdateProposalSnapshot,
|
||||
type AiAgentRedisDryRunGateSnapshot,
|
||||
type AiAgentOwnerApprovedResultCaptureDryRunSnapshot,
|
||||
type AiAgentOwnerApprovedResultCaptureReadbackSnapshot,
|
||||
@@ -867,6 +868,7 @@ export function AutomationInventoryTab() {
|
||||
const [actionOwnerAcceptanceEventBus, setActionOwnerAcceptanceEventBus] = useState<AiAgentActionOwnerAcceptanceEventBusSnapshot | null>(null)
|
||||
const [hostRunawayAiops, setHostRunawayAiops] = useState<HostRunawayAiopsLoopReadinessSnapshot | null>(null)
|
||||
const [proactiveOperations, setProactiveOperations] = useState<AiAgentProactiveOperationsContractSnapshot | null>(null)
|
||||
const [versionLifecycleProposal, setVersionLifecycleProposal] = useState<AiAgentVersionLifecycleUpdateProposalSnapshot | null>(null)
|
||||
const [interactionLearningProof, setInteractionLearningProof] = useState<AiAgentInteractionLearningProofSnapshot | null>(null)
|
||||
const [liveReadModelGate, setLiveReadModelGate] = useState<AiAgentLiveReadModelGateSnapshot | null>(null)
|
||||
const [redisDryRunGate, setRedisDryRunGate] = useState<AiAgentRedisDryRunGateSnapshot | null>(null)
|
||||
@@ -964,6 +966,7 @@ export function AutomationInventoryTab() {
|
||||
apiClient.getAiAgentActionOwnerAcceptanceEventBus(),
|
||||
apiClient.getHostRunawayAiopsLoopReadiness(),
|
||||
apiClient.getAiAgentProactiveOperationsContract(),
|
||||
apiClient.getAiAgentVersionLifecycleUpdateProposal(),
|
||||
apiClient.getAiAgentInteractionLearningProof(),
|
||||
apiClient.getAiAgentLiveReadModelGate(),
|
||||
apiClient.getAiAgentRedisDryRunGate(),
|
||||
@@ -1054,6 +1057,7 @@ export function AutomationInventoryTab() {
|
||||
actionOwnerAcceptanceEventBusResult,
|
||||
hostRunawayAiopsResult,
|
||||
proactiveOperationsResult,
|
||||
versionLifecycleProposalResult,
|
||||
interactionLearningProofResult,
|
||||
liveReadModelGateResult,
|
||||
redisDryRunGateResult,
|
||||
@@ -1141,6 +1145,7 @@ export function AutomationInventoryTab() {
|
||||
setActionOwnerAcceptanceEventBus(settledPublicValue(actionOwnerAcceptanceEventBusResult))
|
||||
setHostRunawayAiops(settledPublicValue(hostRunawayAiopsResult))
|
||||
setProactiveOperations(settledPublicValue(proactiveOperationsResult))
|
||||
setVersionLifecycleProposal(settledPublicValue(versionLifecycleProposalResult))
|
||||
setInteractionLearningProof(settledPublicValue(interactionLearningProofResult))
|
||||
setLiveReadModelGate(settledPublicValue(liveReadModelGateResult))
|
||||
setRedisDryRunGate(settledPublicValue(redisDryRunGateResult))
|
||||
@@ -1228,6 +1233,7 @@ export function AutomationInventoryTab() {
|
||||
highRiskOwnerReviewQueueResult,
|
||||
hostRunawayAiopsResult,
|
||||
proactiveOperationsResult,
|
||||
versionLifecycleProposalResult,
|
||||
interactionLearningProofResult,
|
||||
liveReadModelGateResult,
|
||||
redisDryRunGateResult,
|
||||
@@ -2791,6 +2797,23 @@ export function AutomationInventoryTab() {
|
||||
.slice(0, 5)
|
||||
}, [dependencySupplyChainDriftMonitor])
|
||||
|
||||
const visibleVersionLifecycleProposals = useMemo(() => {
|
||||
if (!versionLifecycleProposal) return []
|
||||
const priorityOrder = { P1: 0, P2: 1, P3: 2, P0: 3 } as Record<string, number>
|
||||
const riskPriority = { critical: 0, high: 1, medium: 2, low: 3 } as Record<string, number>
|
||||
return [...versionLifecycleProposal.update_proposals]
|
||||
.sort((a, b) => {
|
||||
const leftPriority = priorityOrder[a.priority] ?? 4
|
||||
const rightPriority = priorityOrder[b.priority] ?? 4
|
||||
if (leftPriority !== rightPriority) return leftPriority - rightPriority
|
||||
const leftRisk = riskPriority[a.risk_tier] ?? 4
|
||||
const rightRisk = riskPriority[b.risk_tier] ?? 4
|
||||
if (leftRisk !== rightRisk) return leftRisk - rightRisk
|
||||
return a.proposal_id.localeCompare(b.proposal_id)
|
||||
})
|
||||
.slice(0, 6)
|
||||
}, [versionLifecycleProposal])
|
||||
|
||||
if (loading) {
|
||||
if (reportTruthActionabilityReview) {
|
||||
return (
|
||||
@@ -2835,7 +2858,7 @@ export function AutomationInventoryTab() {
|
||||
)
|
||||
}
|
||||
|
||||
if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !warRoom || !professionalTaskExpansion || !receiptReadbackOwnerReview || !reportNoWriteAnalysisRuntime || !lowMediumRiskWhitelist || !highRiskOwnerReviewQueue || !actionAuditLedger || !actionOwnerAcceptanceEventBus || !hostRunawayAiops || !proactiveOperations || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportStatusBoard || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !runtimeReadbackApprovalPackage || !runtimeReadbackImplementationReview || !reportLiveDeliveryApprovalPackage || !runtimeReadbackFixtureApproval || !runtimeReadbackPromotionGate || !ownerApprovedFixturePromotionGate || !canonicalRuntimeReadbackOwnerAcceptance || !failureReceiptNoSendReplay || !reviewerQueueNoWriteReadback || !resultCaptureNoWriteReadback || !resultCapturePromotionApprovalGate || !ownerApprovedResultCapturePromotionDryRun || !resultCaptureWriteGateReview || !resultCaptureWriterImplementationReview || !resultCaptureWriterDryRunFixture || !resultCaptureWriterDryRunReadback || !resultCaptureOwnerPromotionReview || !resultCaptureOwnerApprovedExecutionRehearsal || !resultCaptureOwnerAcceptanceMaintenanceGate || !resultCaptureOwnerAcceptanceReadbackPreflightHold || !resultCaptureOwnerApprovedPreflightReleasePackage || !resultCaptureOwnerApprovedReleaseReadinessReadback || !resultCaptureOwnerReleaseApprovalGate || !resultCapturePostReleaseVerifierRollbackGate || !resultCaptureFinalReleaseCandidateReadback || !resultCaptureReleaseAuthorizationHold || !resultCaptureReleaseAuthorizationReadbackGate || !resultCaptureReleaseVerifierPreflightGate || !resultCaptureReleaseVerifierOwnerReviewPacket || !resultCaptureReleaseDecisionHold || !resultCaptureReleaseDecisionReadback || !resultCaptureReleaseDecisionNextHandoff || !resultCaptureReleaseDecisionInputPrep || !resultCaptureReleaseDecisionOwnerResponsePreflight || !resultCaptureReleaseDecisionOwnerResponseReadback || !resultCaptureReleaseDecisionOwnerResponseAcceptanceGate || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !dependencySupplyChainDriftMonitor || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) {
|
||||
if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !warRoom || !professionalTaskExpansion || !receiptReadbackOwnerReview || !reportNoWriteAnalysisRuntime || !lowMediumRiskWhitelist || !highRiskOwnerReviewQueue || !actionAuditLedger || !actionOwnerAcceptanceEventBus || !hostRunawayAiops || !proactiveOperations || !versionLifecycleProposal || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportStatusBoard || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !runtimeReadbackApprovalPackage || !runtimeReadbackImplementationReview || !reportLiveDeliveryApprovalPackage || !runtimeReadbackFixtureApproval || !runtimeReadbackPromotionGate || !ownerApprovedFixturePromotionGate || !canonicalRuntimeReadbackOwnerAcceptance || !failureReceiptNoSendReplay || !reviewerQueueNoWriteReadback || !resultCaptureNoWriteReadback || !resultCapturePromotionApprovalGate || !ownerApprovedResultCapturePromotionDryRun || !resultCaptureWriteGateReview || !resultCaptureWriterImplementationReview || !resultCaptureWriterDryRunFixture || !resultCaptureWriterDryRunReadback || !resultCaptureOwnerPromotionReview || !resultCaptureOwnerApprovedExecutionRehearsal || !resultCaptureOwnerAcceptanceMaintenanceGate || !resultCaptureOwnerAcceptanceReadbackPreflightHold || !resultCaptureOwnerApprovedPreflightReleasePackage || !resultCaptureOwnerApprovedReleaseReadinessReadback || !resultCaptureOwnerReleaseApprovalGate || !resultCapturePostReleaseVerifierRollbackGate || !resultCaptureFinalReleaseCandidateReadback || !resultCaptureReleaseAuthorizationHold || !resultCaptureReleaseAuthorizationReadbackGate || !resultCaptureReleaseVerifierPreflightGate || !resultCaptureReleaseVerifierOwnerReviewPacket || !resultCaptureReleaseDecisionHold || !resultCaptureReleaseDecisionReadback || !resultCaptureReleaseDecisionNextHandoff || !resultCaptureReleaseDecisionInputPrep || !resultCaptureReleaseDecisionOwnerResponsePreflight || !resultCaptureReleaseDecisionOwnerResponseReadback || !resultCaptureReleaseDecisionOwnerResponseAcceptanceGate || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !dependencySupplyChainDriftMonitor || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) {
|
||||
return (
|
||||
<div style={{ padding: 20 }}>
|
||||
<GlassCard variant="subtle" padding="lg">
|
||||
@@ -3025,6 +3048,43 @@ export function AutomationInventoryTab() {
|
||||
active: dependencySupplyChainDriftMonitor.monitor_boundaries.production_write_allowed,
|
||||
},
|
||||
]
|
||||
const versionLifecycleBoundaryRows = [
|
||||
{
|
||||
key: 'updates',
|
||||
label: t('versionLifecycleProposal.boundaries.updates'),
|
||||
active: versionLifecycleProposal.runtime_boundaries.package_upgrade_allowed
|
||||
|| versionLifecycleProposal.runtime_boundaries.host_upgrade_allowed
|
||||
|| versionLifecycleProposal.runtime_boundaries.k3s_upgrade_allowed,
|
||||
},
|
||||
{
|
||||
key: 'containers',
|
||||
label: t('versionLifecycleProposal.boundaries.containers'),
|
||||
active: versionLifecycleProposal.runtime_boundaries.image_pull_allowed
|
||||
|| versionLifecycleProposal.runtime_boundaries.docker_build_allowed
|
||||
|| versionLifecycleProposal.runtime_boundaries.registry_push_allowed,
|
||||
},
|
||||
{
|
||||
key: 'automation',
|
||||
label: t('versionLifecycleProposal.boundaries.automation'),
|
||||
active: versionLifecycleProposal.runtime_boundaries.schedule_activation_allowed
|
||||
|| versionLifecycleProposal.runtime_boundaries.pr_creation_allowed
|
||||
|| versionLifecycleProposal.runtime_boundaries.auto_merge_allowed,
|
||||
},
|
||||
{
|
||||
key: 'telegram',
|
||||
label: t('versionLifecycleProposal.boundaries.telegram'),
|
||||
active: versionLifecycleProposal.telegram_digest_contract.direct_send_allowed
|
||||
|| versionLifecycleProposal.telegram_digest_contract.gateway_queue_write_allowed
|
||||
|| versionLifecycleProposal.telegram_digest_contract.bot_api_call_allowed,
|
||||
},
|
||||
{
|
||||
key: 'production',
|
||||
label: t('versionLifecycleProposal.boundaries.production'),
|
||||
active: versionLifecycleProposal.runtime_boundaries.provider_route_switch_allowed
|
||||
|| versionLifecycleProposal.runtime_boundaries.production_write_allowed
|
||||
|| versionLifecycleProposal.runtime_boundaries.openclaw_replacement_allowed,
|
||||
},
|
||||
]
|
||||
const receiptOwnerReviewOverall = receiptReadbackOwnerReview.program_status.overall_completion_percent
|
||||
const receiptOwnerReviewSources = receiptReadbackOwnerReview.rollups.source_readback_count
|
||||
const receiptOwnerReviewCadences = receiptReadbackOwnerReview.rollups.report_cadence_count
|
||||
@@ -6681,6 +6741,148 @@ export function AutomationInventoryTab() {
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard variant="subtle" padding="md">
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 14, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'flex-start', gap: 10, minWidth: 0 }}>
|
||||
<div style={{
|
||||
width: 38,
|
||||
height: 38,
|
||||
borderRadius: 8,
|
||||
border: '0.5px solid #38bdf840',
|
||||
background: 'rgba(56,189,248,0.08)',
|
||||
color: '#0284c7',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexShrink: 0,
|
||||
}}>
|
||||
<RefreshCw size={18} />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 5, minWidth: 0 }}>
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 18, fontWeight: 760, color: '#141413', lineHeight: 1.15, overflowWrap: 'anywhere' }}>
|
||||
{t('versionLifecycleProposal.title')}
|
||||
</span>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 11, color: '#5c5a55', lineHeight: 1.55, overflowWrap: 'anywhere' }}>
|
||||
{t('versionLifecycleProposal.subtitle', {
|
||||
current: versionLifecycleProposal.program_status.current_task_id,
|
||||
next: versionLifecycleProposal.program_status.next_task_id,
|
||||
proposals: versionLifecycleProposal.rollups.proposal_count,
|
||||
gates: versionLifecycleProposal.rollups.approval_gate_count,
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-end', gap: 6, minWidth: 0 }}>
|
||||
<Chip value={t('versionLifecycleProposal.badges.readOnly')} />
|
||||
<Chip value={t('versionLifecycleProposal.badges.telegram', { value: versionLifecycleProposal.rollups.telegram_direct_send_count })} muted />
|
||||
<Chip value={t('versionLifecycleProposal.badges.production', { value: versionLifecycleProposal.rollups.production_write_count })} muted />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, minmax(0, 1fr))', gap: 10 }} className="automation-inventory-kpi-grid">
|
||||
{[
|
||||
{ label: t('versionLifecycleProposal.metrics.overall'), value: `${versionLifecycleProposal.program_status.overall_completion_percent}%`, tone: 'ok' as const, icon: <Gauge size={15} /> },
|
||||
{ label: t('versionLifecycleProposal.metrics.domains'), value: versionLifecycleProposal.rollups.domain_count, tone: 'ok' as const, icon: <Layers3 size={15} /> },
|
||||
{ label: t('versionLifecycleProposal.metrics.proposals'), value: versionLifecycleProposal.rollups.proposal_count, tone: 'warn' as const, icon: <ClipboardCheck size={15} /> },
|
||||
{ label: t('versionLifecycleProposal.metrics.critical'), value: versionLifecycleProposal.rollups.critical_candidate_count, tone: 'warn' as const, icon: <ShieldAlert size={15} /> },
|
||||
{ label: t('versionLifecycleProposal.metrics.blocked'), value: versionLifecycleProposal.rollups.false_runtime_boundary_count, tone: 'ok' as const, icon: <Lock size={15} /> },
|
||||
{ label: t('versionLifecycleProposal.metrics.autoExecute'), value: versionLifecycleProposal.rollups.auto_execution_allowed_count, tone: 'ok' as const, icon: <ShieldCheck size={15} /> },
|
||||
].map(metric => {
|
||||
const color = toneColor(metric.tone)
|
||||
return (
|
||||
<div key={metric.label} style={{ padding: 11, border: '0.5px solid #e0ddd4', borderRadius: 7, background: '#fff', minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
|
||||
<div style={{ color, flexShrink: 0 }}>{metric.icon}</div>
|
||||
<SmallLabel>{metric.label}</SmallLabel>
|
||||
</div>
|
||||
<div style={{ marginTop: 7, fontFamily: 'Syne, sans-serif', fontSize: 23, fontWeight: 760, lineHeight: 1, color }}>
|
||||
{metric.value}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.35fr) minmax(260px, 0.65fr)', gap: 12 }} className="automation-inventory-visual-grid">
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 9, minWidth: 0 }}>
|
||||
<SmallLabel>{t('versionLifecycleProposal.sections.proposals')}</SmallLabel>
|
||||
{visibleVersionLifecycleProposals.map(proposal => (
|
||||
<div key={proposal.proposal_id} style={{ padding: 11, border: '0.5px solid #e0ddd4', borderRadius: 7, background: '#fff', minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, flexWrap: 'wrap' }}>
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 13, fontWeight: 760, color: '#141413', overflowWrap: 'anywhere' }}>
|
||||
{proposal.display_name}
|
||||
</span>
|
||||
<Chip value={proposal.priority} muted={proposal.priority !== 'P1'} />
|
||||
</div>
|
||||
<div style={{ marginTop: 7, fontFamily: "'DM Mono', monospace", fontSize: 10, lineHeight: 1.55, color: '#5c5a55', overflowWrap: 'anywhere' }}>
|
||||
{redactPublicText(proposal.summary)}
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 8 }}>
|
||||
<Chip value={`${t('versionLifecycleProposal.labels.owner')}: ${proactiveValueLabel('agents', proposal.owner_agent)}`} />
|
||||
<Chip value={`${t('versionLifecycleProposal.labels.risk')}: ${proactiveValueLabel('risks', proposal.risk_tier)}`} muted={proposal.risk_tier === 'medium'} />
|
||||
<Chip value={`${t('versionLifecycleProposal.labels.gate')}: ${proposal.approval_gate}`} muted />
|
||||
<Chip value={`${t('versionLifecycleProposal.labels.evidence')}: ${proposal.evidence_refs.length}`} muted />
|
||||
<Chip value={`${t('versionLifecycleProposal.labels.rollback')}: ${proposal.rollback_plan.length}`} muted />
|
||||
<Chip value={`${t('versionLifecycleProposal.labels.blocked')}: ${proposal.blocked_runtime_actions.length}`} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12, minWidth: 0 }}>
|
||||
<div style={{ padding: 12, border: '0.5px solid #e0ddd4', borderRadius: 7, background: '#faf9f3', minWidth: 0 }}>
|
||||
<SmallLabel>{t('versionLifecycleProposal.sections.boundaries')}</SmallLabel>
|
||||
<div style={{ marginTop: 7 }}>
|
||||
{versionLifecycleBoundaryRows.map(row => (
|
||||
<GateMatrixRow
|
||||
key={row.key}
|
||||
label={row.label}
|
||||
value={String(row.active)}
|
||||
detail={row.active ? t('versionLifecycleProposal.labels.boundaryOpen') : t('versionLifecycleProposal.labels.boundaryClosed')}
|
||||
tone={row.active ? 'danger' : 'ok'}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ padding: 12, border: '0.5px solid #e0ddd4', borderRadius: 7, background: '#fff', minWidth: 0 }}>
|
||||
<SmallLabel>{t('versionLifecycleProposal.sections.cadence')}</SmallLabel>
|
||||
<div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 8 }}>
|
||||
{versionLifecycleProposal.cadence_matrix.slice(0, 4).map(cadence => (
|
||||
<div key={cadence.cadence_id} style={{ display: 'flex', flexDirection: 'column', gap: 5, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'center', minWidth: 0 }}>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, fontWeight: 700, color: '#141413', overflowWrap: 'anywhere' }}>
|
||||
{cadence.cadence_id}
|
||||
</span>
|
||||
<Chip value={cadence.allowed_now ? t('versionLifecycleProposal.labels.allowedNow') : t('versionLifecycleProposal.labels.ownerGate')} muted={!cadence.allowed_now} />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#87867f', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{redactPublicText(cadence.output)}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ padding: 12, border: '0.5px solid #e0ddd4', borderRadius: 7, background: '#fff', minWidth: 0 }}>
|
||||
<SmallLabel>{t('versionLifecycleProposal.sections.telegram')}</SmallLabel>
|
||||
<div style={{ marginTop: 8, display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={versionLifecycleProposal.telegram_digest_contract.status} />
|
||||
<Chip value={`${t('versionLifecycleProposal.labels.drafts')}: ${versionLifecycleProposal.telegram_digest_contract.draft_outputs.length}`} muted />
|
||||
<Chip value={`${t('versionLifecycleProposal.labels.redaction')}: ${String(versionLifecycleProposal.telegram_digest_contract.redaction_required)}`} muted />
|
||||
</div>
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<Chip value={t('versionLifecycleProposal.source', {
|
||||
generated: formatDateTime(versionLifecycleProposal.generated_at),
|
||||
current: versionLifecycleProposal.program_status.current_task_id,
|
||||
next: versionLifecycleProposal.program_status.next_task_id,
|
||||
})} muted />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard variant="subtle" padding="md">
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 14, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
|
||||
|
||||
@@ -397,6 +397,11 @@ export const apiClient = {
|
||||
return handleResponse<AiAgentProactiveOperationsContractSnapshot>(res)
|
||||
},
|
||||
|
||||
async getAiAgentVersionLifecycleUpdateProposal() {
|
||||
const res = await fetch(`${API_BASE_URL}/agents/agent-version-lifecycle-update-proposal`)
|
||||
return handleResponse<AiAgentVersionLifecycleUpdateProposalSnapshot>(res)
|
||||
},
|
||||
|
||||
async getAiAgentInteractionLearningProof() {
|
||||
const res = await fetch(`${API_BASE_URL}/agents/agent-interaction-learning-proof`)
|
||||
return handleResponse<AiAgentInteractionLearningProofSnapshot>(res)
|
||||
@@ -2447,6 +2452,104 @@ export interface AiAgentProactiveOperationsContractSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
export interface AiAgentVersionLifecycleUpdateProposalSnapshot {
|
||||
schema_version: 'ai_agent_version_lifecycle_update_proposal_v1'
|
||||
generated_at: string
|
||||
program_status: {
|
||||
overall_completion_percent: number
|
||||
current_priority: 'P0' | 'P1' | 'P2' | 'P3'
|
||||
current_task_id: string
|
||||
next_task_id: string
|
||||
read_only_mode: true
|
||||
runtime_authority: string
|
||||
status_note: string
|
||||
}
|
||||
source_refs: string[]
|
||||
agent_roles: Array<{
|
||||
agent_id: 'openclaw' | 'hermes' | 'nemotron'
|
||||
role: string
|
||||
responsibility: string
|
||||
}>
|
||||
lifecycle_domains: Array<{
|
||||
domain_id: string
|
||||
display_name: string
|
||||
owner_agent: 'openclaw' | 'hermes' | 'nemotron'
|
||||
risk_tier: 'low' | 'medium' | 'high' | 'critical'
|
||||
cadence: string
|
||||
decision_policy: string
|
||||
current_authority: string
|
||||
}>
|
||||
update_proposals: Array<{
|
||||
proposal_id: string
|
||||
domain_id: string
|
||||
display_name: string
|
||||
owner_agent: 'openclaw' | 'hermes' | 'nemotron'
|
||||
priority: 'P0' | 'P1' | 'P2' | 'P3'
|
||||
risk_tier: 'low' | 'medium' | 'high' | 'critical'
|
||||
status: string
|
||||
summary: string
|
||||
evidence_refs: string[]
|
||||
approval_gate: string
|
||||
requires_owner_approval: true
|
||||
direct_update_allowed: false
|
||||
auto_execution_allowed: false
|
||||
validation_plan: string[]
|
||||
rollback_plan: string[]
|
||||
blocked_runtime_actions: string[]
|
||||
telegram_policy: string
|
||||
}>
|
||||
cadence_matrix: Array<{
|
||||
cadence_id: string
|
||||
frequency: string
|
||||
scope: string
|
||||
allowed_now: boolean
|
||||
owner_agent: 'openclaw' | 'hermes' | 'nemotron'
|
||||
output: string
|
||||
}>
|
||||
approval_gate_matrix: Array<{
|
||||
gate_id: string
|
||||
risk_tier: 'low' | 'medium' | 'high' | 'critical'
|
||||
owner_approval_required: true
|
||||
auto_execute_allowed: false
|
||||
required_evidence: string[]
|
||||
}>
|
||||
telegram_digest_contract: {
|
||||
status: string
|
||||
direct_send_allowed: false
|
||||
gateway_queue_write_allowed: false
|
||||
bot_api_call_allowed: false
|
||||
success_noise_suppression: boolean
|
||||
draft_outputs: string[]
|
||||
redaction_required: boolean
|
||||
}
|
||||
runtime_boundaries: Record<string, boolean>
|
||||
rollups: {
|
||||
domain_count: number
|
||||
proposal_count: number
|
||||
cadence_count: number
|
||||
approval_gate_count: number
|
||||
read_only_proposal_count: number
|
||||
approval_required_count: number
|
||||
critical_candidate_count: number
|
||||
high_candidate_count: number
|
||||
false_runtime_boundary_count: number
|
||||
auto_execution_allowed_count: number
|
||||
telegram_direct_send_count: number
|
||||
telegram_gateway_queue_write_count: number
|
||||
production_write_count: number
|
||||
update_allowed_count: number
|
||||
domain_ids: string[]
|
||||
proposal_ids: string[]
|
||||
}
|
||||
next_actions: Array<{
|
||||
task_id: string
|
||||
priority: 'P0' | 'P1' | 'P2' | 'P3'
|
||||
owner_agent: 'openclaw' | 'hermes' | 'nemotron'
|
||||
summary: string
|
||||
gate: string
|
||||
}>
|
||||
}
|
||||
|
||||
export interface HostRunawayAiopsLoopReadinessSnapshot {
|
||||
schema_version: 'host_runaway_aiops_loop_readiness_v1'
|
||||
generated_at: string
|
||||
|
||||
Reference in New Issue
Block a user