{
  "marker_version": "v1",
  "marker_type": "spawn_visibility_false_negative_prevention_guard_implemented",
  "recorded_at": "2026-05-25T12:54:30+09:00",
  "task_id": "task-2658",
  "chair_authorization_id": "CHAIR-AUTH-SPAWN-VISIBILITY-20260525-JJONGS-GUARD-001",
  "current_status": "SPAWN_VISIBILITY_FALSE_NEGATIVE_PREVENTION_GUARD_IMPLEMENTED",
  "completion_status_enum_selected_verbatim": "SPAWN_VISIBILITY_FALSE_NEGATIVE_PREVENTION_GUARD_IMPLEMENTED",
  "forbidden_action_count": 0,
  "self_check_passed": true,
  "executor": "dev6_perun_team_lead_direct",
  "scope_recommendation_received": "FULL_IMPLEMENTATION (회장 verbatim)",
  "branch": "task/task-2658-dev6",
  "worktree_path": "/home/jay/workspace/.worktrees/task-2658-dev6",
  "base_commit": "0e172435 (origin/main: Merge PR #144 task-2641)",
  "commit_push_pr_merge_performed": false,
  "monitoring_judgment_layer_only": true,
  "module_location_anchor": "utils/anu_spawn_visibility_guard/* (★ ANU 공통 dispatch/spawn 검증 도구 · Axis 3 전용 위치 금지)",
  "predecessor_task": "task-2657 (Axis 3 canary scale-aware guard) — WARN 1 initial_spawn_visibility_gap 직 후속",
  "predecessor_incident": {
    "anu_false_negative_at_kst": "2026-05-25T11:57:24+09:00",
    "schedule_id": "426931FE",
    "fire_at_kst": "2026-05-25T11:46:52+09:00",
    "anu_check_location_used_only": "/home/jay/workspace/.worktrees/",
    "actual_bot_worktree_revealed": "/home/jay/.cokacdir/workspace/426931FE/wt-2657-dev6",
    "classification": "FALSE_NEGATIVE_SPAWN_VISIBILITY (location coverage 누락)"
  },
  "changed_files": [
    "utils/anu_spawn_visibility_guard/__init__.py",
    "utils/anu_spawn_visibility_guard/path_resolver.py",
    "utils/anu_spawn_visibility_guard/source_collector.py",
    "utils/anu_spawn_visibility_guard/status_classifier.py",
    "utils/anu_spawn_visibility_guard/timeout_gate.py",
    "tests/anu_spawn_visibility_guard/__init__.py",
    "tests/anu_spawn_visibility_guard/test_regression_6.py",
    "memory/events/task-2658.spawn-visibility-guard-result-260525.json",
    "memory/reports/task-2658.md",
    "memory/events/task-2658.done"
  ],
  "guard_applied_locations": {
    "path_resolver": "utils/anu_spawn_visibility_guard/path_resolver.py — 두 후보 worktree root (legacy /home/jay/workspace/.worktrees + cokacdir /home/jay/.cokacdir/workspace/<schedule_id>) 동시 glob · wt-<task>-<team>/iso-/task-/<task>- 5 패턴 + schedule_id 미제공 시 광역 fallback glob (★ ANU 가 schedule_id 컨벤션을 몰라도 false negative 방지)",
    "source_collector": "utils/anu_spawn_visibility_guard/source_collector.py — 8 source 동시 수집 (legacy_worktree, cokacdir_worktree, schedule_workspace_dir, executor_process(ps+pattern), schedule_history JSONL parse, done_marker, result_marker, report_marker, callback_inbox.acked)",
    "status_classifier": "utils/anu_spawn_visibility_guard/status_classifier.py — 5 enum 판정 (SPAWN_VERIFIED / SPAWN_PENDING / SPAWN_VISIBILITY_GAP / CALLBACK_RECOVERED_AFTER_VISIBILITY_GAP / TRUE_SILENT_DROP) · 2 source 교차 룰 · self-attestation 단독 금지",
    "timeout_gate": "utils/anu_spawn_visibility_guard/timeout_gate.py — 30분 hard timeout + ANCHOR-3 예외 3건 (schedule_history pending / result marker present / callback envelope present)",
    "regression_fixtures": "tests/anu_spawn_visibility_guard/test_regression_6.py — R1~R6 + R3 보강 fallback glob 케이스 총 7 케이스 · 모두 격리 tmp_path · 외부 fs 미오염",
    "pretooluse_runtime_change": "ZERO — monitoring/judgment layer 한정 · runtime policy 변경 0",
    "axis_1_2_runtime_change": "ZERO",
    "axis_3_canary_module_change": "ZERO — utils/axis_3_canary_scale_aware_guard/* 미수정 · observer chain 격리 유지",
    "dispatch_py_change": "ZERO",
    "live_settings_json_change": "ZERO",
    "live_cokacdir_change": "ZERO",
    "hooks_dir_change": "ZERO"
  },
  "source_priority_and_cross_check_rule": {
    "rule_v1_total_8_sources": [
      "1. legacy worktree (/home/jay/workspace/.worktrees/wt-<task_id_short>-<team>/)",
      "2. cokacdir worktree (/home/jay/.cokacdir/workspace/<schedule_id>/wt-<task_id_short>-<team>/)",
      "3. schedule_id workspace dir (/home/jay/.cokacdir/workspace/<schedule_id>/)",
      "4. executor process (ps -e -o pid,args + 8 pattern match: wt-/task//--task-id 등)",
      "5. schedule_history JSONL (/home/jay/.cokacdir/schedule_history/<schedule_id>.log)",
      "6. result marker (memory/events/<task_id>.*-result-*.json glob)",
      "7. report marker (memory/reports/<task_id>.md)",
      "8. done marker (memory/events/<task_id>.done)",
      "8a. callback_inbox.acked (memory/.callback_inbox/*<task_id>*.acked + short 패턴)"
    ],
    "cross_check_min_2_sources_required": true,
    "self_attestation_single_source_forbidden": true,
    "anchor_2_callback_evidence_definition": "callback evidence = (a) result/report/done marker + (b) callback_inbox.acked. 둘 다 인정. 단 단독 1 source 인정 금지. 최소 2 source 교차 필수.",
    "anchor_4_worktree_one_side_missing_silent_drop_forbidden": "legacy 또는 cokacdir 한쪽이 missing 하더라도 다른 쪽이 양성이면 silent drop 단정 금지. 두 위치를 동시에 glob 한다."
  },
  "true_silent_drop_timeout_rule": {
    "hard_timeout_seconds": 1800,
    "hard_timeout_minutes": 30,
    "anchor_3_blocking_exceptions_3": [
      "schedule_history pending (last_status ∈ {pending, running, in_progress, started, fired})",
      "result marker present (memory/events/<task_id>.*-result-*.json)",
      "callback envelope present (done marker OR report marker OR callback_inbox.acked)"
    ],
    "decision_function": "evaluate_timeout_gate(sources, elapsed_seconds, hard_timeout_seconds=1800) -> TimeoutDecision(silent_drop_eligible, blocking_exceptions, reason)",
    "eligibility_condition": "elapsed >= hard_timeout_seconds AND blocking_exceptions == ()",
    "anchor_3_one_or_more_exception_forbids_true_silent_drop_classification": true
  },
  "status_enum_decision_table": {
    "SPAWN_VERIFIED": {
      "strict_3_signals": "worktree(legacy OR cokacdir) AND executor_process AND first_response_not_refusal=True",
      "relaxed_2_signals": "worktree AND executor_process AND first_response_not_refusal=None (미관측 케이스 호환)",
      "regression_id": "R1, R2, R3, R3-fallback-glob"
    },
    "SPAWN_PENDING": {
      "rule": "(NOT silent_drop_eligible) AND (schedule_history_last_status ∈ pending-set OR elapsed < hard_timeout/2)",
      "regression_id": "R6 (short-elapsed 케이스 + R6 long-elapsed pending 보호)"
    },
    "SPAWN_VISIBILITY_GAP": {
      "rule": "(NOT silent_drop_eligible) AND (positive sources exist) AND (NOT schedule_history pending) AND (elapsed >= hard_timeout/2) — 일부 source 부재 + 다른 source 양성. fallback: 교차 검증 미달 (self-attestation 단독 인정 금지).",
      "regression_id": "(분기 fallback · 명시 fixture 없음 · classifier 내부 rule 5)"
    },
    "CALLBACK_RECOVERED_AFTER_VISIBILITY_GAP": {
      "rule": "callback_evidence_sources >= 2 교차 AND (initial_anu_absent_observed OR executor_process_absent)",
      "regression_id": "R4 (★ 2 source 교차 강제: done + result + report = 3 source)"
    },
    "TRUE_SILENT_DROP": {
      "rule": "silent_drop_eligible=True AND positive_sources==() AND callback_evidence_sources==()",
      "regression_id": "R5 (elapsed = hard_timeout + 60s · 전 source 부재)"
    }
  },
  "regression_results_6": [
    {
      "id": "R1",
      "name": "RegressionR1LegacyWorktree::test_r1",
      "scenario": "legacy /home/jay/workspace/.worktrees/ 위치 worktree 존재 + executor process 양성",
      "expected": "SPAWN_VERIFIED",
      "actual": "SPAWN_VERIFIED",
      "status": "PASSED"
    },
    {
      "id": "R2",
      "name": "RegressionR2CokacdirWorktree::test_r2",
      "scenario": "/home/jay/.cokacdir/workspace/<sid>/wt-<task>-<team>/ 양성 + legacy 도 양성 + process 양성",
      "expected": "SPAWN_VERIFIED",
      "actual": "SPAWN_VERIFIED",
      "status": "PASSED"
    },
    {
      "id": "R3",
      "name": "RegressionR3CokacdirOnlyFalseNegativeBlock::test_r3",
      "scenario": "legacy 부재 · cokacdir 만 존재 · process 양성 (★ task-2657 사고 직접 재현 + false negative 금지 핵심)",
      "expected": "SPAWN_VERIFIED",
      "actual": "SPAWN_VERIFIED",
      "status": "PASSED"
    },
    {
      "id": "R3-bonus",
      "name": "RegressionR3CokacdirOnlyFalseNegativeBlock::test_r3_without_schedule_id_fallback_glob",
      "scenario": "R3 + schedule_id 미제공 → 광역 fallback glob 으로 cokacdir worktree 검출 (ANU 가 schedule_id 컨벤션 모를 때 false negative 방지)",
      "expected": "SPAWN_VERIFIED",
      "actual": "SPAWN_VERIFIED",
      "status": "PASSED"
    },
    {
      "id": "R4",
      "name": "RegressionR4CallbackRecoveredAfterGap::test_r4",
      "scenario": "executor process 부재 + done + result + report 모두 존재 (3 source 교차)",
      "expected": "CALLBACK_RECOVERED_AFTER_VISIBILITY_GAP",
      "actual": "CALLBACK_RECOVERED_AFTER_VISIBILITY_GAP",
      "status": "PASSED",
      "crossed_sources_count": 3
    },
    {
      "id": "R5",
      "name": "RegressionR5TrueSilentDrop::test_r5",
      "scenario": "전 source 부재 (worktree 0, process 0, history 0, marker 0, callback 0) + elapsed = hard_timeout + 60s",
      "expected": "TRUE_SILENT_DROP",
      "actual": "TRUE_SILENT_DROP",
      "status": "PASSED",
      "timeout_decision": {
        "silent_drop_eligible": true,
        "blocking_exceptions": []
      }
    },
    {
      "id": "R6",
      "name": "RegressionR6SchedulePendingBlocksSilentDrop::test_r6",
      "scenario": "schedule_history last_status='pending' · 다른 source 일부 부재 · short elapsed → SPAWN_PENDING · long elapsed 도 silent_drop NOT eligible (★ pending 예외)",
      "expected": "SPAWN_PENDING + TRUE_SILENT_DROP 단정 금지",
      "actual": "SPAWN_PENDING (short) + NOT TRUE_SILENT_DROP (long) · timeout_gate.silent_drop_eligible=False · blocking_exceptions=['schedule_history pending']",
      "status": "PASSED"
    }
  ],
  "regression_summary": {
    "required_by_chair_verbatim": 6,
    "implemented_total": 7,
    "passed": 7,
    "failed": 0,
    "extra_bonus": "R3-fallback-glob (광역 glob false-negative 차단 보강)",
    "pytest_duration_s": 0.11,
    "pytest_invocation": "WORKSPACE_ROOT=/home/jay/workspace/.worktrees/task-2658-dev6 python3 -m pytest tests/anu_spawn_visibility_guard/test_regression_6.py -v",
    "rootdir": "/home/jay/workspace/.worktrees/task-2658-dev6"
  },
  "forbidden_action_count_report": 0,
  "forbidden_actions_audit": {
    "axis_3_running_auto_declaration": 0,
    "full_rollout": 0,
    "harness_enforced_total_declaration": 0,
    "policy_promotion": 0,
    "block_policy_expansion": 0,
    "pretooluse_runtime_change": 0,
    "axis_1_2_runtime_change": 0,
    "live_settings_json_change": 0,
    "dispatch_py_change": 0,
    "live_cokacdir_change": 0,
    "hooks_dir_change": 0,
    "axis_3_canary_module_change": 0,
    "commit_push_pr_merge": 0
  },
  "frozen_anchors_verbatim_compliance": {
    "ANCHOR-1_module_location_utils_anu_spawn_visibility_guard_axis3_position_forbidden": true,
    "ANCHOR-2_callback_evidence_result_report_done_plus_callback_inbox_acked_min_2_source_cross": true,
    "ANCHOR-3_true_silent_drop_hard_timeout_30min_exceptions_3": true,
    "ANCHOR-4_worktree_2_candidate_locations_simultaneous_glob_one_side_missing_not_silent_drop": true,
    "ANCHOR-5_status_enum_5_separation_callback_recovered_after_visibility_gap_explicit": true,
    "ANCHOR-6_runtime_and_repo_critical_paths_unchanged_no_commit_no_push_no_pr_no_merge": true,
    "ANCHOR-7_chair_session_application_0_collector_session_application_0_axis3_running_auto_declaration_0": true
  },
  "axis_3_canary_observer_chain_isolation": {
    "axis_3_canary_modules_modified": 0,
    "axis_3_canary_tests_modified": 0,
    "real_t0_preserved": "2026-05-24T19:51:35+09:00",
    "wall_clock_24h_target_preserved": "2026-05-25T19:51:35+09:00",
    "monitoring_silent_continue_with_traffic_sample_unchanged": true
  },
  "linked_markers": [
    "memory/tasks/task-2658.md (★ spec 단일소스 · sha256 5d870e01fc7e0be12b23af6a91b60e16372b004eacd628a41bf877cee70a1e76)",
    "memory/events/spawn-visibility-false-negative-prevention-guard-packet-260525.json (★ packet 보강 자료)",
    "memory/events/task-2657.axis-3-canary-scale-aware-guard-implemented-chair-verified-260525.json (★ WARN 1 initial_spawn_visibility_gap 직 후속)",
    "memory/events/task-2657.axis-3-canary-scale-aware-guard-result-260525.json (★ task-2657 executor result · 본 사고 발견 근거)"
  ],
  "anu_normal_callback_cron": {
    "cron_id": "A89DD65A",
    "scheduled_for_kst": "2026-05-25T13:01:04+09:00",
    "owner_key": "c119085addb0f8b7",
    "chat_id": "6937032012",
    "kind": "normal",
    "once": true,
    "prompt_bytes": 1135,
    "envelope_only": true,
    "helper_verdict": "PASS",
    "helper_chain": "dispatch.normal_fallback_callback_helper.build_anu_owned_callback_request -> cokacdir --cron",
    "self_key_blocked_by_helper_pre_argv_gate": true,
    "fallback_registered": false,
    "no_fallback_explicit_contract": true
  }
}
