241 lines
8.2 KiB
JSON
241 lines
8.2 KiB
JSON
{
|
||
"schema_version": "ai_agent_redis_dry_run_gate_v1",
|
||
"generated_at": "2026-06-11T23:58:00+08:00",
|
||
"program_status": {
|
||
"overall_completion_percent": 65,
|
||
"current_priority": "P2",
|
||
"current_task_id": "P2-403C",
|
||
"next_task_id": "P2-403D",
|
||
"read_only_mode": true,
|
||
"runtime_authority": "dry_run_contract_only_no_redis_runtime",
|
||
"status_note": "P2-403C 已把 Redis Streams consumer group dry-run、handoff envelope、ack、dead-letter 與 replay gate 固定為只讀契約;尚未連 Redis、未建立 consumer group、未 XADD、未 XREADGROUP、未 ACK、未 replay、未發 Telegram、未做 learning writeback。"
|
||
},
|
||
"source_refs": [
|
||
"docs/evaluations/ai_agent_live_read_model_gate_2026-06-11.json",
|
||
"apps/api/src/services/signal_producer.py",
|
||
"apps/api/src/main.py:Signal Worker",
|
||
"docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md"
|
||
],
|
||
"dry_run_truth": {
|
||
"redis_connection_allowed": false,
|
||
"consumer_group_created": false,
|
||
"xadd_allowed": false,
|
||
"xreadgroup_allowed": false,
|
||
"ack_allowed": false,
|
||
"dead_letter_write_allowed": false,
|
||
"replay_runtime_allowed": false,
|
||
"telegram_send_allowed": false,
|
||
"learning_writeback_allowed": false,
|
||
"live_dry_run_event_count": 0,
|
||
"live_ack_count": 0,
|
||
"live_dead_letter_count": 0,
|
||
"live_replay_count": 0,
|
||
"truth_note": "目前只允許 fixture / snapshot 層 dry-run 設計;治理頁看得到每一步需要什麼證據,但 production Redis runtime 全部維持關閉。"
|
||
},
|
||
"consumer_group_dry_run_contract": {
|
||
"candidate_group_name": "awoooi-agent-handoff-dry-run",
|
||
"stream_namespace": "awoooi:agent:*",
|
||
"fixture_only": true,
|
||
"redis_network_call_allowed": false,
|
||
"required_fixture_fields": [
|
||
"event_id",
|
||
"trace_id",
|
||
"session_id",
|
||
"incident_id",
|
||
"from_agent",
|
||
"to_agent",
|
||
"handoff_type",
|
||
"event_status",
|
||
"idempotency_key",
|
||
"redacted_evidence_ref",
|
||
"created_at"
|
||
],
|
||
"forbidden_fixture_fields": [
|
||
"secret_value",
|
||
"credential_value",
|
||
"raw_prompt",
|
||
"conversation_transcript",
|
||
"private_reasoning",
|
||
"chain_of_thought",
|
||
"raw_tool_output"
|
||
],
|
||
"dry_run_assertion": "fixture replay 必須能決定 ack / dead-letter / replay lane,但不得連 Redis 或寫任何 runtime queue。"
|
||
},
|
||
"handoff_envelope_contract": {
|
||
"required_fields": [
|
||
"event_id",
|
||
"trace_id",
|
||
"session_id",
|
||
"incident_id",
|
||
"from_agent",
|
||
"to_agent",
|
||
"handoff_type",
|
||
"handoff_reason",
|
||
"evidence_summary",
|
||
"redacted_evidence_ref",
|
||
"required_next_action",
|
||
"idempotency_key",
|
||
"created_at"
|
||
],
|
||
"forbidden_fields": [
|
||
"secret_value",
|
||
"credential_value",
|
||
"raw_prompt",
|
||
"conversation_transcript",
|
||
"private_reasoning",
|
||
"chain_of_thought",
|
||
"raw_tool_output"
|
||
],
|
||
"redacted_evidence_required": true,
|
||
"idempotency_key_required": true,
|
||
"operator_meaning": "每次 Agent 接手都必須能說清楚誰交給誰、為什麼交、下一步是什麼、證據在哪裡;但不顯示未脫敏 payload 或未核准內部細節。"
|
||
},
|
||
"ack_dead_letter_replay_contract": {
|
||
"ack_requires_verifier": true,
|
||
"dead_letter_requires_reason": true,
|
||
"replay_requires_idempotency": true,
|
||
"runtime_replay_allowed": false,
|
||
"ack_allowed_statuses": [
|
||
"validated_no_write",
|
||
"duplicate_idempotency_key",
|
||
"operator_review_recorded"
|
||
],
|
||
"dead_letter_reasons": [
|
||
"missing_required_field",
|
||
"forbidden_payload_detected",
|
||
"unknown_agent_lane",
|
||
"stale_or_replayed_without_idempotency",
|
||
"execution_intent_detected"
|
||
],
|
||
"replay_preconditions": [
|
||
"fixture_only",
|
||
"idempotency_key_present",
|
||
"redacted_evidence_ref_present",
|
||
"no_runtime_write",
|
||
"no_telegram_send"
|
||
]
|
||
},
|
||
"dry_run_steps": [
|
||
{
|
||
"step_id": "fixture_envelope_validation",
|
||
"display_name": "Fixture envelope 驗證",
|
||
"owner_agent": "hermes",
|
||
"status": "contract_ready",
|
||
"operator_signal": "固定 fixture 必須通過必填欄位、idempotency key 與 redacted evidence refs 檢查。",
|
||
"blocked_runtime_action": "redis_xadd"
|
||
},
|
||
{
|
||
"step_id": "consumer_group_plan",
|
||
"display_name": "Consumer group 方案",
|
||
"owner_agent": "openclaw",
|
||
"status": "approval_required",
|
||
"operator_signal": "只定義 group name、stream namespace、pending / ack / dead-letter 行為,不建立 Redis group。",
|
||
"blocked_runtime_action": "redis_xgroup_create"
|
||
},
|
||
{
|
||
"step_id": "ack_decision_fixture",
|
||
"display_name": "ACK 判定 fixture",
|
||
"owner_agent": "openclaw",
|
||
"status": "contract_ready",
|
||
"operator_signal": "dry-run 可判斷哪些事件應 ack,但不執行 XACK。",
|
||
"blocked_runtime_action": "redis_xack"
|
||
},
|
||
{
|
||
"step_id": "dead_letter_fixture",
|
||
"display_name": "Dead-letter 分流 fixture",
|
||
"owner_agent": "hermes",
|
||
"status": "contract_ready",
|
||
"operator_signal": "缺欄位、敏感 payload、未知 lane 或 execution intent 必須進 dead-letter 候選。",
|
||
"blocked_runtime_action": "dead_letter_write"
|
||
},
|
||
{
|
||
"step_id": "replay_idempotency_fixture",
|
||
"display_name": "Replay idempotency fixture",
|
||
"owner_agent": "nemotron",
|
||
"status": "approval_required",
|
||
"operator_signal": "replay 必須先證明 idempotency,不得把重放當成 runtime 自動執行。",
|
||
"blocked_runtime_action": "runtime_replay"
|
||
}
|
||
],
|
||
"handoff_lanes": [
|
||
{
|
||
"lane_id": "diagnosis_to_rule_review",
|
||
"display_name": "診斷 → 規則審核",
|
||
"from_agent": "openclaw",
|
||
"to_agent": "hermes",
|
||
"status": "contract_ready",
|
||
"required_evidence": "alert category、matched rule、evidence summary、blocked reason、redacted evidence ref。"
|
||
},
|
||
{
|
||
"lane_id": "rule_review_to_repair_candidate",
|
||
"display_name": "規則審核 → 修復候選",
|
||
"from_agent": "hermes",
|
||
"to_agent": "openclaw",
|
||
"status": "approval_required",
|
||
"required_evidence": "PlayBook trust、MCP evidence refs、risk gate、repair candidate safety。"
|
||
},
|
||
{
|
||
"lane_id": "repair_candidate_to_replay_review",
|
||
"display_name": "修復候選 → replay 審核",
|
||
"from_agent": "openclaw",
|
||
"to_agent": "nemotron",
|
||
"status": "blocked_by_runtime_gate",
|
||
"required_evidence": "sanitized fixture、idempotency key、no-write replay result、operator review lane。"
|
||
}
|
||
],
|
||
"approval_boundaries": {
|
||
"redis_connection_allowed": false,
|
||
"consumer_group_creation_allowed": false,
|
||
"xadd_allowed": false,
|
||
"xreadgroup_allowed": false,
|
||
"xack_allowed": false,
|
||
"dead_letter_write_allowed": false,
|
||
"runtime_replay_allowed": false,
|
||
"worker_start_allowed": false,
|
||
"telegram_send_allowed": false,
|
||
"learning_writeback_allowed": false,
|
||
"secret_plaintext_allowed": false
|
||
},
|
||
"display_redaction_contract": {
|
||
"redaction_required": true,
|
||
"raw_payload_display_allowed": false,
|
||
"private_reasoning_display_allowed": false,
|
||
"secret_value_display_allowed": false,
|
||
"allowed_frontend_content": [
|
||
"dry-run status",
|
||
"handoff lane",
|
||
"agent role",
|
||
"required fields count",
|
||
"blocked runtime action",
|
||
"redacted evidence ref",
|
||
"next gate"
|
||
],
|
||
"forbidden_frontend_content": [
|
||
"未脫敏 payload",
|
||
"提示內容",
|
||
"未核准內部細節",
|
||
"機密值",
|
||
"raw tool output"
|
||
],
|
||
"frontend_display_policy": "治理頁只顯示 dry-run 狀態、handoff lane、欄位數、阻擋動作與下一步;未脫敏 payload、未核准內部細節、機密值與 raw tool output 不進前端。"
|
||
},
|
||
"rollups": {
|
||
"source_ref_count": 4,
|
||
"dry_run_step_count": 5,
|
||
"handoff_lane_count": 3,
|
||
"contract_ready_step_ids": [
|
||
"ack_decision_fixture",
|
||
"dead_letter_fixture",
|
||
"fixture_envelope_validation"
|
||
],
|
||
"approval_required_step_ids": [
|
||
"consumer_group_plan",
|
||
"replay_idempotency_fixture"
|
||
],
|
||
"blocked_runtime_action_count": 5,
|
||
"required_handoff_field_count": 13,
|
||
"forbidden_field_count": 7,
|
||
"live_truth_count_total": 0
|
||
}
|
||
}
|