feat(governance): 新增 AI Agent Telegram 預覽審核包
This commit is contained in:
@@ -17,13 +17,16 @@ import {
|
||||
BookOpenCheck,
|
||||
Boxes,
|
||||
CalendarClock,
|
||||
ClipboardCheck,
|
||||
Database,
|
||||
FileText,
|
||||
Fingerprint,
|
||||
GitBranch,
|
||||
Gauge,
|
||||
HardDrive,
|
||||
Layers3,
|
||||
Lock,
|
||||
MessageSquareText,
|
||||
PackageCheck,
|
||||
RefreshCw,
|
||||
Route,
|
||||
@@ -3700,6 +3703,15 @@ export function AutomationInventoryTab() {
|
||||
&& professionalTaskExpansion.redaction_contract.redaction_required === true
|
||||
)
|
||||
const visibleProfessionalTasks = professionalTaskExpansion.professional_tasks.slice(0, 8)
|
||||
const visibleTelegramPreviews = professionalTaskExpansion.telegram_runtime_bridge.no_send_message_previews.slice(0, 6)
|
||||
const professionalTaskCanaryPackage = professionalTaskExpansion.telegram_runtime_bridge.canary_approval_package
|
||||
const professionalTaskPreviewLiveWrites = (
|
||||
professionalTaskExpansion.rollups.preview_send_enabled_count
|
||||
+ professionalTaskExpansion.rollups.preview_queue_write_enabled_count
|
||||
+ professionalTaskExpansion.rollups.preview_bot_api_call_enabled_count
|
||||
+ professionalTaskExpansion.rollups.receipt_live_write_enabled_count
|
||||
+ professionalTaskExpansion.rollups.canary_live_send_enabled_count
|
||||
)
|
||||
const backlogProgressPercent = backlog.progress_summary.overall_percent
|
||||
const explicitApprovalItemCount = backlog.item_approval_boundary_rollup.items_requiring_explicit_approval.length
|
||||
const taskBoundaryCount = snapshot.task_approval_boundary_rollup.total_tasks
|
||||
@@ -4121,6 +4133,10 @@ export function AutomationInventoryTab() {
|
||||
<MetricCard label={t('professionalTaskExpansion.metrics.approvals')} value={professionalTaskApprovals} tone="warn" icon={<ShieldAlert size={16} />} />
|
||||
<MetricCard label={t('professionalTaskExpansion.metrics.highCritical')} value={professionalTaskHighCritical} tone="danger" icon={<AlertTriangle size={16} />} />
|
||||
<MetricCard label={t('professionalTaskExpansion.metrics.liveWrites')} value={professionalTaskLiveWrites} tone={professionalTaskLiveWrites === 0 ? 'ok' : 'danger'} icon={<BellOff size={16} />} />
|
||||
<MetricCard label={t('professionalTaskExpansion.metrics.noSendPreviews')} value={professionalTaskExpansion.rollups.no_send_preview_count} tone="ok" icon={<MessageSquareText size={16} />} />
|
||||
<MetricCard label={t('professionalTaskExpansion.metrics.dedupKeys')} value={professionalTaskExpansion.rollups.dedup_key_count} tone="ok" icon={<Fingerprint size={16} />} />
|
||||
<MetricCard label={t('professionalTaskExpansion.metrics.receipts')} value={professionalTaskExpansion.rollups.receipt_expectation_count} tone="warn" icon={<ClipboardCheck size={16} />} />
|
||||
<MetricCard label={t('professionalTaskExpansion.metrics.previewLiveWrites')} value={professionalTaskPreviewLiveWrites} tone={professionalTaskPreviewLiveWrites === 0 ? 'ok' : 'danger'} icon={<BellOff size={16} />} />
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))', gap: 10 }}>
|
||||
@@ -4152,6 +4168,61 @@ export function AutomationInventoryTab() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SmallLabel>{t('professionalTaskExpansion.previewTitle')}</SmallLabel>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(245px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{visibleTelegramPreviews.map(preview => {
|
||||
const previewTone = preview.risk_tier === 'critical' ? 'danger' : preview.risk_tier === 'high' ? 'warn' : 'neutral'
|
||||
const previewColor = toneColor(previewTone)
|
||||
return (
|
||||
<div key={preview.preview_id} style={{ padding: 10, border: `0.5px solid ${previewColor}55`, borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 7, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'center', minWidth: 0 }}>
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 12, fontWeight: 700, color: '#141413', overflowWrap: 'anywhere' }}>
|
||||
{preview.title}
|
||||
</span>
|
||||
<Chip value={t(`professionalTaskExpansion.riskTiers.${preview.risk_tier}` as never)} muted={preview.risk_tier !== 'critical'} />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
{preview.sanitized_body_lines.slice(0, 3).map(line => (
|
||||
<span key={`${preview.preview_id}-${line}`} style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#5c5a55', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{redactPublicText(line)}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={preview.owner_agent} muted />
|
||||
<Chip value={t('professionalTaskExpansion.labels.dedup', { value: preview.dedup_key })} muted />
|
||||
<Chip value={t('professionalTaskExpansion.labels.receipt', { value: preview.receipt_expectation_id })} muted />
|
||||
<Chip value={t('professionalTaskExpansion.labels.previewSend', { value: String(preview.send_enabled) })} muted />
|
||||
<Chip value={t('professionalTaskExpansion.labels.queueWrites', { value: String(preview.gateway_queue_write_enabled) })} muted />
|
||||
<Chip value={t('professionalTaskExpansion.labels.botCalls', { value: String(preview.bot_api_call_enabled) })} muted />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div style={{ padding: 10, border: '0.5px solid #d7c7a1', borderRadius: 7, background: '#fff', minWidth: 0 }}>
|
||||
<SmallLabel>{t('professionalTaskExpansion.canaryTitle')}</SmallLabel>
|
||||
<p style={{ margin: '6px 0 8px', fontFamily: "'DM Mono', monospace", fontSize: 10, lineHeight: 1.5, color: '#5c5a55', overflowWrap: 'anywhere' }}>
|
||||
{professionalTaskCanaryPackage.package_id} · {professionalTaskCanaryPackage.status}
|
||||
</p>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 8 }}>
|
||||
<Chip value={t('professionalTaskExpansion.labels.packageReady', { value: String(professionalTaskCanaryPackage.package_ready) })} />
|
||||
<Chip value={t('professionalTaskExpansion.labels.canaryApproval', { value: String(professionalTaskCanaryPackage.approval_required) })} muted />
|
||||
<Chip value={t('professionalTaskExpansion.labels.arbiter', { value: professionalTaskCanaryPackage.arbiter })} muted />
|
||||
<Chip value={t('professionalTaskExpansion.labels.owner', { value: professionalTaskCanaryPackage.owner_agent })} muted />
|
||||
<Chip value={t('professionalTaskExpansion.labels.canarySend', { value: String(professionalTaskCanaryPackage.live_send_enabled) })} muted />
|
||||
<Chip value={t('professionalTaskExpansion.labels.productionWrites', { value: String(professionalTaskCanaryPackage.production_write_enabled) })} muted />
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 8 }}>
|
||||
{professionalTaskCanaryPackage.approval_checklist.slice(0, 5).map(item => (
|
||||
<div key={item} style={{ padding: 8, borderRadius: 6, background: '#f8f5ed', fontFamily: "'DM Mono', monospace", fontSize: 10, lineHeight: 1.45, color: '#5c5a55', overflowWrap: 'anywhere' }}>
|
||||
{item}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SmallLabel>{t('professionalTaskExpansion.tasksTitle')}</SmallLabel>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{visibleProfessionalTasks.map(task => {
|
||||
|
||||
@@ -1429,8 +1429,8 @@ export interface AiAgentProfessionalTaskExpansionSnapshot {
|
||||
program_status: {
|
||||
overall_completion_percent: number
|
||||
current_priority: 'P0' | 'P1' | 'P2' | 'P3'
|
||||
current_task_id: 'P2-405A'
|
||||
next_task_id: 'P2-405B'
|
||||
current_task_id: 'P2-405B'
|
||||
next_task_id: 'P2-405C'
|
||||
read_only_mode: true
|
||||
runtime_authority: 'professional_task_expansion_and_telegram_bridge_read_only_no_send'
|
||||
status_note: string
|
||||
@@ -1461,19 +1461,91 @@ export interface AiAgentProfessionalTaskExpansionSnapshot {
|
||||
exit_condition: string
|
||||
}>
|
||||
message_types: Array<{
|
||||
message_type_id: string
|
||||
title: string
|
||||
message_type: string
|
||||
cadence: string
|
||||
risk_scope: string
|
||||
delivery_gate: string
|
||||
risk_tier: string
|
||||
owner_agent: string
|
||||
send_policy: string
|
||||
}>
|
||||
no_send_message_previews: Array<{
|
||||
preview_id: string
|
||||
message_type: string
|
||||
title: string
|
||||
target_room_alias: string
|
||||
target_room_env: string
|
||||
owner_agent: string
|
||||
risk_tier: 'low' | 'medium' | 'high' | 'critical'
|
||||
status: string
|
||||
dedup_key: string
|
||||
receipt_expectation_id: string
|
||||
approval_required_before_send: boolean
|
||||
canary_required_before_live: boolean
|
||||
send_enabled: boolean
|
||||
gateway_queue_write_enabled: boolean
|
||||
bot_api_call_enabled: boolean
|
||||
delivery_receipt_write_enabled: boolean
|
||||
sanitized_body_lines: string[]
|
||||
redaction_checks: string[]
|
||||
}>
|
||||
dedup_policy: {
|
||||
required: boolean
|
||||
key_count: number
|
||||
collision_policy: string
|
||||
preview_hash_algorithm: string
|
||||
live_cache_write_enabled: boolean
|
||||
keys: Array<{
|
||||
message_type: string
|
||||
key_template: string
|
||||
owner_agent: string
|
||||
risk_tier: string
|
||||
window: string
|
||||
live_cache_write_enabled: boolean
|
||||
}>
|
||||
}
|
||||
queue_preview_readback: {
|
||||
enabled: boolean
|
||||
preview_only: boolean
|
||||
write_enabled: boolean
|
||||
readback_enabled: boolean
|
||||
envelope_fields: string[]
|
||||
readback_checks: string[]
|
||||
}
|
||||
receipt_expectations: Array<{
|
||||
receipt_id: string
|
||||
message_type: string
|
||||
preview_id: string
|
||||
expected_signal: string
|
||||
required_evidence_refs: string[]
|
||||
receipt_write_enabled: boolean
|
||||
production_receipt_readback_enabled: boolean
|
||||
missing_receipt_policy: string
|
||||
}>
|
||||
canary_approval_package: {
|
||||
package_id: string
|
||||
status: string
|
||||
package_ready: boolean
|
||||
approval_required: boolean
|
||||
target_room_alias: string
|
||||
target_room_env: string
|
||||
arbiter: string
|
||||
owner_agent: string
|
||||
reviewers: string[]
|
||||
message_type_scope: string[]
|
||||
required_approval_inputs: string[]
|
||||
approval_checklist: string[]
|
||||
live_send_enabled: boolean
|
||||
gateway_queue_write_enabled: boolean
|
||||
bot_api_call_enabled: boolean
|
||||
delivery_receipt_write_enabled: boolean
|
||||
production_write_enabled: boolean
|
||||
}
|
||||
no_send_preview_completion_percent: number
|
||||
canary_approval_package_completion_percent: number
|
||||
}
|
||||
professional_task_domains: Array<{
|
||||
domain_id: string
|
||||
title: string
|
||||
summary: string
|
||||
primary_owner: string
|
||||
task_count: number
|
||||
label: string
|
||||
owner_agent: string
|
||||
}>
|
||||
professional_tasks: Array<{
|
||||
task_id: string
|
||||
@@ -1491,8 +1563,8 @@ export interface AiAgentProfessionalTaskExpansionSnapshot {
|
||||
}>
|
||||
reporting_contract: Record<'daily' | 'weekly' | 'monthly' | 'action_required', {
|
||||
required: boolean
|
||||
delivery_mode: string
|
||||
sections: string[]
|
||||
owner_agent: string
|
||||
telegram_stage: string
|
||||
}>
|
||||
redaction_contract: {
|
||||
redaction_required: boolean
|
||||
@@ -1503,6 +1575,7 @@ export interface AiAgentProfessionalTaskExpansionSnapshot {
|
||||
raw_runtime_payload_display_allowed: boolean
|
||||
telegram_message_must_be_sanitized: boolean
|
||||
frontend_display_policy: string
|
||||
message_preview_redaction_checks: string[]
|
||||
}
|
||||
rollups: {
|
||||
professional_task_count: number
|
||||
@@ -1524,6 +1597,18 @@ export interface AiAgentProfessionalTaskExpansionSnapshot {
|
||||
paid_api_call_count: number
|
||||
host_write_count: number
|
||||
kubectl_action_count: number
|
||||
no_send_preview_count: number
|
||||
dedup_key_count: number
|
||||
receipt_expectation_count: number
|
||||
canary_approval_package_count: number
|
||||
queue_preview_envelope_field_count: number
|
||||
canary_required_preview_count: number
|
||||
approval_required_preview_count: number
|
||||
preview_send_enabled_count: number
|
||||
preview_queue_write_enabled_count: number
|
||||
preview_bot_api_call_enabled_count: number
|
||||
receipt_live_write_enabled_count: number
|
||||
canary_live_send_enabled_count: number
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user