{
  "version": "kg_quality_gate.v1",
  "generated_at": "2026-03-28T12:51:04.063285Z",
  "profile": "fix_only",
  "candidate_run_dir": "outputs/daozu_closure_fix_only_smoke_20260328",
  "baseline_run_dir": "",
  "gate_config": {
    "phase1": {
      "max_run_errors": 0,
      "require_stage_status_ok": true,
      "stage_status": {
        "required_stages": [
          "closure_fix",
          "type_consolidation"
        ]
      },
      "chunks": {
        "min_chunks": 1,
        "oversize_tolerance_chars": 80,
        "max_oversize_ratio": 0.0,
        "min_avg_fill_ratio": 0.55
      },
      "ontology": {
        "min_samples": 1,
        "min_candidate_entity_types": 3,
        "min_candidate_relation_types": 3,
        "min_entity_taxonomy": 8,
        "min_relation_taxonomy": 4
      },
      "kg": {
        "min_entities_per_chunk": 1.0,
        "min_relations_per_chunk": 1.0,
        "min_observations_per_chunk": 8.0,
        "max_ambiguous_entity_forks": 6,
        "require_ontology_loaded": false,
        "min_supplement_ratio_when_high_density": 0.3
      },
      "type_consolidation": {
        "max_other_after_abs": 3,
        "max_other_after_ratio": 0.2,
        "require_not_worse_than_before": true
      },
      "baseline_diff": {
        "min_relations_delta_pct": -20.0,
        "min_observations_delta_pct": -20.0,
        "max_other_after_delta": 1,
        "max_llm_calls_delta_pct": 50.0,
        "max_run_errors_delta": 0
      },
      "golden_manifest": {
        "min_match_ratio": 1.0,
        "allow_missing_chunks": false
      }
    },
    "kg_lite": {
      "enabled": false,
      "require_stage_status_ok": true,
      "require_artifacts": true,
      "min_kept_entities": 1,
      "min_kept_relations": 1,
      "require_not_exceed_source": true,
      "require_decisions_payload": true,
      "require_source_paths": true,
      "require_summary_store_alignment": true
    },
    "fix_only": {
      "enabled": true,
      "expected_start_stage": "closure_fix",
      "expected_stop_stage": "type_consolidation",
      "expected_stage_rows": [
        "closure_fix",
        "type_consolidation"
      ],
      "require_manifest_bounds": true,
      "require_exact_stage_rows": true,
      "require_zero_llm_calls": true,
      "require_zero_run_errors": true
    }
  },
  "candidate": {
    "summary": {
      "run_dir": "daozu_closure_fix_only_smoke_20260328",
      "run_id": "20260327T172224884310Z",
      "created_at": "2026-03-27T17:22:24.909126Z",
      "out_dir": "outputs/daozu_closure_fix_only_smoke_20260328",
      "input_path": "/wwwb/aitools/writer/input/道祖是克苏鲁.txt",
      "input_sha256": "5c05796b90b9a1956f3fe767cd8288965db478acac5dbed44f64419f0fea185d",
      "provider": "deepseek",
      "video_provider": "doubao",
      "enable_video": false,
      "style_preset": "电影化叙事，细节清晰，角色形象一致，光照连续",
      "limits": {
        "max_chars": 1800,
        "limit_chunks": 3,
        "limit_scenes": null,
        "limit_shots": null
      },
      "status": "ok",
      "errors": 0,
      "counts": {
        "chunks": 3,
        "ontology_samples": 3,
        "ontology_candidate_entity_types": 3,
        "ontology_candidate_relation_types": 5,
        "ontology_entity_taxonomy": 13,
        "ontology_relation_taxonomy": 5,
        "observations": 53,
        "entities": 23,
        "relations": 18,
        "type_candidates": 20,
        "type_apply_type_count": 1,
        "type_apply_subtype_count": 8,
        "type_other_before": 2,
        "type_other_after": 1,
        "entity_registry_entities": 0,
        "entity_visual_cards": 0,
        "entity_voice_cards": 0,
        "entity_asset_bindings": 0,
        "scenes": 0,
        "chronology_scenes": 0,
        "chronology_groups": 0,
        "chronology_edges": 0,
        "chronology_conflicts": 0,
        "adaptation_scenes": 0,
        "adaptation_groups": 0,
        "adaptation_beats": 0,
        "adaptation_retain_scenes": 0,
        "adaptation_compress_scenes": 0,
        "adaptation_bridge_scenes": 0,
        "adaptation_drop_scenes": 0,
        "scripts": 0,
        "shots": 0,
        "style_fixed_positive_terms": 0,
        "style_fixed_negative_terms": 0,
        "style_provider_profiles": 0,
        "style_manual_override_slots": 0,
        "style_reference_ready_entities": 0,
        "storyboards": 0,
        "prompt_guard_shots": 0,
        "prompt_guard_pass_shots": 0,
        "prompt_guard_warning_shots": 0,
        "prompt_guard_fail_shots": 0,
        "prompt_guard_issue_count": 0,
        "segments": 0,
        "captions": 0,
        "audio_tasks": 0,
        "audio_results": 0,
        "video_tasks": 0,
        "video_results": 0,
        "manual_video_attempts": 0,
        "manual_video_task_covered_count": 0,
        "manual_video_result_ready_count": 0,
        "manual_video_eval_count": 0,
        "manual_video_selected_count": 0
      },
      "paths": {
        "project": "project.json",
        "manifest": "run_manifest.json",
        "chunks": "01_chunks.json",
        "ontology_samples": "01b_ontology_samples.json",
        "ontology_candidates": "01c_ontology_candidates.json",
        "ontology_doc": "01d_ontology.json",
        "kg": "02_kg.json",
        "kg_store": "02_kg_store.json",
        "kg_observations": "02_kg_observations.jsonl",
        "kg_closure": "02a_kg_closure.json",
        "kg_store_closure": "02a_kg_store_closure.json",
        "kg_closure_decisions": "02a_kg_closure_decisions.json",
        "type_candidates": "02b_type_candidates.json",
        "type_consolidation": "02c_type_consolidation.json",
        "kg_consolidated": "02d_kg_consolidated.json",
        "kg_store_consolidated": "02d_kg_store_consolidated.json",
        "entity_registry": "02e_entity_registry.json",
        "entity_visual_cards": "02f_entity_visual_cards.json",
        "entity_voice_cards": "02g_entity_voice_cards.json",
        "entity_assets": "02h_entity_assets.json",
        "kg_lite": "02i_kg_lite.json",
        "kg_lite_store": "02i_kg_lite_store.json",
        "kg_lite_decisions": "02i_kg_lite_decisions.json",
        "kg_deep": "02j_kg_deep.json",
        "kg_deep_store": "02j_kg_deep_store.json",
        "kg_deep_decisions": "02j_kg_deep_decisions.json",
        "scenes": "03_scenes.json",
        "chronology": "03b_chronology.json",
        "adaptation": "03c_adaptation.json",
        "scripts": "04_scripts.json",
        "style_bible": "04b_style_bible.json",
        "storyboard": "05_storyboard.json",
        "prompt_guard": "05b_storyboard_guard.json",
        "timeline": "06_timeline.json",
        "audio_tasks": "06b_audio_tasks.json",
        "audio_results": "06c_audio_results.json",
        "video_tasks": "07_video_tasks.json",
        "video_results": "07_video_results.json",
        "manual_video_runs": "07b_manual_video_runs.json",
        "manual_video_eval": "07c_manual_video_eval.json",
        "events": "logs/run_events.jsonl",
        "errors": "logs/run_errors.jsonl",
        "stage_timings": "logs/stage_timings.jsonl",
        "llm_calls": "logs/llm_calls.jsonl",
        "report_html": "logs/run_report.html",
        "report_md": "logs/run_report.md",
        "metrics": "logs/run_metrics.json"
      },
      "updated_at": "2026-03-28T12:51:04.062426Z",
      "run_uid": "20260327T172224884310Z",
      "run_key": "20260327T172224884310Z",
      "trace_scope": "live",
      "is_current_live": true,
      "archive_rel": "",
      "web_paths": {
        "run_root": "",
        "logs_dir": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/logs/",
        "llm_dir": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/logs/llm/",
        "manifest": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/run_manifest.json",
        "project": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/project.json",
        "report_html": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/logs/run_report.html",
        "report_md": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/logs/run_report.md",
        "metrics": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/logs/run_metrics.json",
        "events": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/logs/run_events.jsonl",
        "errors": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/logs/run_errors.jsonl",
        "stage_timings": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/logs/stage_timings.jsonl",
        "llm_calls": "/novel2video/runs/daozu_closure_fix_only_smoke_20260328/logs/llm_calls.jsonl"
      }
    },
    "counts": {
      "chunks": 3,
      "ontology_samples": 3,
      "ontology_candidate_entity_types": 3,
      "ontology_candidate_relation_types": 5,
      "ontology_entity_taxonomy": 13,
      "ontology_relation_taxonomy": 5,
      "observations": 53,
      "entities": 23,
      "relations": 18,
      "type_candidates": 20,
      "type_apply_type_count": 1,
      "type_apply_subtype_count": 8,
      "type_other_before": 2,
      "type_other_after": 1,
      "entity_registry_entities": 0,
      "entity_visual_cards": 0,
      "entity_voice_cards": 0,
      "entity_asset_bindings": 0,
      "scenes": 0,
      "chronology_scenes": 0,
      "chronology_groups": 0,
      "chronology_edges": 0,
      "chronology_conflicts": 0,
      "adaptation_scenes": 0,
      "adaptation_groups": 0,
      "adaptation_beats": 0,
      "adaptation_retain_scenes": 0,
      "adaptation_compress_scenes": 0,
      "adaptation_bridge_scenes": 0,
      "adaptation_drop_scenes": 0,
      "scripts": 0,
      "shots": 0,
      "style_fixed_positive_terms": 0,
      "style_fixed_negative_terms": 0,
      "style_provider_profiles": 0,
      "style_manual_override_slots": 0,
      "style_reference_ready_entities": 0,
      "storyboards": 0,
      "prompt_guard_shots": 0,
      "prompt_guard_pass_shots": 0,
      "prompt_guard_warning_shots": 0,
      "prompt_guard_fail_shots": 0,
      "prompt_guard_issue_count": 0,
      "segments": 0,
      "captions": 0,
      "audio_tasks": 0,
      "audio_results": 0,
      "video_tasks": 0,
      "video_results": 0,
      "manual_video_attempts": 0,
      "manual_video_task_covered_count": 0,
      "manual_video_result_ready_count": 0,
      "manual_video_eval_count": 0,
      "manual_video_selected_count": 0,
      "llm_calls": 0,
      "run_errors": 0
    },
    "stage_rows": [
      {
        "ts_start": "2026-03-27T17:22:29.309829Z",
        "ts_end": "2026-03-27T17:22:29.365665Z",
        "duration_sec": 0.056,
        "stage": "closure_fix",
        "status": "ok",
        "run_id": "20260327T172224884310Z",
        "agent": "Contextual Closure & Cleanup Agent",
        "inputs": [
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02_kg_store.json",
            "kind": "kg_store"
          },
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02_kg_observations.jsonl",
            "kind": "kg_observations"
          }
        ],
        "outputs": [
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02a_kg_closure.json",
            "kind": "kg_summary_closure"
          },
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02a_kg_store_closure.json",
            "kind": "kg_store_closure"
          },
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02a_kg_closure_decisions.json",
            "kind": "kg_closure_decisions"
          }
        ],
        "metrics": {
          "entities": 23,
          "relations": 18,
          "closure_decision_count": 0,
          "closure_drop_count": 0,
          "closure_merge_count": 0,
          "stub_cleanup_dropped_entities": 0,
          "stub_cleanup_dropped_relations": 0,
          "stub_cleanup_merged_duplicate_entities": 0,
          "stub_cleanup_merged_same_name_entities": 0,
          "stub_cleanup_merged_duplicate_relations": 0,
          "resumed": false
        }
      },
      {
        "ts_start": "2026-03-27T17:22:29.385146Z",
        "ts_end": "2026-03-27T17:22:29.428440Z",
        "duration_sec": 0.043,
        "stage": "type_consolidation",
        "status": "ok",
        "run_id": "20260327T172224884310Z",
        "agent": "Ontology & Taxonomy Agent",
        "inputs": [
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02a_kg_store_closure.json",
            "kind": "kg_store_closure"
          },
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/01d_ontology.json",
            "kind": "ontology_doc"
          }
        ],
        "outputs": [
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02b_type_candidates.json",
            "kind": "type_candidates"
          },
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02c_type_consolidation.json",
            "kind": "type_consolidation"
          },
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02d_kg_store_consolidated.json",
            "kind": "kg_store_consolidated"
          },
          {
            "path": "/wwwb/aitools/writer/outputs/daozu_closure_fix_only_smoke_20260328/02d_kg_consolidated.json",
            "kind": "kg_summary_consolidated"
          }
        ],
        "metrics": {
          "candidates": 20,
          "apply_type_count": 1,
          "apply_subtype_count": 8,
          "review_type_count": 3,
          "review_subtype_count": 5,
          "other_before": 2,
          "other_after": 1,
          "ontology_loaded": true,
          "resumed": false
        }
      }
    ],
    "stage_metrics": {
      "closure_fix": {
        "status": "ok",
        "duration_sec": 0.056,
        "metrics": {
          "entities": 23,
          "relations": 18,
          "closure_decision_count": 0,
          "closure_drop_count": 0,
          "closure_merge_count": 0,
          "stub_cleanup_dropped_entities": 0,
          "stub_cleanup_dropped_relations": 0,
          "stub_cleanup_merged_duplicate_entities": 0,
          "stub_cleanup_merged_same_name_entities": 0,
          "stub_cleanup_merged_duplicate_relations": 0,
          "resumed": false
        }
      },
      "type_consolidation": {
        "status": "ok",
        "duration_sec": 0.043,
        "metrics": {
          "candidates": 20,
          "apply_type_count": 1,
          "apply_subtype_count": 8,
          "review_type_count": 3,
          "review_subtype_count": 5,
          "other_before": 2,
          "other_after": 1,
          "ontology_loaded": true,
          "resumed": false
        }
      }
    },
    "quality_metrics": {
      "chunks": {
        "chunk_count": 3,
        "avg_chunk_chars": 1754.0,
        "max_chunk_chars": 1787,
        "avg_fill_ratio": null,
        "oversize_chunks": 0
      },
      "ontology": {
        "sample_count": 3,
        "sample_coverage_ratio": 1.0,
        "candidate_entity_types": 3,
        "candidate_relation_types": 5,
        "taxonomy_entity_types": 13,
        "taxonomy_relations": 5
      },
      "kg": {
        "entity_count": 23,
        "relation_count": 18,
        "observation_count": 53,
        "entity_per_chunk": 7.666667,
        "relation_per_chunk": 6.0,
        "observation_per_chunk": 17.666667,
        "ambiguous_entity_forks": 0,
        "supplement_ratio": null,
        "ontology_loaded": false
      },
      "type_consolidation": {
        "candidate_count": 20,
        "auto_apply_total": 9,
        "review_total": 8,
        "other_before": 2,
        "other_after": 1,
        "other_reduction": 1,
        "other_reduction_ratio": 0.5,
        "ontology_loaded": true
      }
    }
  },
  "candidate_validation": {
    "artifact_paths": {
      "chunks": "outputs/daozu_closure_fix_only_smoke_20260328/01_chunks.json",
      "ontology_samples": "outputs/daozu_closure_fix_only_smoke_20260328/01b_ontology_samples.json",
      "ontology_candidates": "outputs/daozu_closure_fix_only_smoke_20260328/01c_ontology_candidates.json",
      "ontology_doc": "outputs/daozu_closure_fix_only_smoke_20260328/01d_ontology.json",
      "kg_store": "outputs/daozu_closure_fix_only_smoke_20260328/02_kg_store.json",
      "kg_summary": "outputs/daozu_closure_fix_only_smoke_20260328/02_kg.json",
      "kg_store_closure": "outputs/daozu_closure_fix_only_smoke_20260328/02a_kg_store_closure.json",
      "kg_summary_closure": "outputs/daozu_closure_fix_only_smoke_20260328/02a_kg_closure.json",
      "kg_closure_decisions": "outputs/daozu_closure_fix_only_smoke_20260328/02a_kg_closure_decisions.json",
      "type_candidates": "outputs/daozu_closure_fix_only_smoke_20260328/02b_type_candidates.json",
      "type_consolidation": "outputs/daozu_closure_fix_only_smoke_20260328/02c_type_consolidation.json"
    },
    "missing": [],
    "errors": {
      "chunks": [],
      "ontology_samples": [],
      "ontology_candidates": [],
      "ontology_doc": [],
      "kg_store": [],
      "kg_summary": [],
      "kg_store_closure": [],
      "kg_summary_closure": [],
      "kg_closure_decisions": [],
      "type_candidates": [],
      "type_consolidation": []
    },
    "is_valid": true
  },
  "checks": [
    {
      "id": "schema.candidate",
      "stage": "phase1",
      "status": "pass",
      "severity": "error",
      "message": "phase-1 candidate artifacts passed schema validation",
      "actual": null,
      "expected": null
    },
    {
      "id": "run.errors",
      "stage": "phase1",
      "status": "pass",
      "severity": "error",
      "message": "run error count is within gate threshold",
      "actual": 0,
      "expected": {
        "max_run_errors": 0
      }
    },
    {
      "id": "stage_status.closure_fix",
      "stage": "closure_fix",
      "status": "pass",
      "severity": "error",
      "message": "closure_fix stage completed with status ok",
      "actual": "ok",
      "expected": "ok"
    },
    {
      "id": "stage_status.type_consolidation",
      "stage": "type_consolidation",
      "status": "pass",
      "severity": "error",
      "message": "type_consolidation stage completed with status ok",
      "actual": "ok",
      "expected": "ok"
    },
    {
      "id": "chunks.count",
      "stage": "chunks",
      "status": "pass",
      "severity": "error",
      "message": "chunk count meets minimum threshold",
      "actual": 3,
      "expected": {
        "min_chunks": 1
      }
    },
    {
      "id": "chunks.oversize_ratio",
      "stage": "chunks",
      "status": "pass",
      "severity": "error",
      "message": "oversize chunks stay within threshold",
      "actual": {
        "oversize_count": 0,
        "oversize_ratio": 0.0,
        "max_chars": 1800,
        "tolerance": 80
      },
      "expected": {
        "max_oversize_ratio": 0.0
      }
    },
    {
      "id": "chunks.avg_fill_ratio",
      "stage": "chunks",
      "status": "pass",
      "severity": "warn",
      "message": "average chunk fill ratio looks healthy",
      "actual": 0.974444,
      "expected": {
        "min_avg_fill_ratio": 0.55
      }
    },
    {
      "id": "ontology.samples",
      "stage": "ontology",
      "status": "pass",
      "severity": "error",
      "message": "samples meets minimum threshold",
      "actual": 3,
      "expected": {
        "min": 1
      }
    },
    {
      "id": "ontology.candidate_entity_types",
      "stage": "ontology",
      "status": "pass",
      "severity": "error",
      "message": "candidate_entity_types meets minimum threshold",
      "actual": 3,
      "expected": {
        "min": 3
      }
    },
    {
      "id": "ontology.candidate_relation_types",
      "stage": "ontology",
      "status": "pass",
      "severity": "error",
      "message": "candidate_relation_types meets minimum threshold",
      "actual": 5,
      "expected": {
        "min": 3
      }
    },
    {
      "id": "ontology.entity_taxonomy",
      "stage": "ontology",
      "status": "pass",
      "severity": "error",
      "message": "entity_taxonomy meets minimum threshold",
      "actual": 13,
      "expected": {
        "min": 8
      }
    },
    {
      "id": "ontology.relation_taxonomy",
      "stage": "ontology",
      "status": "pass",
      "severity": "error",
      "message": "relation_taxonomy meets minimum threshold",
      "actual": 5,
      "expected": {
        "min": 4
      }
    },
    {
      "id": "kg.entities_per_chunk",
      "stage": "kg",
      "status": "pass",
      "severity": "error",
      "message": "entities_per_chunk meets minimum threshold",
      "actual": 7.666667,
      "expected": {
        "min": 1.0
      }
    },
    {
      "id": "kg.relations_per_chunk",
      "stage": "kg",
      "status": "pass",
      "severity": "error",
      "message": "relations_per_chunk meets minimum threshold",
      "actual": 6.0,
      "expected": {
        "min": 1.0
      }
    },
    {
      "id": "kg.observations_per_chunk",
      "stage": "kg",
      "status": "pass",
      "severity": "error",
      "message": "observations_per_chunk meets minimum threshold",
      "actual": 17.666667,
      "expected": {
        "min": 8.0
      }
    },
    {
      "id": "kg.ambiguous_entity_forks",
      "stage": "kg",
      "status": "pass",
      "severity": "error",
      "message": "ambiguous entity forks stay within threshold",
      "actual": 0,
      "expected": {
        "max": 6
      }
    },
    {
      "id": "type.other_not_worse",
      "stage": "type_consolidation",
      "status": "pass",
      "severity": "error",
      "message": "type consolidation does not increase '其他'",
      "actual": {
        "other_before": 2,
        "other_after": 1
      },
      "expected": "other_after <= other_before"
    },
    {
      "id": "type.other_after_limit",
      "stage": "type_consolidation",
      "status": "pass",
      "severity": "error",
      "message": "post-consolidation '其他' count stays within threshold",
      "actual": 1,
      "expected": {
        "max": 3,
        "max_abs": 3,
        "max_ratio": 0.2
      }
    },
    {
      "id": "fix_only.manifest_bounds",
      "stage": "phase1",
      "status": "pass",
      "severity": "error",
      "message": "fix-only manifest start/stop stages are correct",
      "actual": {
        "start_stage": "closure_fix",
        "stop_stage": "type_consolidation"
      },
      "expected": {
        "start_stage": "closure_fix",
        "stop_stage": "type_consolidation"
      }
    },
    {
      "id": "fix_only.stage_rows",
      "stage": "phase1",
      "status": "pass",
      "severity": "error",
      "message": "fix-only run only executed closure stages",
      "actual": [
        "closure_fix",
        "type_consolidation"
      ],
      "expected": [
        "closure_fix",
        "type_consolidation"
      ]
    },
    {
      "id": "fix_only.llm_calls",
      "stage": "phase1",
      "status": "pass",
      "severity": "error",
      "message": "fix-only run issued no LLM calls",
      "actual": 0,
      "expected": 0
    },
    {
      "id": "fix_only.run_errors",
      "stage": "phase1",
      "status": "pass",
      "severity": "error",
      "message": "fix-only run produced no run_errors",
      "actual": 0,
      "expected": 0
    }
  ],
  "summary": {
    "check_count": 22,
    "failure_count": 0,
    "warning_count": 0
  },
  "phase1_gate": {
    "status": "pass",
    "summary": {
      "check_count": 18,
      "failure_count": 0,
      "warning_count": 0
    }
  },
  "regression_report": {},
  "status": "pass"
}