feat(agents): expose autonomous runtime control
Some checks failed
CD Pipeline / tests (push) Successful in 1m43s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
Code Review / ai-code-review (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled

This commit is contained in:
Your Name
2026-06-27 19:31:02 +08:00
parent d359587316
commit ce0c7cbaf8
13 changed files with 1017 additions and 38 deletions

View File

@@ -45,6 +45,7 @@ import { redactPublicIdentifier } from '@/lib/public-security-redaction'
import {
apiClient,
type AiAgent12AgentWarRoomSnapshot,
type AiAgentAutonomousRuntimeControlSnapshot,
type AiAgentProfessionalTaskExpansionSnapshot,
type AiAgentReceiptReadbackOwnerReviewSnapshot,
type AiAgentReportNoWriteAnalysisRuntimeSnapshot,
@@ -849,6 +850,7 @@ function GateMatrixRow({
export function AutomationInventoryTab() {
const t = useTranslations('governance.automationInventory')
const [snapshot, setSnapshot] = useState<AiAgentAutomationInventorySnapshot | null>(null)
const [autonomousRuntimeControl, setAutonomousRuntimeControl] = useState<AiAgentAutonomousRuntimeControlSnapshot | null>(null)
const [backlog, setBacklog] = useState<AiAgentAutomationBacklogSnapshot | null>(null)
const [backupTargets, setBackupTargets] = useState<BackupDrTargetInventorySnapshot | null>(null)
const [backupReadiness, setBackupReadiness] = useState<BackupDrReadinessMatrixSnapshot | null>(null)
@@ -948,6 +950,7 @@ export function AutomationInventoryTab() {
setLoading(true)
const requests = [
apiClient.getAiAgentAutomationInventorySnapshot(),
apiClient.getAiAgentAutonomousRuntimeControl(),
apiClient.getAiAgentAutomationBacklogSnapshot(),
apiClient.getBackupDrTargetInventory(),
apiClient.getBackupDrReadinessMatrix(),
@@ -1040,6 +1043,7 @@ export function AutomationInventoryTab() {
.then((results) => {
const [
inventoryResult,
autonomousRuntimeControlResult,
backlogResult,
targetResult,
readinessResult,
@@ -1129,6 +1133,7 @@ export function AutomationInventoryTab() {
] = results
setSnapshot(settledPublicValue(inventoryResult))
setAutonomousRuntimeControl(settledPublicValue(autonomousRuntimeControlResult))
setBacklog(settledPublicValue(backlogResult))
setBackupTargets(settledPublicValue(targetResult))
setBackupReadiness(settledPublicValue(readinessResult))
@@ -5503,6 +5508,12 @@ export function AutomationInventoryTab() {
tone: hostRedactionLocked && professionalTaskRedactionLocked && warRoomRedactionLocked && serviceHealthRedactionLocked ? 'ok' as const : 'warn' as const,
},
]
const currentAutonomyCadences = autonomousRuntimeControl?.report_delivery.cadences ?? []
const currentAutonomyExecutorReceipts = autonomousRuntimeControl?.controlled_executor.operation_receipts ?? []
const currentAutonomyOverrides = autonomousRuntimeControl?.legacy_policy_overrides ?? []
const currentAutonomyHardBlockers = autonomousRuntimeControl?.hard_blockers ?? []
const currentAutonomyPolicy = autonomousRuntimeControl?.current_policy
const currentAutonomySwitches = autonomousRuntimeControl?.runtime_switches
const globalControlRunwayRows: Array<{
key: string
label: string
@@ -6311,6 +6322,161 @@ export function AutomationInventoryTab() {
]}
/>
{autonomousRuntimeControl ? (
<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 #15803d40',
background: 'rgba(21,128,61,0.08)',
color: '#15803d',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
}}>
<BellRing 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('globalControl.currentAutonomy.title')}
</span>
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 11, color: '#4f6156', lineHeight: 1.55, overflowWrap: 'anywhere' }}>
{autonomousRuntimeControl.program_status.status_note}
</span>
</div>
</div>
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-end', gap: 6, minWidth: 0 }}>
<Chip value={autonomousRuntimeControl.program_status.current_task_id} />
<Chip value={t('globalControl.currentAutonomy.badges.override')} />
<Chip value={t('globalControl.currentAutonomy.badges.gateway')} muted={autonomousRuntimeControl.rollups.telegram_gateway_delivery_enabled_count === 0} />
</div>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(128px, 1fr))', gap: 10 }} className="automation-inventory-global-control-kpi-grid">
<MetricCard label={t('globalControl.currentAutonomy.metrics.completion')} value={`${autonomousRuntimeControl.program_status.implementation_completion_percent}%`} tone="ok" icon={<Gauge size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.riskTiers')} value={`${autonomousRuntimeControl.rollups.automated_risk_tier_count}/3`} tone={autonomousRuntimeControl.rollups.automated_risk_tier_count === 3 ? 'ok' : 'warn'} icon={<ShieldCheck size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.reports')} value={autonomousRuntimeControl.rollups.report_cadence_enabled_count} tone="ok" icon={<CalendarClock size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.gateway')} value={autonomousRuntimeControl.rollups.telegram_gateway_delivery_enabled_count} tone="ok" icon={<BellRing size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.executor')} value={autonomousRuntimeControl.rollups.controlled_executor_operation_receipt_count} tone="ok" icon={<ClipboardCheck size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.hardBlockers')} value={autonomousRuntimeControl.rollups.hard_blocker_count} tone="warn" icon={<ShieldAlert size={16} />} />
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.2fr) minmax(260px, 0.8fr)', gap: 12 }} className="automation-inventory-global-control-grid">
<div style={{ padding: 12, border: '0.5px solid #cfe7d7', borderRadius: 7, background: '#f8fffa', display: 'flex', flexDirection: 'column', gap: 10, minWidth: 0 }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap' }}>
<SmallLabel>{t('globalControl.currentAutonomy.policyTitle')}</SmallLabel>
<Chip value={autonomousRuntimeControl.program_status.runtime_authority} muted />
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: 8 }} className="automation-inventory-global-control-pipeline-grid">
<GateMatrixRow
label={t('globalControl.currentAutonomy.policy.low')}
value={currentAutonomyPolicy?.low_risk_controlled_apply_allowed ? 'on' : 'off'}
detail={t('globalControl.currentAutonomy.policy.noOwnerReview', { value: String(currentAutonomyPolicy?.owner_review_required_for_low_medium_high === false) })}
tone={currentAutonomyPolicy?.low_risk_controlled_apply_allowed ? 'ok' : 'warn'}
/>
<GateMatrixRow
label={t('globalControl.currentAutonomy.policy.medium')}
value={currentAutonomyPolicy?.medium_risk_controlled_apply_allowed ? 'on' : 'off'}
detail={t('globalControl.currentAutonomy.policy.verifier', { value: String(currentAutonomyPolicy?.post_apply_verifier_required === true) })}
tone={currentAutonomyPolicy?.medium_risk_controlled_apply_allowed ? 'ok' : 'warn'}
/>
<GateMatrixRow
label={t('globalControl.currentAutonomy.policy.high')}
value={currentAutonomyPolicy?.high_risk_controlled_apply_allowed ? 'on' : 'off'}
detail={t('globalControl.currentAutonomy.policy.km', { value: String(currentAutonomyPolicy?.km_learning_writeback_required === true) })}
tone={currentAutonomyPolicy?.high_risk_controlled_apply_allowed ? 'ok' : 'warn'}
/>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 8 }}>
{currentAutonomyCadences.map(cadence => (
<div key={cadence.cadence} style={{ padding: 10, border: '0.5px solid #d8e8df', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 6, minWidth: 0 }}>
<div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'flex-start' }}>
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 13, fontWeight: 760, color: '#141413', lineHeight: 1.2, overflowWrap: 'anywhere' }}>
{cadence.display_name}
</span>
<Chip value={cadence.telegram_gateway_delivery_enabled ? 'Gateway on' : 'Gateway off'} muted={!cadence.telegram_gateway_delivery_enabled} />
</div>
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#50665a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
{cadence.schedule}
</span>
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#50665a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
{cadence.worker}
</span>
</div>
))}
</div>
</div>
<div style={{ padding: 12, border: '0.5px solid #e5dbc7', borderRadius: 7, background: '#fffdf7', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
<SmallLabel>{t('globalControl.currentAutonomy.runtimeTitle')}</SmallLabel>
<GateMatrixRow
label={t('globalControl.currentAutonomy.runtime.checkMode')}
value={currentAutonomySwitches?.ansible_check_mode_worker_enabled ? 'on' : 'off'}
detail={`interval=${currentAutonomySwitches?.ansible_check_mode_interval_seconds ?? '--'}s batch=${currentAutonomySwitches?.ansible_check_mode_batch_limit ?? '--'}`}
tone={currentAutonomySwitches?.ansible_check_mode_worker_enabled ? 'ok' : 'warn'}
/>
<GateMatrixRow
label={t('globalControl.currentAutonomy.runtime.apply')}
value={currentAutonomySwitches?.ansible_controlled_apply_enabled ? 'on' : 'off'}
detail={(currentAutonomySwitches?.ansible_controlled_apply_allowed_risk_levels ?? []).join(', ') || '--'}
tone={currentAutonomySwitches?.ansible_controlled_apply_enabled ? 'ok' : 'warn'}
/>
<GateMatrixRow
label={t('globalControl.currentAutonomy.runtime.botApi')}
value={currentAutonomyPolicy?.direct_bot_api_allowed ? 'on' : 'off'}
detail={t('globalControl.currentAutonomy.runtime.gatewayOnly')}
tone={currentAutonomyPolicy?.direct_bot_api_allowed ? 'danger' : 'ok'}
/>
</div>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: 10 }} className="automation-inventory-global-control-runway-grid">
<div style={{ padding: 12, border: '0.5px solid #d7d2f4', borderRadius: 7, background: '#fbfaff', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
<SmallLabel>{t('globalControl.currentAutonomy.executorTitle')}</SmallLabel>
{currentAutonomyExecutorReceipts.slice(0, 5).map(receipt => (
<GateMatrixRow
key={receipt.operation_type}
label={receipt.operation_type}
value={receipt.writes_runtime_state ? 'write' : 'dry'}
detail={`${receipt.owner_agent}: ${receipt.purpose}`}
tone={receipt.writes_runtime_state ? 'warn' : 'ok'}
/>
))}
</div>
<div style={{ padding: 12, border: '0.5px solid #d7e2ea', borderRadius: 7, background: '#f9fcff', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
<SmallLabel>{t('globalControl.currentAutonomy.overrideTitle')}</SmallLabel>
{currentAutonomyOverrides.slice(0, 4).map(row => (
<GateMatrixRow
key={row.legacy_area}
label={row.legacy_area}
value={row.current_effect}
detail={row.new_behavior}
tone="ok"
/>
))}
</div>
<div style={{ padding: 12, border: '0.5px solid #f1d4d4', borderRadius: 7, background: '#fffafa', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
<SmallLabel>{t('globalControl.currentAutonomy.hardBlockerTitle')}</SmallLabel>
{currentAutonomyHardBlockers.slice(0, 5).map(blocker => (
<GateMatrixRow
key={blocker}
label={blocker}
value="blocked"
detail={t('globalControl.currentAutonomy.hardBlockerDetail')}
tone="warn"
/>
))}
</div>
</div>
</div>
</GlassCard>
) : null}
<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' }}>

View File

@@ -843,6 +843,11 @@ export const apiClient = {
return handleResponse<AiAgentAutomationInventorySnapshot>(res)
},
async getAiAgentAutonomousRuntimeControl() {
const res = await fetch(`${API_BASE_URL}/agents/agent-autonomous-runtime-control`)
return handleResponse<AiAgentAutonomousRuntimeControlSnapshot>(res)
},
async getAiAgentAutomationBacklogSnapshot() {
const res = await fetch(`${API_BASE_URL}/agents/automation-backlog-snapshot`)
return handleResponse<AiAgentAutomationBacklogSnapshot>(res)
@@ -1848,6 +1853,91 @@ export interface AiTechnologyReportCadenceReadback {
// AI Agent Automation Inventory Snapshot
// =========================================================================
export interface AiAgentAutonomousRuntimeControlSnapshot {
schema_version: 'ai_agent_autonomous_runtime_control_v1'
generated_at: string
program_status: {
current_task_id: 'P2-416-D1N'
status: string
runtime_authority: 'current_owner_directive_controlled_ai_automation'
legacy_no_send_no_live_rules_overridden: true
implementation_completion_percent: number
status_note: string
}
current_policy: {
low_risk_controlled_apply_allowed: boolean
medium_risk_controlled_apply_allowed: boolean
high_risk_controlled_apply_allowed: boolean
critical_break_glass_required: boolean
owner_review_required_for_low_medium_high: boolean
direct_bot_api_allowed: boolean
telegram_gateway_required: boolean
post_apply_verifier_required: boolean
km_learning_writeback_required: boolean
}
runtime_switches: {
ansible_check_mode_worker_enabled: boolean
ansible_controlled_apply_enabled: boolean
ansible_controlled_apply_allowed_risk_levels: string[]
ansible_check_mode_interval_seconds: number
ansible_check_mode_batch_limit: number
ansible_check_mode_timeout_seconds: number
ansible_controlled_apply_timeout_seconds: number
}
agent_roles: Array<{
agent_id: string
role: string
current_job: string
}>
report_delivery: {
status: string
cadences: Array<{
cadence: 'daily' | 'weekly' | 'monthly'
display_name: string
schedule: string
worker: string
telegram_gateway_delivery_enabled: boolean
direct_bot_api_allowed: boolean
receipt_source: string
}>
}
controlled_executor: {
status: string
operation_receipts: Array<{
operation_type: string
owner_agent: string
purpose: string
writes_runtime_state: boolean
}>
required_flow: string[]
}
legacy_policy_overrides: Array<{
legacy_area: string
current_effect: string
new_behavior: string
}>
hard_blockers: string[]
visibility_contract: {
frontend_displays_runtime_truth: boolean
work_window_transcript_display_allowed: boolean
raw_prompt_display_allowed: boolean
private_reasoning_display_allowed: boolean
secret_value_display_allowed: boolean
raw_telegram_payload_display_allowed: boolean
lan_topology_redaction_required: boolean
}
rollups: {
automated_risk_tier_count: number
hard_blocker_count: number
report_cadence_enabled_count: number
telegram_gateway_delivery_enabled_count: number
direct_bot_api_allowed_count: number
controlled_executor_operation_receipt_count: number
runtime_write_receipt_type_count: number
legacy_policy_overridden_count: number
}
}
export interface AiAgentAutomationInventorySnapshot {
schema_version: 'ai_agent_automation_inventory_snapshot_v1'
generated_at: string