24549 lines
1.0 MiB
24549 lines
1.0 MiB
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from flask import Flask
|
|
from sqlalchemy import create_engine, text
|
|
|
|
from database.manager import Base
|
|
from services.market_intel import MarketIntelService
|
|
from services.market_intel.service import MARKET_INTEL_TABLES
|
|
from services.market_intel.adapters import get_adapter, get_adapter_summaries
|
|
from services.market_intel.candidate_preview import build_candidate_preview_from_discovery
|
|
from services.market_intel.discovery_runner import ManualDiscoveryRunner
|
|
from services.market_intel.html_diagnostics import parse_html_diagnostics
|
|
from services.market_intel.mcp_activation_evidence import build_mcp_activation_evidence_preview
|
|
from services.market_intel.mcp_activation_runbook import build_mcp_activation_runbook_preview
|
|
from services.market_intel.mcp_completion_audit import build_mcp_completion_audit_preview
|
|
from services.market_intel.mcp_contract import build_mcp_tool_contract_preview
|
|
from services.market_intel.mcp_deploy_preflight import build_mcp_deploy_preflight_plan
|
|
from services.market_intel.mcp_fetch_gate import build_mcp_fetch_gate_preview
|
|
from services.market_intel.mcp_fetch_run_package import (
|
|
build_mcp_fetch_run_package_preview,
|
|
)
|
|
from services.market_intel.mcp_fetch_run_readiness import (
|
|
build_mcp_fetch_run_readiness_preview,
|
|
)
|
|
from services.market_intel.mcp_fetch_run_receipt import (
|
|
build_mcp_fetch_run_receipt_preview,
|
|
)
|
|
from services.market_intel.mcp_fetch_result_parser_review import (
|
|
build_mcp_fetch_result_parser_review_preview,
|
|
)
|
|
from services.market_intel.mcp_fetch_candidate_handoff_review import (
|
|
build_mcp_fetch_candidate_handoff_review_preview,
|
|
)
|
|
from services.market_intel.mcp_fetch_candidate_queue_review import (
|
|
build_mcp_fetch_candidate_queue_review_preview,
|
|
)
|
|
from services.market_intel.mcp_fetch_target_review import (
|
|
build_mcp_fetch_target_review_preview,
|
|
)
|
|
from services.market_intel.mcp_manual_fetch_handoff import (
|
|
build_mcp_manual_fetch_handoff_preview,
|
|
)
|
|
from services.market_intel.mcp_readiness import build_mcp_readiness_plan
|
|
from services.market_intel.mcp_runtime_promotion import build_mcp_runtime_promotion_preview
|
|
from services.market_intel.mcp_runtime_smoke_receipt import build_mcp_runtime_smoke_receipt_preview
|
|
from services.market_intel.live_db_inventory import build_live_db_inventory_preview
|
|
from services.market_intel.manual_sample_review import evaluate_manual_sample_result
|
|
from services.market_intel.platform_seed_db_diff import build_platform_seed_db_diff_plan
|
|
from services.market_intel.schema_db_probe import build_schema_db_probe_plan
|
|
|
|
|
|
TEST_APPROVAL_TOKEN = "test-market-intel-approval-token"
|
|
|
|
|
|
def _market_intel_sample_result(batch_id="sample-batch-receipt"):
|
|
return {
|
|
"batch_id": batch_id,
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "b" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
|
|
|
|
def _build_candidate_queue_writer_receipt_fixture(batch_id="sample-batch-receipt"):
|
|
from services.market_intel.candidate_queue_writer_cli import (
|
|
build_candidate_queue_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_operator_drill import (
|
|
build_candidate_queue_writer_operator_drill,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_postwrite_smoke import (
|
|
build_candidate_queue_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_preflight import (
|
|
build_candidate_queue_writer_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_package import (
|
|
build_candidate_queue_writer_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_readiness import (
|
|
build_candidate_queue_writer_run_readiness,
|
|
)
|
|
|
|
service = MarketIntelService()
|
|
sample_result = _market_intel_sample_result(batch_id=batch_id)
|
|
transaction = service.build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
preflight = build_candidate_queue_writer_preflight(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
writer_status = build_candidate_queue_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
)
|
|
postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
operator_drill = build_candidate_queue_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
)
|
|
run_package = build_candidate_queue_writer_run_package(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
operator_drill=operator_drill,
|
|
)
|
|
operator_evidence = {
|
|
"reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": "artifacts/market_intel/preflight.json",
|
|
"migration_live_smoke_passed": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
"writer_output_json_path": "artifacts/market_intel/writer-output.json",
|
|
"postwrite_smoke_json_path": "artifacts/market_intel/postwrite-smoke.json",
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
"receipt_notes": "small-batch queue writer receipt reviewed",
|
|
}
|
|
run_readiness = build_candidate_queue_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
operator_drill=operator_drill,
|
|
run_package=run_package,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
expected_keys = sorted(
|
|
str(statement["lookup"]["dedupe_key"])
|
|
for statement in transaction["statements"]
|
|
)
|
|
writer_output = {
|
|
"mode": "candidate_queue_writer_cli_executed",
|
|
"exit_code": 0,
|
|
"approval_token_present": True,
|
|
"approval_token_valid": True,
|
|
"approval_token_secret_configured": True,
|
|
"approval_env_var": "MARKET_INTEL_QUEUE_WRITE_APPROVAL",
|
|
"writes_executed": True,
|
|
"would_write_database": True,
|
|
"database_connection_opened": True,
|
|
"explicit_transaction_opened": True,
|
|
"database_write_executed": True,
|
|
"database_commit_executed": True,
|
|
"database_rollback_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"inserted_count": len(expected_keys),
|
|
"skipped_count": 0,
|
|
"affected_dedupe_keys": expected_keys,
|
|
"skipped_dedupe_keys": [],
|
|
}
|
|
postwrite_smoke_result = {
|
|
"mode": "candidate_queue_writer_postwrite_smoke_read_only",
|
|
"postwrite_smoke_passed": True,
|
|
"ready_for_operator_review": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"expected_dedupe_key_count": len(expected_keys),
|
|
"found_count": len(expected_keys),
|
|
"missing_count": 0,
|
|
"found_dedupe_keys": expected_keys,
|
|
"missing_dedupe_keys": [],
|
|
"row_summaries": [
|
|
{
|
|
"dedupe_key": key,
|
|
"review_state": "needs_review",
|
|
"priority_lane": "watch",
|
|
"total_score": 82.5,
|
|
"source_batch_id": batch_id,
|
|
"created_at": "2026-05-19T12:00:00",
|
|
"updated_at": "2026-05-19T12:00:00",
|
|
}
|
|
for key in expected_keys
|
|
],
|
|
}
|
|
return {
|
|
"sample_result": sample_result,
|
|
"transaction": transaction,
|
|
"run_readiness": run_readiness,
|
|
"operator_evidence": operator_evidence,
|
|
"writer_output": writer_output,
|
|
"postwrite_smoke_result": postwrite_smoke_result,
|
|
"expected_keys": expected_keys,
|
|
}
|
|
|
|
|
|
def _build_ready_review_decision_transaction(
|
|
batch_id="sample-batch-review-decision-writer"
|
|
):
|
|
from services.market_intel.candidate_queue_review_decision import (
|
|
build_candidate_queue_review_decision,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_approval import (
|
|
build_candidate_queue_review_decision_approval,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_transaction import (
|
|
build_candidate_queue_review_decision_transaction,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(batch_id)
|
|
inventory = {
|
|
"mode": "candidate_queue_review_inventory_preview",
|
|
"review_inventory_ready": True,
|
|
"expected_dedupe_keys": fixture["expected_keys"],
|
|
"row_summaries": [
|
|
{
|
|
"dedupe_key": fixture["expected_keys"][0],
|
|
"review_state": "needs_review",
|
|
"priority_lane": "watch",
|
|
"total_score": 82.5,
|
|
}
|
|
],
|
|
}
|
|
decision_evidence = {
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "evidence reviewed manually",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
}
|
|
approval_evidence = {
|
|
**decision_evidence,
|
|
"decision_approval_notes": "approved for cli-only transaction preview",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
}
|
|
transaction_evidence = {
|
|
**approval_evidence,
|
|
"decision_transaction_notes": "payload reviewed for shell transaction",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
}
|
|
decision = build_candidate_queue_review_decision(
|
|
review_inventory=inventory,
|
|
operator_evidence=decision_evidence,
|
|
)
|
|
approval = build_candidate_queue_review_decision_approval(
|
|
review_decision=decision,
|
|
operator_evidence=approval_evidence,
|
|
)
|
|
transaction = build_candidate_queue_review_decision_transaction(
|
|
decision_approval=approval,
|
|
operator_evidence=transaction_evidence,
|
|
)
|
|
return transaction, transaction_evidence
|
|
|
|
|
|
def _build_review_decision_writer_receipt_fixture(
|
|
batch_id="sample-batch-review-decision-writer-closeout"
|
|
):
|
|
from services.market_intel.candidate_queue_review_decision_writer_cli import (
|
|
build_candidate_queue_review_decision_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_preflight import (
|
|
build_candidate_queue_review_decision_writer_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
|
|
build_candidate_queue_review_decision_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
|
|
build_candidate_queue_review_decision_writer_operator_drill,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_package import (
|
|
build_candidate_queue_review_decision_writer_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_readiness import (
|
|
build_candidate_queue_review_decision_writer_run_readiness,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_receipt import (
|
|
build_candidate_queue_review_decision_writer_run_receipt,
|
|
)
|
|
|
|
transaction, operator_evidence = _build_ready_review_decision_transaction(
|
|
batch_id
|
|
)
|
|
expected_key = transaction["statements"][0]["lookup"]["dedupe_key"]
|
|
operator_evidence = {
|
|
**operator_evidence,
|
|
"operator_confirmed_manual_shell_window": True,
|
|
"operator_confirmed_post_update_inventory_planned": True,
|
|
"operator_drill_notes": "review_state shell drill reviewed",
|
|
}
|
|
writer_status = build_candidate_queue_review_decision_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
preflight = build_candidate_queue_review_decision_writer_preflight(
|
|
writer_status=writer_status,
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
drill = build_candidate_queue_review_decision_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
package = build_candidate_queue_review_decision_writer_run_package(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_drill=drill,
|
|
)
|
|
receipt_evidence = {
|
|
**operator_evidence,
|
|
"review_state_transaction_json_path": (
|
|
"artifacts/market_intel/review-state-transaction.json"
|
|
),
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": (
|
|
"artifacts/market_intel/review-state-preflight.json"
|
|
),
|
|
"operator_confirmed_review_state_preflight_only": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
"review_state_writer_output_json_path": (
|
|
"artifacts/market_intel/review-state-writer-output.json"
|
|
),
|
|
"review_state_postwrite_smoke_json_path": (
|
|
"artifacts/market_intel/review-state-postwrite-smoke.json"
|
|
),
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
"receipt_notes": "review_state receipt reviewed",
|
|
}
|
|
readiness = build_candidate_queue_review_decision_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_drill=drill,
|
|
run_package=package,
|
|
operator_evidence=receipt_evidence,
|
|
)
|
|
writer_output = {
|
|
"mode": "candidate_queue_review_decision_writer_cli_executed",
|
|
"exit_code": 0,
|
|
"approval_token_present": True,
|
|
"approval_token_valid": True,
|
|
"approval_token_secret_configured": True,
|
|
"approval_env_var": "MARKET_INTEL_QUEUE_WRITE_APPROVAL",
|
|
"writes_executed": True,
|
|
"would_write_database": True,
|
|
"database_connection_opened": True,
|
|
"explicit_transaction_opened": True,
|
|
"database_write_executed": True,
|
|
"database_commit_executed": True,
|
|
"database_rollback_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"api_updates_review_state": False,
|
|
"review_state_update_executed": True,
|
|
"updated_count": 1,
|
|
"skipped_count": 0,
|
|
"affected_dedupe_keys": [expected_key],
|
|
"skipped_dedupe_keys": [],
|
|
}
|
|
postwrite_smoke_result = {
|
|
"mode": "candidate_queue_review_decision_writer_postwrite_smoke_read_only",
|
|
"postwrite_smoke_passed": True,
|
|
"review_state_update_verified": True,
|
|
"ready_for_operator_review": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"expected_dedupe_key_count": 1,
|
|
"found_count": 1,
|
|
"missing_count": 0,
|
|
"state_mismatch_count": 0,
|
|
"found_dedupe_keys": [expected_key],
|
|
"missing_dedupe_keys": [],
|
|
"state_mismatches": [],
|
|
"row_summaries": [
|
|
{
|
|
"dedupe_key": expected_key,
|
|
"review_state": "confirmed",
|
|
"priority_lane": "watch",
|
|
"threshold_level": "medium",
|
|
"total_score": 82.5,
|
|
"evidence_bundle_id": "evidence-1",
|
|
"source_batch_id": batch_id,
|
|
"reviewed_at": "2026-05-19T12:30:00",
|
|
"created_at": "2026-05-19T12:00:00",
|
|
"updated_at": "2026-05-19T12:30:00",
|
|
}
|
|
],
|
|
}
|
|
receipt = build_candidate_queue_review_decision_writer_run_receipt(
|
|
transaction_preview=transaction,
|
|
run_readiness=readiness,
|
|
writer_output=writer_output,
|
|
postwrite_smoke_result=postwrite_smoke_result,
|
|
operator_evidence=receipt_evidence,
|
|
)
|
|
return {
|
|
"transaction": transaction,
|
|
"operator_evidence": receipt_evidence,
|
|
"writer_output": writer_output,
|
|
"postwrite_smoke_result": postwrite_smoke_result,
|
|
"receipt": receipt,
|
|
}
|
|
|
|
|
|
def test_market_intel_defaults_are_safe():
|
|
service = MarketIntelService()
|
|
status = service.get_runtime_status().to_dict()
|
|
plan = service.build_dry_run_plan("momo")
|
|
|
|
assert status["enabled"] is False
|
|
assert status["crawler_enabled"] is False
|
|
assert status["write_enabled"] is False
|
|
assert status["database_write_allowed"] is False
|
|
assert plan["would_discover_campaigns"] is False
|
|
assert plan["would_write_database"] is False
|
|
|
|
|
|
def test_market_intel_adapter_registry_is_read_only():
|
|
summaries = get_adapter_summaries()
|
|
codes = {item["platform_code"] for item in summaries}
|
|
|
|
assert {"momo", "pchome", "coupang", "shopee"} <= codes
|
|
for summary in summaries:
|
|
policy = summary["safety_policy"]
|
|
assert policy["allow_login"] is False
|
|
assert policy["allow_database_write"] is False
|
|
assert policy["allow_scheduler_attach"] is False
|
|
|
|
|
|
def test_market_intel_discovery_plan_does_not_allow_network_or_write():
|
|
service = MarketIntelService()
|
|
plan = service.build_discovery_plan("momo")
|
|
|
|
assert plan["found"] is True
|
|
assert len(plan["plans"]) == 1
|
|
momo_plan = plan["plans"][0]
|
|
assert momo_plan["network_request_allowed"] is False
|
|
assert momo_plan["database_write_allowed"] is False
|
|
assert momo_plan["scheduler_attach_allowed"] is False
|
|
assert momo_plan["sources"]
|
|
|
|
|
|
def test_unknown_adapter_returns_diagnostic_error():
|
|
assert get_adapter("unknown") is None
|
|
plan = MarketIntelService().build_discovery_plan("unknown")
|
|
assert plan["found"] is False
|
|
assert plan["error"] == "未知平台 adapter"
|
|
|
|
|
|
def test_manual_discovery_default_does_not_call_network():
|
|
called = {"count": 0}
|
|
|
|
def fake_get(*args, **kwargs):
|
|
called["count"] += 1
|
|
raise AssertionError("預設 dry-run 不應發 HTTP request")
|
|
|
|
result = MarketIntelService().run_manual_discovery("momo", fetch=False, http_get=fake_get)
|
|
|
|
assert called["count"] == 0
|
|
assert result["found"] is True
|
|
assert result["runs"][0]["status"] == "planned"
|
|
assert result["runs"][0]["sources_fetched"] == 0
|
|
assert all(item["network_executed"] is False for item in result["runs"][0]["results"])
|
|
|
|
|
|
def test_manual_discovery_fetch_is_blocked_when_flags_are_off():
|
|
called = {"count": 0}
|
|
|
|
def fake_get(*args, **kwargs):
|
|
called["count"] += 1
|
|
raise AssertionError("flags 關閉時不應發 HTTP request")
|
|
|
|
result = MarketIntelService().run_manual_discovery("momo", fetch=True, http_get=fake_get)
|
|
|
|
assert called["count"] == 0
|
|
assert result["runs"][0]["status"] == "blocked"
|
|
assert result["runs"][0]["network_allowed"] is False
|
|
assert result["runs"][0]["database_write_allowed"] is False
|
|
assert result["mcp_fetch_gate"]["network_request_allowed"] is False
|
|
assert result["runs"][0]["network_gate"]["manual_fetch_gate_open"] is False
|
|
|
|
|
|
def test_manual_runner_fetch_can_be_blocked_by_mcp_gate_even_when_flags_allow():
|
|
class RuntimeStatus:
|
|
enabled = True
|
|
crawler_enabled = True
|
|
|
|
called = {"count": 0}
|
|
|
|
def fake_get(*args, **kwargs):
|
|
called["count"] += 1
|
|
raise AssertionError("MCP gate 關閉時不應發 HTTP request")
|
|
|
|
gate = {
|
|
"manual_fetch_gate_open": False,
|
|
"network_request_allowed": False,
|
|
"blocked_reasons": ["mcp_router_enabled"],
|
|
"operator_message": "人工 fetch 仍被 MCP gate 阻擋",
|
|
}
|
|
adapter = get_adapter("momo")
|
|
runner = ManualDiscoveryRunner(
|
|
runtime_status=RuntimeStatus(),
|
|
http_get=fake_get,
|
|
network_allowed_override=False,
|
|
network_gate=gate,
|
|
)
|
|
result = runner.run(adapter, fetch=True).to_dict()
|
|
|
|
assert called["count"] == 0
|
|
assert result["status"] == "blocked"
|
|
assert result["network_allowed"] is False
|
|
assert result["network_gate"]["blocked_reasons"] == ["mcp_router_enabled"]
|
|
assert "MCP gate" in result["error_message"]
|
|
|
|
|
|
def test_manual_runner_fetch_uses_injected_http_get_when_allowed():
|
|
class RuntimeStatus:
|
|
enabled = True
|
|
crawler_enabled = True
|
|
|
|
class Response:
|
|
status_code = 200
|
|
text = "<html><title>活動頁</title><body>OK</body></html>"
|
|
|
|
called = {"count": 0}
|
|
|
|
def fake_get(url, **kwargs):
|
|
called["count"] += 1
|
|
return Response()
|
|
|
|
adapter = get_adapter("momo")
|
|
runner = ManualDiscoveryRunner(runtime_status=RuntimeStatus(), http_get=fake_get)
|
|
result = runner.run(adapter, fetch=True).to_dict()
|
|
|
|
assert called["count"] == len(adapter.campaign_sources())
|
|
assert result["status"] == "success"
|
|
assert result["database_write_allowed"] is False
|
|
assert result["scheduler_attached"] is False
|
|
assert result["sources_fetched"] == len(adapter.campaign_sources())
|
|
assert result["results"][0]["title"] == "活動頁"
|
|
assert result["results"][0]["diagnostics"]["title"] == "活動頁"
|
|
|
|
|
|
def test_html_diagnostics_extracts_campaign_link_candidates():
|
|
html = """
|
|
<html>
|
|
<head><title>五月品牌日</title></head>
|
|
<body>
|
|
<a href="/event/brand-day">品牌日活動</a>
|
|
<a href="https://example.com/help">客服中心</a>
|
|
<a href="https://other.example/promo">外部 promo</a>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
diagnostics = parse_html_diagnostics(html, base_url="https://shop.example").to_dict()
|
|
|
|
assert diagnostics["title"] == "五月品牌日"
|
|
assert diagnostics["link_count"] == 3
|
|
assert diagnostics["same_host_link_count"] == 1
|
|
assert diagnostics["campaign_link_candidates"][0]["href"] == "https://shop.example/event/brand-day"
|
|
assert diagnostics["campaign_link_candidates"][0]["score"] > 0
|
|
assert "generic_score" in diagnostics["campaign_link_candidates"][0]
|
|
assert "platform_score" in diagnostics["campaign_link_candidates"][0]
|
|
assert "confidence_band" in diagnostics["campaign_link_candidates"][0]
|
|
assert "confidence_reason" in diagnostics["campaign_link_candidates"][0]
|
|
|
|
|
|
def test_manual_runner_returns_parser_diagnostics_when_fetch_succeeds():
|
|
class RuntimeStatus:
|
|
enabled = True
|
|
crawler_enabled = True
|
|
|
|
class Response:
|
|
status_code = 200
|
|
text = """
|
|
<html>
|
|
<head><title>PChome 優惠活動</title></head>
|
|
<body><a href="/event/sale">限時優惠</a></body>
|
|
</html>
|
|
"""
|
|
|
|
adapter = get_adapter("pchome")
|
|
runner = ManualDiscoveryRunner(runtime_status=RuntimeStatus(), http_get=lambda *args, **kwargs: Response())
|
|
result = runner.run(adapter, fetch=True).to_dict()
|
|
diagnostics = result["results"][0]["diagnostics"]
|
|
|
|
assert diagnostics["title"] == "PChome 優惠活動"
|
|
assert diagnostics["campaign_link_candidates"]
|
|
assert diagnostics["campaign_link_candidates"][0]["is_same_host"] is True
|
|
|
|
|
|
def test_momo_platform_scorer_prioritizes_momo_campaign_links():
|
|
adapter = get_adapter("momo")
|
|
html = """
|
|
<html><title>MOMO 活動</title><body>
|
|
<a href="https://other.example/promo">外部 promo</a>
|
|
<a href="/edm/cmmedm.jsp">MOMO 品牌日活動</a>
|
|
</body></html>
|
|
"""
|
|
|
|
diagnostics = parse_html_diagnostics(
|
|
html,
|
|
base_url=adapter.base_url,
|
|
score_link=adapter.score_campaign_link,
|
|
).to_dict()
|
|
|
|
first = diagnostics["campaign_link_candidates"][0]
|
|
assert first["href"] == "https://www.momoshop.com.tw/edm/cmmedm.jsp"
|
|
assert first["platform_score"] > 0
|
|
assert first["confidence_band"] == "high"
|
|
|
|
|
|
def test_pchome_platform_scorer_prioritizes_region_campaign_links():
|
|
adapter = get_adapter("pchome")
|
|
html = """
|
|
<html><title>PChome 活動</title><body>
|
|
<a href="https://other.example/event">外部 event</a>
|
|
<a href="/region/DDAB">PChome 24h 美妝優惠</a>
|
|
</body></html>
|
|
"""
|
|
|
|
diagnostics = parse_html_diagnostics(
|
|
html,
|
|
base_url=adapter.base_url,
|
|
score_link=adapter.score_campaign_link,
|
|
).to_dict()
|
|
|
|
first = diagnostics["campaign_link_candidates"][0]
|
|
assert first["href"] == "https://24h.pchome.com.tw/region/DDAB"
|
|
assert first["platform_score"] > 0
|
|
assert first["confidence_band"] == "high"
|
|
|
|
|
|
def test_coupang_platform_scorer_prioritizes_official_campaign_links():
|
|
adapter = get_adapter("coupang")
|
|
html = """
|
|
<html><title>Coupang 活動</title><body>
|
|
<a href="https://other.example/event">外部 event</a>
|
|
<a href="/np/coupangglobal">酷澎 火箭跨境優惠</a>
|
|
</body></html>
|
|
"""
|
|
|
|
diagnostics = parse_html_diagnostics(
|
|
html,
|
|
base_url=adapter.base_url,
|
|
score_link=adapter.score_campaign_link,
|
|
).to_dict()
|
|
|
|
first = diagnostics["campaign_link_candidates"][0]
|
|
assert first["href"] == "https://www.tw.coupang.com/np/coupangglobal"
|
|
assert first["platform_score"] > 0
|
|
assert first["confidence_band"] == "high"
|
|
|
|
|
|
def test_shopee_platform_scorer_prioritizes_mall_campaign_links():
|
|
adapter = get_adapter("shopee")
|
|
html = """
|
|
<html><title>Shopee 活動</title><body>
|
|
<a href="https://other.example/event">外部 event</a>
|
|
<a href="/mall">蝦皮商城 品牌限時優惠</a>
|
|
</body></html>
|
|
"""
|
|
|
|
diagnostics = parse_html_diagnostics(
|
|
html,
|
|
base_url=adapter.base_url,
|
|
score_link=adapter.score_campaign_link,
|
|
).to_dict()
|
|
|
|
first = diagnostics["campaign_link_candidates"][0]
|
|
assert first["href"] == "https://shopee.tw/mall"
|
|
assert first["platform_score"] > 0
|
|
assert first["confidence_band"] == "high"
|
|
|
|
|
|
def test_confidence_bands_cover_high_medium_low():
|
|
adapter = get_adapter("momo")
|
|
html = """
|
|
<html><title>信心帶測試</title><body>
|
|
<a href="/edm/cmmedm.jsp">MOMO 限時品牌日活動優惠</a>
|
|
<a href="https://neutral.example/event-light">活動</a>
|
|
<a href="https://other.example/sale">清單</a>
|
|
</body></html>
|
|
"""
|
|
|
|
diagnostics = parse_html_diagnostics(
|
|
html,
|
|
base_url=adapter.base_url,
|
|
score_link=adapter.score_campaign_link,
|
|
).to_dict()
|
|
bands = {item["href"]: item["confidence_band"] for item in diagnostics["campaign_link_candidates"]}
|
|
|
|
assert bands["https://www.momoshop.com.tw/edm/cmmedm.jsp"] == "high"
|
|
assert bands["https://neutral.example/event-light"] == "medium"
|
|
assert bands["https://other.example/sale"] == "low"
|
|
for item in diagnostics["campaign_link_candidates"]:
|
|
assert item["confidence_reason"]
|
|
|
|
|
|
def test_candidate_preview_default_is_empty_and_does_not_call_network():
|
|
called = {"count": 0}
|
|
|
|
def fake_get(*args, **kwargs):
|
|
called["count"] += 1
|
|
raise AssertionError("candidate preview 預設不應發 HTTP request")
|
|
|
|
preview = MarketIntelService().build_candidate_preview("momo", fetch=False, http_get=fake_get)
|
|
|
|
assert called["count"] == 0
|
|
assert preview["candidate_count"] == 0
|
|
assert preview["database_write_allowed"] is False
|
|
assert preview["scheduler_attached"] is False
|
|
assert preview["mcp_fetch_gate_open"] is False
|
|
assert preview["mcp_fetch_gate"]["network_request_allowed"] is False
|
|
assert preview["run_statuses"][0]["status"] == "planned"
|
|
|
|
|
|
def test_candidate_preview_fetch_is_blocked_when_flags_are_off():
|
|
called = {"count": 0}
|
|
|
|
def fake_get(*args, **kwargs):
|
|
called["count"] += 1
|
|
raise AssertionError("flags 關閉時 candidate preview 不應發 HTTP request")
|
|
|
|
preview = MarketIntelService().build_candidate_preview("momo", fetch=True, http_get=fake_get)
|
|
|
|
assert called["count"] == 0
|
|
assert preview["candidate_count"] == 0
|
|
assert preview["run_statuses"][0]["status"] == "blocked"
|
|
assert preview["mcp_fetch_gate_open"] is False
|
|
assert "market_intel_enabled" in preview["mcp_fetch_gate"]["blocked_reasons"]
|
|
|
|
|
|
def test_candidate_preview_aggregates_and_filters_by_band():
|
|
discovery = {
|
|
"platform_code": "all",
|
|
"fetch_requested": True,
|
|
"manual_fetch_allowed": True,
|
|
"runs": [
|
|
{
|
|
"platform_code": "momo",
|
|
"status": "success",
|
|
"sources_planned": 1,
|
|
"sources_fetched": 1,
|
|
"errors": 0,
|
|
"results": [
|
|
{
|
|
"source_key": "momo_edm",
|
|
"name": "MOMO EDM",
|
|
"url": "https://www.momoshop.com.tw/edm/cmmedm.jsp",
|
|
"status": "fetched",
|
|
"diagnostics": {
|
|
"title": "MOMO 活動",
|
|
"page_hash": "hash-a",
|
|
"campaign_link_candidates": [
|
|
{
|
|
"href": "https://www.momoshop.com.tw/edm/a",
|
|
"text": "品牌日",
|
|
"is_same_host": True,
|
|
"score": 20,
|
|
"generic_score": 6,
|
|
"platform_score": 14,
|
|
"confidence_band": "high",
|
|
"confidence_reason": "same_host",
|
|
},
|
|
{
|
|
"href": "https://other.example/sale",
|
|
"text": "清單",
|
|
"is_same_host": False,
|
|
"score": 2,
|
|
"generic_score": 2,
|
|
"platform_score": 0,
|
|
"confidence_band": "low",
|
|
"confidence_reason": "external_host",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
],
|
|
}
|
|
],
|
|
}
|
|
|
|
preview = build_candidate_preview_from_discovery(discovery, min_band="medium", limit=10)
|
|
|
|
assert preview["candidate_count"] == 1
|
|
assert preview["candidates"][0]["confidence_band"] == "high"
|
|
assert preview["candidates"][0]["platform_code"] == "momo"
|
|
assert preview["candidates"][0]["source_key"] == "momo_edm"
|
|
|
|
|
|
def test_market_intel_preview_template_uses_safe_fetch_false_endpoint():
|
|
template = Path("templates/market_intel/disabled.html").read_text(encoding="utf-8")
|
|
|
|
assert "data-market-intel-preview" in template
|
|
assert "data-market-intel-writer" in template
|
|
assert "data-market-intel-cli" in template
|
|
assert "data-market-intel-cli-body" in template
|
|
assert "data-market-intel-db-probe" in template
|
|
assert "data-market-intel-db-probe-body" in template
|
|
assert "data-market-intel-seed-diff" in template
|
|
assert "data-market-intel-seed-diff-body" in template
|
|
assert "data-market-intel-mcp-readiness" in template
|
|
assert "data-market-intel-mcp-servers" in template
|
|
assert "data-market-intel-mcp-checks" in template
|
|
assert "data-market-intel-mcp-tools" in template
|
|
assert "market_intel_contract" in template
|
|
assert "data-market-intel-mcp-preflight" in template
|
|
assert "data-market-intel-mcp-preflight-env" in template
|
|
assert "data-market-intel-mcp-preflight-services" in template
|
|
assert "data-market-intel-mcp-preflight-ports" in template
|
|
assert "data-market-intel-mcp-preflight-fallback" in template
|
|
assert "data-market-intel-mcp-activation" in template
|
|
assert "data-market-intel-mcp-activation-stages" in template
|
|
assert "data-market-intel-mcp-activation-safety" in template
|
|
assert "data-market-intel-mcp-activation-fallback" in template
|
|
assert "data-market-intel-mcp-fetch-gate" in template
|
|
assert "data-market-intel-mcp-fetch-gate-checks" in template
|
|
assert "data-market-intel-mcp-fetch-gate-sequence" in template
|
|
assert "data-market-intel-mcp-fetch-gate-readiness" in template
|
|
assert "data-market-intel-scheduler" in template
|
|
assert "data-market-intel-scheduler-checks" in template
|
|
assert "data-market-intel-scheduler-jobs" in template
|
|
assert "data-market-intel-scheduler-sequence" in template
|
|
assert "data-market-intel-scheduler-fallback" in template
|
|
assert "data-market-intel-match-review" in template
|
|
assert "data-market-intel-match-review-checks" in template
|
|
assert "data-market-intel-match-review-signals" in template
|
|
assert "data-market-intel-match-review-actions" in template
|
|
assert "data-market-intel-match-review-sequence" in template
|
|
assert "data-market-intel-opportunity" in template
|
|
assert "data-market-intel-opportunity-checks" in template
|
|
assert "data-market-intel-opportunity-rules" in template
|
|
assert "data-market-intel-opportunity-severity" in template
|
|
assert "data-market-intel-opportunity-sequence" in template
|
|
assert "data-market-intel-opportunity-scoring" in template
|
|
assert "data-market-intel-opportunity-scoring-checks" in template
|
|
assert "data-market-intel-opportunity-scoring-dimensions" in template
|
|
assert "data-market-intel-opportunity-scoring-thresholds" in template
|
|
assert "data-market-intel-opportunity-scoring-evidence" in template
|
|
assert "data-market-intel-opportunity-scoring-sequence" in template
|
|
assert "data-market-intel-opportunity-evidence" in template
|
|
assert "data-market-intel-opportunity-evidence-checks" in template
|
|
assert "data-market-intel-opportunity-evidence-sections" in template
|
|
assert "data-market-intel-opportunity-evidence-escalation" in template
|
|
assert "data-market-intel-opportunity-evidence-tables" in template
|
|
assert "data-market-intel-opportunity-evidence-sequence" in template
|
|
assert "data-market-intel-opportunity-alert" in template
|
|
assert "data-market-intel-opportunity-alert-checks" in template
|
|
assert "data-market-intel-opportunity-alert-channels" in template
|
|
assert "data-market-intel-opportunity-alert-escalation" in template
|
|
assert "data-market-intel-opportunity-alert-payload" in template
|
|
assert "data-market-intel-opportunity-alert-review" in template
|
|
assert "data-market-intel-opportunity-alert-actions" in template
|
|
assert "data-market-intel-opportunity-alert-queue-contract" in template
|
|
assert "data-market-intel-opportunity-alert-priority-lanes" in template
|
|
assert "data-market-intel-opportunity-alert-queue-indexes" in template
|
|
assert "data-market-intel-opportunity-alert-approval" in template
|
|
assert "data-market-intel-opportunity-alert-sequence" in template
|
|
assert "data-market-intel-migration" in template
|
|
assert "data-market-intel-migration-tables" in template
|
|
assert "data-market-intel-migration-drill" in template
|
|
assert "data-market-intel-migration-drill-checks" in template
|
|
assert "data-market-intel-migration-drill-preapply" in template
|
|
assert "data-market-intel-migration-drill-rollback" in template
|
|
assert "data-market-intel-catalog-review" in template
|
|
assert "data-market-intel-catalog-review-checks" in template
|
|
assert "data-market-intel-catalog-review-findings" in template
|
|
assert "data-market-intel-catalog-review-tables" in template
|
|
assert "data-market-intel-live-smoke" in template
|
|
assert "data-market-intel-live-smoke-checks" in template
|
|
assert "data-market-intel-live-smoke-findings" in template
|
|
assert "data-market-intel-live-smoke-targets" in template
|
|
assert "data-market-intel-live-inventory" in template
|
|
assert "data-market-intel-live-inventory-checks" in template
|
|
assert "data-market-intel-live-inventory-tables" in template
|
|
assert "data-market-intel-live-inventory-platforms" in template
|
|
assert "data-market-intel-live-inventory-alerts" in template
|
|
assert "data-market-intel-manual-sample" in template
|
|
assert "data-market-intel-manual-sample-checks" in template
|
|
assert "data-market-intel-manual-sample-platforms" in template
|
|
assert "data-market-intel-manual-sample-sequence" in template
|
|
assert "data-market-intel-sample-acceptance" in template
|
|
assert "data-market-intel-sample-acceptance-checks" in template
|
|
assert "data-market-intel-sample-acceptance-fields" in template
|
|
assert "data-market-intel-sample-acceptance-rules" in template
|
|
assert "data-market-intel-sample-review" in template
|
|
assert "data-market-intel-sample-review-checks" in template
|
|
assert "data-market-intel-sample-review-findings" in template
|
|
assert "data-market-intel-sample-review-actions" in template
|
|
assert "data-market-intel-sample-review-boundaries" in template
|
|
assert "data-market-intel-sample-review-input" in template
|
|
assert "data-market-intel-sample-review-evaluate" in template
|
|
assert "data-market-intel-sample-candidate-handoff" in template
|
|
assert "data-market-intel-sample-review-actions-rail" in template
|
|
assert ".market-intel-control-actions" in template
|
|
assert "grid-template-columns: minmax(0, 1fr) auto auto auto" not in template
|
|
assert "data-market-intel-sample-candidate-queue-draft" in template
|
|
assert "data-market-intel-sample-candidate-queue-approval" in template
|
|
assert "data-market-intel-sample-candidate-queue-transaction" in template
|
|
assert "data-market-intel-sample-candidate-queue-writer" in template
|
|
assert "data-market-intel-sample-candidate-queue-preflight" in template
|
|
assert "data-market-intel-sample-candidate-queue-run-receipt" in template
|
|
assert "data-market-intel-sample-candidate-queue-run-closeout" in template
|
|
assert "data-market-intel-sample-candidate-queue-review-handoff" in template
|
|
assert "data-market-intel-sample-candidate-queue-review-inventory" in template
|
|
assert "data-market-intel-sample-candidate-queue-review-decision" in template
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-approval"
|
|
in template
|
|
)
|
|
assert "data-market-intel-approval" in template
|
|
assert "data-market-intel-approval-gates" in template
|
|
assert "data-market-intel-deploy" in template
|
|
assert "data-market-intel-deploy-steps" in template
|
|
assert "data-market-intel-deploy-fallback" in template
|
|
assert "market_intel.market_intel_candidate_preview" in template
|
|
assert "market_intel.market_intel_platform_seed_writer_plan" in template
|
|
assert "market_intel.market_intel_seed_writer_cli_status" in template
|
|
assert "market_intel.market_intel_schema_db_probe" in template
|
|
assert "market_intel.market_intel_platform_seed_db_diff" in template
|
|
assert "market_intel.market_intel_legacy_source_bridge" in template
|
|
assert "market_intel.market_intel_mcp_readiness" in template
|
|
assert "market_intel.market_intel_mcp_deploy_preflight" in template
|
|
assert "market_intel.market_intel_mcp_activation_runbook" in template
|
|
assert "market_intel.market_intel_mcp_fetch_gate" in template
|
|
assert "market_intel.market_intel_mcp_completion_audit" in template
|
|
assert "data-market-intel-mcp-completion" in template
|
|
assert "market_intel.market_intel_mcp_activation_evidence" in template
|
|
assert "data-market-intel-mcp-activation-evidence" in template
|
|
assert "market_intel.market_intel_mcp_runtime_smoke_receipt" in template
|
|
assert "data-market-intel-mcp-runtime-smoke" in template
|
|
assert "market_intel.market_intel_mcp_runtime_promotion" in template
|
|
assert "data-market-intel-mcp-runtime-promotion" in template
|
|
assert "market_intel.market_intel_mcp_manual_fetch_handoff" in template
|
|
assert "data-market-intel-mcp-manual-fetch-handoff" in template
|
|
assert "data-market-intel-mcp-manual-fetch-handoff-gates" in template
|
|
assert "data-market-intel-mcp-manual-fetch-handoff-summary" in template
|
|
assert "data-market-intel-mcp-manual-fetch-handoff-next" in template
|
|
assert "market_intel.market_intel_mcp_fetch_target_review" in template
|
|
assert "data-market-intel-mcp-fetch-target-review" in template
|
|
assert "data-market-intel-mcp-fetch-target-review-gates" in template
|
|
assert "data-market-intel-mcp-fetch-target-review-targets" in template
|
|
assert "data-market-intel-mcp-fetch-target-review-next" in template
|
|
assert "market_intel.market_intel_mcp_fetch_run_package" in template
|
|
assert "data-market-intel-mcp-fetch-run-package" in template
|
|
assert "data-market-intel-mcp-fetch-run-package-gates" in template
|
|
assert "data-market-intel-mcp-fetch-run-package-commands" in template
|
|
assert "data-market-intel-mcp-fetch-run-package-next" in template
|
|
assert "market_intel.market_intel_mcp_fetch_run_readiness" in template
|
|
assert "data-market-intel-mcp-fetch-run-readiness" in template
|
|
assert "data-market-intel-mcp-fetch-run-readiness-gates" in template
|
|
assert "data-market-intel-mcp-fetch-run-readiness-operator" in template
|
|
assert "data-market-intel-mcp-fetch-run-readiness-commands" in template
|
|
assert "data-market-intel-mcp-fetch-run-readiness-next" in template
|
|
assert "market_intel.market_intel_mcp_fetch_run_receipt" in template
|
|
assert "data-market-intel-mcp-fetch-run-receipt" in template
|
|
assert "data-market-intel-mcp-fetch-run-receipt-gates" in template
|
|
assert "data-market-intel-mcp-fetch-run-receipt-receipt" in template
|
|
assert "data-market-intel-mcp-fetch-run-receipt-sources" in template
|
|
assert "data-market-intel-mcp-fetch-run-receipt-next" in template
|
|
assert "market_intel.market_intel_mcp_fetch_result_parser_review" in template
|
|
assert "data-market-intel-mcp-fetch-result-parser-review" in template
|
|
assert "data-market-intel-mcp-fetch-result-parser-review-gates" in template
|
|
assert "data-market-intel-mcp-fetch-result-parser-review-parser" in template
|
|
assert "data-market-intel-mcp-fetch-result-parser-review-sources" in template
|
|
assert "data-market-intel-mcp-fetch-result-parser-review-candidates" in template
|
|
assert "data-market-intel-mcp-fetch-result-parser-review-next" in template
|
|
assert "market_intel.market_intel_mcp_fetch_candidate_handoff_review" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-handoff-review" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-handoff-review-gates" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-handoff-review-parser" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-handoff-review-groups" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-handoff-review-queue" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-handoff-review-next" in template
|
|
assert "market_intel.market_intel_mcp_fetch_candidate_queue_review" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-queue-review" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-queue-review-gates" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-queue-review-handoff" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-queue-review-items" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-queue-review-policy" in template
|
|
assert "data-market-intel-mcp-fetch-candidate-queue-review-next" in template
|
|
assert "market_intel.market_intel_manual_sample_plan" in template
|
|
assert "market_intel.market_intel_manual_sample_acceptance" in template
|
|
assert "market_intel.market_intel_manual_sample_review" in template
|
|
assert "market_intel.market_intel_manual_sample_review_evaluate" in template
|
|
assert "market_intel.market_intel_manual_sample_candidate_handoff" in template
|
|
assert "market_intel.market_intel_manual_sample_candidate_queue_draft" in template
|
|
assert "market_intel.market_intel_manual_sample_candidate_queue_approval" in template
|
|
assert "market_intel.market_intel_manual_sample_candidate_queue_transaction" in template
|
|
assert "market_intel.market_intel_manual_sample_candidate_queue_writer_status" in template
|
|
assert "market_intel.market_intel_manual_sample_candidate_queue_writer_preflight" in template
|
|
assert (
|
|
"market_intel.market_intel_manual_sample_candidate_queue_writer_postwrite_smoke"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel.market_intel_manual_sample_candidate_queue_writer_operator_drill"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel.market_intel_manual_sample_candidate_queue_writer_run_package"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel.market_intel_manual_sample_candidate_queue_writer_run_readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel.market_intel_manual_sample_candidate_queue_writer_run_receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel.market_intel_manual_sample_candidate_queue_writer_run_closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel.market_intel_manual_sample_candidate_queue_review_handoff"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_inventory"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_approval"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_transaction"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-transaction"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_status"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_postwrite_smoke"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_operator_drill"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_package"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_writer_run_closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_decision_post_closeout_inventory"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_completion_archive"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_archive_summary"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_run_package"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_output_receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_transaction"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_writer_preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_run_package"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_run_readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_run_receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_run_closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-writer"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-postwrite-smoke"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-operator-drill"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-run-package"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-run-readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-run-receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-run-closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-decision-post-closeout-inventory"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-completion-archive"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-archive-summary"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-run-package"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-output-receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-transaction"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-writer-preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-run-package"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-run-readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-run-receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-run-closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-gate"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-run-package"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-run-readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-run-receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-archive"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-archive-summary"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-input"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-run-package"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-run-readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-run-receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-archive"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-archive-summary"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-handoff"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-index"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-write-preflight"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-write"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-run-package"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-run-readiness"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-run-receipt"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-commit"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-archive"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-archive-summary"
|
|
in template
|
|
)
|
|
assert (
|
|
"market_intel_review.market_intel_manual_sample_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
in template
|
|
)
|
|
assert (
|
|
"data-market-intel-sample-candidate-queue-review-ai-summary-persistence-telegram-dispatch-report-catalog-record-final-closeout"
|
|
in template
|
|
)
|
|
assert "X-CSRFToken" in template
|
|
assert "market_intel.market_intel_scheduler_plan" in template
|
|
assert "market_intel.market_intel_match_review_plan" in template
|
|
assert "market_intel.market_intel_opportunity_plan" in template
|
|
assert "market_intel.market_intel_opportunity_scoring_plan" in template
|
|
assert "market_intel.market_intel_opportunity_evidence_plan" in template
|
|
assert "market_intel.market_intel_opportunity_alert_plan" in template
|
|
assert "market_intel.market_intel_migration_blueprint" in template
|
|
assert "market_intel.market_intel_migration_apply_drill" in template
|
|
assert "market_intel.market_intel_migration_catalog_review" in template
|
|
assert "market_intel.market_intel_migration_live_smoke" in template
|
|
assert "market_intel.market_intel_live_db_inventory" in template
|
|
assert "market_intel.market_intel_write_approval_runbook" in template
|
|
assert "market_intel.market_intel_deployment_readiness" in template
|
|
assert "required_manual_steps" in template
|
|
assert "fallback_plan" in template
|
|
assert "approval_gates" in template
|
|
assert "備援方案" in template
|
|
assert "fetch=false" in template
|
|
assert "fetch=true" not in template
|
|
assert "execute=false" in template
|
|
assert "execute=true" not in template
|
|
assert "writes=executed" not in template
|
|
assert "API 不執行推版" in template
|
|
|
|
|
|
def test_market_intel_schema_metadata_contains_all_market_tables():
|
|
metadata_tables = set(Base.metadata.tables)
|
|
|
|
assert set(MARKET_INTEL_TABLES) <= metadata_tables
|
|
|
|
|
|
def test_legacy_source_bridge_default_is_planned_only():
|
|
bridge = MarketIntelService().build_legacy_source_bridge()
|
|
|
|
assert bridge["mode"] == "legacy_source_bridge_planned"
|
|
assert bridge["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert bridge["execute_requested"] is False
|
|
assert bridge["read_only_query_executed"] is False
|
|
assert bridge["database_connection_opened"] is False
|
|
assert bridge["database_session_created"] is False
|
|
assert bridge["database_write_executed"] is False
|
|
assert bridge["database_commit_executed"] is False
|
|
assert bridge["external_network_executed"] is False
|
|
assert bridge["scheduler_attached"] is False
|
|
assert bridge["writes_executed"] is False
|
|
assert bridge["would_write_database"] is False
|
|
assert bridge["source_count"] == 3
|
|
assert bridge["existing_source_count"] == 0
|
|
assert "execute_false_planned_only" in bridge["blocked_reasons"]
|
|
assert {item["table"] for item in bridge["source_summaries"]} == {
|
|
"promo_products",
|
|
"competitor_prices",
|
|
"competitor_price_history",
|
|
}
|
|
|
|
|
|
def test_legacy_source_bridge_read_only_sqlite_counts_sources():
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE promo_products (
|
|
id INTEGER PRIMARY KEY,
|
|
batch_id TEXT,
|
|
crawled_at TEXT,
|
|
time_slot TEXT,
|
|
activity_time_text TEXT,
|
|
session_time_text TEXT,
|
|
i_code TEXT,
|
|
name TEXT,
|
|
price INTEGER,
|
|
discount_text TEXT,
|
|
url TEXT,
|
|
image_url TEXT,
|
|
previous_price INTEGER,
|
|
remain_qty INTEGER,
|
|
status_change TEXT,
|
|
page_type TEXT
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE competitor_prices (
|
|
id INTEGER PRIMARY KEY,
|
|
sku TEXT,
|
|
source TEXT,
|
|
price NUMERIC,
|
|
original_price NUMERIC,
|
|
discount_pct INTEGER,
|
|
competitor_product_id TEXT,
|
|
competitor_product_name TEXT,
|
|
match_score NUMERIC,
|
|
crawled_at TEXT
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE competitor_price_history (
|
|
id INTEGER PRIMARY KEY,
|
|
sku TEXT,
|
|
source TEXT,
|
|
momo_product_id INTEGER,
|
|
momo_price NUMERIC,
|
|
price NUMERIC,
|
|
original_price NUMERIC,
|
|
discount_pct INTEGER,
|
|
competitor_product_id TEXT,
|
|
competitor_product_name TEXT,
|
|
match_score NUMERIC,
|
|
crawled_at TEXT
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
INSERT INTO promo_products
|
|
(batch_id, crawled_at, time_slot, i_code, name, price, discount_text, url, page_type)
|
|
VALUES
|
|
('batch-1', '2026-05-18 10:00:00', '10:00', 'A001', 'MOMO 商品 A', 399, '8折', 'https://momo/A001', 'edm'),
|
|
('batch-1', '2026-05-18 10:01:00', '10:00', 'A002', 'MOMO 商品 B', 499, '9折', 'https://momo/A002', 'edm')
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
INSERT INTO competitor_prices
|
|
(sku, source, price, original_price, competitor_product_id, competitor_product_name, match_score, crawled_at)
|
|
VALUES
|
|
('A001', 'pchome', 379, 459, 'PC-A001', 'PChome 商品 A', 0.82, '2026-05-18 11:00:00')
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
INSERT INTO competitor_price_history
|
|
(sku, source, momo_product_id, momo_price, price, original_price, competitor_product_id, competitor_product_name, match_score, crawled_at)
|
|
VALUES
|
|
('A001', 'pchome', 1, 399, 379, 459, 'PC-A001', 'PChome 商品 A', 0.82, '2026-05-18 11:00:00')
|
|
"""
|
|
)
|
|
)
|
|
|
|
bridge = MarketIntelService().build_legacy_source_bridge(
|
|
execute_requested=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
|
|
assert bridge["mode"] == "legacy_source_bridge_read_only"
|
|
assert bridge["execute_requested"] is True
|
|
assert bridge["read_only_query_executed"] is True
|
|
assert bridge["database_connection_opened"] is True
|
|
assert bridge["database_session_created"] is False
|
|
assert bridge["database_write_executed"] is False
|
|
assert bridge["database_commit_executed"] is False
|
|
assert bridge["external_network_executed"] is False
|
|
assert bridge["scheduler_attached"] is False
|
|
assert bridge["writes_executed"] is False
|
|
assert bridge["would_write_database"] is False
|
|
assert bridge["source_tables_ready"] is True
|
|
assert bridge["existing_source_count"] == 3
|
|
assert bridge["total_existing_rows"] == 4
|
|
assert [item["table"] for item in bridge["source_summaries"]] == [
|
|
"promo_products",
|
|
"competitor_prices",
|
|
"competitor_price_history",
|
|
]
|
|
assert bridge["source_summaries"][0]["row_count"] == 2
|
|
assert bridge["source_summaries"][0]["distinct_entity_count"] == 2
|
|
assert bridge["source_summaries"][1]["row_count"] == 1
|
|
assert bridge["source_summaries"][2]["row_count"] == 1
|
|
assert len(bridge["bridge_operations"]) == 4
|
|
assert all(
|
|
item["write_status"] != "executed"
|
|
for item in bridge["bridge_operations"]
|
|
)
|
|
|
|
|
|
def test_mcp_tool_contract_preview_is_read_only_and_whitelisted():
|
|
contract = MarketIntelService().build_mcp_tool_contract()
|
|
|
|
assert contract["mode"] == "mcp_tool_contract_preview"
|
|
assert contract["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert contract["caller"] == "market_intel"
|
|
assert contract["contract_ready"] is True
|
|
assert contract["blocked_reasons"] == []
|
|
assert contract["tool_count"] == 3
|
|
assert contract["database_session_created"] is False
|
|
assert contract["database_write_executed"] is False
|
|
assert contract["database_commit_executed"] is False
|
|
assert contract["external_network_executed"] is False
|
|
assert contract["scheduler_attached"] is False
|
|
assert contract["writes_executed"] is False
|
|
assert contract["would_write_database"] is False
|
|
assert contract["checks"]["market_intel_caller_registered"] is True
|
|
assert contract["checks"]["all_router_tools_whitelisted"] is True
|
|
assert contract["checks"]["all_tools_read_only"] is True
|
|
assert contract["checks"]["no_database_write_allowed"] is True
|
|
assert contract["checks"]["no_scheduler_attach_allowed"] is True
|
|
assert {item["name"] for item in contract["tools"]} == {
|
|
"market_campaign_search",
|
|
"market_campaign_scrape",
|
|
"market_product_match_lookup",
|
|
}
|
|
assert all(item["router_tools_whitelisted"] is True for item in contract["tools"])
|
|
assert all(item["write_risk"] is False for item in contract["tools"])
|
|
|
|
|
|
def test_mcp_tool_contract_detects_missing_router_whitelist():
|
|
contract = build_mcp_tool_contract_preview(tool_registry={})
|
|
|
|
assert contract["contract_ready"] is False
|
|
assert "market_intel_caller_registered" in contract["blocked_reasons"]
|
|
assert "all_router_tools_whitelisted" in contract["blocked_reasons"]
|
|
|
|
|
|
def test_mcp_tool_contract_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/mcp_tool_contract")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "mcp_tool_contract_preview"
|
|
assert data["contract_ready"] is True
|
|
assert data["database_session_created"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_activation_runbook_blocks_until_env_and_health_pass():
|
|
preflight = build_mcp_deploy_preflight_plan(env={})
|
|
runbook = build_mcp_activation_runbook_preview(preflight=preflight)
|
|
|
|
assert runbook["mode"] == "mcp_activation_runbook_preview"
|
|
assert runbook["ready_for_operator_activation"] is False
|
|
assert "required_env_ready" in runbook["blocked_reasons"]
|
|
assert "external_health_smoke_not_executed" in runbook["blocked_reasons"]
|
|
assert runbook["deployment_actions_executed"] is False
|
|
assert runbook["docker_command_executed"] is False
|
|
assert runbook["ssh_command_executed"] is False
|
|
assert runbook["database_session_created"] is False
|
|
assert runbook["database_write_executed"] is False
|
|
assert runbook["database_commit_executed"] is False
|
|
assert runbook["external_network_executed"] is False
|
|
assert runbook["scheduler_attached"] is False
|
|
assert runbook["would_write_database"] is False
|
|
assert runbook["safety_contract"]["does_not_execute_docker"] is True
|
|
assert runbook["safety_contract"]["does_not_enable_router"] is True
|
|
assert {item["key"] for item in runbook["stages"]} == {
|
|
"configure_required_env",
|
|
"create_mcp_readonly_role",
|
|
"start_external_mcp_stack",
|
|
"run_mcp_health_smoke",
|
|
"enable_mcp_router_flag",
|
|
"run_market_intel_mcp_smoke",
|
|
}
|
|
|
|
|
|
def test_mcp_activation_runbook_can_be_ready_with_mocked_gates():
|
|
preflight = build_mcp_deploy_preflight_plan(
|
|
env={
|
|
"MCP_POSTGRES_PASSWORD": "secret",
|
|
"TAVILY_API_KEY": "tavily",
|
|
"EXA_API_KEY": "exa",
|
|
"MCP_ROUTER_ENABLED": "false",
|
|
}
|
|
)
|
|
readiness = {
|
|
"readiness_checks": {
|
|
"external_server_health_checked": True,
|
|
"external_servers_all_healthy": True,
|
|
"market_intel_tool_contract_ready": True,
|
|
}
|
|
}
|
|
|
|
runbook = build_mcp_activation_runbook_preview(
|
|
preflight=preflight,
|
|
readiness=readiness,
|
|
)
|
|
|
|
assert runbook["ready_for_operator_activation"] is True
|
|
assert runbook["blocked_reasons"] == []
|
|
assert runbook["checks"]["required_env_ready"] is True
|
|
assert runbook["checks"]["all_health_passed"] is True
|
|
assert {
|
|
item["key"]: item["status"]
|
|
for item in runbook["stages"]
|
|
}["enable_mcp_router_flag"] == "ready"
|
|
|
|
|
|
def test_mcp_activation_runbook_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/mcp_activation_runbook")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "mcp_activation_runbook_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["deployment_actions_executed"] is False
|
|
assert data["docker_command_executed"] is False
|
|
assert data["ssh_command_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_gate_default_blocks_external_fetch():
|
|
gate = MarketIntelService().build_mcp_fetch_gate(fetch_requested=True)
|
|
|
|
assert gate["mode"] == "mcp_fetch_gate_planned"
|
|
assert gate["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert gate["fetch_requested"] is True
|
|
assert gate["manual_fetch_gate_open"] is False
|
|
assert gate["network_request_allowed"] is False
|
|
assert gate["would_use_external_network"] is False
|
|
assert gate["database_session_created"] is False
|
|
assert gate["database_write_executed"] is False
|
|
assert gate["database_commit_executed"] is False
|
|
assert gate["external_network_executed"] is False
|
|
assert gate["scheduler_attached"] is False
|
|
assert gate["writes_executed"] is False
|
|
assert gate["would_write_database"] is False
|
|
assert "market_intel_enabled" in gate["blocked_reasons"]
|
|
assert "market_intel_crawler_enabled" in gate["blocked_reasons"]
|
|
assert "mcp_readiness_executed" in gate["blocked_reasons"]
|
|
assert "mcp_router_enabled" in gate["blocked_reasons"]
|
|
|
|
|
|
def test_mcp_fetch_gate_can_open_with_mocked_ready_state():
|
|
class RuntimeStatus:
|
|
enabled = True
|
|
crawler_enabled = True
|
|
database_write_allowed = False
|
|
scheduler_attached = False
|
|
|
|
readiness = {
|
|
"mode": "mcp_readiness_read_only",
|
|
"execute_requested": True,
|
|
"router_enabled": True,
|
|
"external_mcp_complete": True,
|
|
"internal_mcp_complete": True,
|
|
"market_intel_mcp_integrated": True,
|
|
"blocked_reasons": [],
|
|
"readiness_checks": {
|
|
"market_intel_tool_contract_ready": True,
|
|
"external_servers_all_healthy": True,
|
|
},
|
|
}
|
|
|
|
gate = build_mcp_fetch_gate_preview(
|
|
RuntimeStatus(),
|
|
fetch_requested=True,
|
|
execute_readiness=True,
|
|
readiness=readiness,
|
|
)
|
|
|
|
assert gate["mode"] == "mcp_fetch_gate_read_only"
|
|
assert gate["manual_fetch_prerequisites_met"] is True
|
|
assert gate["manual_fetch_gate_open"] is True
|
|
assert gate["network_request_allowed"] is True
|
|
assert gate["blocked_reasons"] == []
|
|
assert gate["database_write_executed"] is False
|
|
assert gate["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_gate_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/mcp_fetch_gate")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "mcp_fetch_gate_planned"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["fetch_requested"] is False
|
|
assert data["network_request_allowed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_completion_audit_summarizes_external_and_internal_state(monkeypatch):
|
|
monkeypatch.delenv("MCP_ROUTER_ENABLED", raising=False)
|
|
|
|
audit = MarketIntelService().build_mcp_completion_audit()
|
|
|
|
assert audit["mode"] == "mcp_completion_audit_preview"
|
|
assert audit["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert audit["audit_ready_for_operator_review"] is True
|
|
assert audit["audit_preview_safe"] is True
|
|
assert audit["external_mcp_runtime_complete"] is False
|
|
assert audit["internal_mcp_contract_complete"] is True
|
|
assert audit["internal_mcp_runtime_complete"] is False
|
|
assert audit["market_intel_mcp_integrated"] is True
|
|
assert audit["ready_for_internal_mcp_use"] is True
|
|
assert audit["ready_for_external_mcp_activation"] is False
|
|
assert audit["ready_for_manual_fetch"] is False
|
|
assert audit["api_executes_health_check"] is False
|
|
assert audit["api_executes_docker"] is False
|
|
assert audit["api_opens_database_connection"] is False
|
|
assert audit["api_writes_database"] is False
|
|
assert audit["api_uses_external_network"] is False
|
|
assert audit["database_session_created"] is False
|
|
assert audit["database_write_executed"] is False
|
|
assert audit["database_commit_executed"] is False
|
|
assert audit["external_network_executed"] is False
|
|
assert audit["scheduler_attached"] is False
|
|
assert audit["writes_executed"] is False
|
|
assert audit["would_write_database"] is False
|
|
assert audit["external_mcp_summary"]["expected_servers"] == [
|
|
"postgres",
|
|
"omnisearch",
|
|
"firecrawl",
|
|
"filesystem",
|
|
]
|
|
assert audit["external_mcp_summary"]["health_checked"] is False
|
|
assert audit["internal_mcp_summary"]["tool_count"] == 3
|
|
assert audit["internal_mcp_summary"]["contract_ready"] is True
|
|
assert "external_mcp_runtime_complete" in audit["blocked_reasons"]
|
|
assert "internal_mcp_runtime_complete" in audit["blocked_reasons"]
|
|
assert "preview_side_effect_free" not in audit["blocked_reasons"]
|
|
|
|
|
|
def test_mcp_completion_audit_detects_missing_internal_contract():
|
|
class RuntimeStatus:
|
|
enabled = False
|
|
crawler_enabled = False
|
|
database_write_allowed = False
|
|
scheduler_attached = False
|
|
|
|
readiness = build_mcp_readiness_plan()
|
|
contract = build_mcp_tool_contract_preview(tool_registry={})
|
|
audit = build_mcp_completion_audit_preview(
|
|
runtime_status=RuntimeStatus(),
|
|
readiness=readiness,
|
|
tool_contract=contract,
|
|
)
|
|
|
|
assert audit["mode"] == "mcp_completion_audit_preview"
|
|
assert audit["internal_mcp_contract_complete"] is False
|
|
assert audit["ready_for_internal_mcp_use"] is False
|
|
assert "internal_mcp_contract_complete" in audit["blocked_reasons"]
|
|
assert audit["audit_preview_safe"] is True
|
|
assert audit["api_writes_database"] is False
|
|
|
|
|
|
def test_mcp_completion_audit_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/mcp_completion_audit")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "mcp_completion_audit_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["audit_preview_safe"] is True
|
|
assert data["external_mcp_runtime_complete"] is False
|
|
assert data["internal_mcp_contract_complete"] is True
|
|
assert data["ready_for_manual_fetch"] is False
|
|
assert data["api_executes_health_check"] is False
|
|
assert data["api_executes_docker"] is False
|
|
assert data["api_opens_database_connection"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_uses_external_network"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_activation_evidence_preview_is_safe_without_payload():
|
|
evidence = build_mcp_activation_evidence_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
|
|
assert evidence["mode"] == "mcp_activation_evidence_preview"
|
|
assert evidence["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert evidence["evidence_payload_received"] is False
|
|
assert evidence["activation_evidence_accepted"] is False
|
|
assert evidence["ready_for_runtime_promotion"] is False
|
|
assert evidence["payload_persisted"] is False
|
|
assert evidence["evidence_persisted"] is False
|
|
assert evidence["api_executes_health_check"] is False
|
|
assert evidence["api_opens_database_connection"] is False
|
|
assert evidence["api_writes_database"] is False
|
|
assert evidence["api_uses_external_network"] is False
|
|
assert evidence["database_write_executed"] is False
|
|
assert evidence["external_network_executed"] is False
|
|
assert evidence["scheduler_attached"] is False
|
|
assert "evidence_payload_received" in evidence["blocked_reasons"]
|
|
assert evidence["sample_evidence_template"]["required_env_vars"][
|
|
"MCP_POSTGRES_PASSWORD"
|
|
] == "redacted"
|
|
|
|
|
|
def test_mcp_activation_evidence_accepts_redacted_runtime_evidence():
|
|
sample = build_mcp_activation_evidence_preview()[
|
|
"sample_evidence_template"
|
|
]
|
|
evidence = build_mcp_activation_evidence_preview(
|
|
evidence=sample,
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert evidence["mode"] == "mcp_activation_evidence_review"
|
|
assert evidence["activation_evidence_accepted"] is True
|
|
assert evidence["ready_for_runtime_promotion"] is True
|
|
assert evidence["external_mcp_runtime_evidence_complete"] is True
|
|
assert evidence["internal_mcp_runtime_evidence_complete"] is True
|
|
assert evidence["blocked_reasons"] == []
|
|
assert evidence["passed_gate_count"] == evidence["gate_count"]
|
|
assert all(item["passed"] for item in evidence["health_statuses"])
|
|
assert all(item["present"] for item in evidence["env_statuses"])
|
|
assert evidence["secret_literal_keys"] == []
|
|
assert evidence["prohibited_flags"] == []
|
|
assert evidence["payload_persisted"] is False
|
|
assert evidence["api_writes_database"] is False
|
|
assert evidence["external_network_executed"] is False
|
|
|
|
|
|
def test_mcp_activation_evidence_blocks_secret_literals_and_write_flags():
|
|
sample = build_mcp_activation_evidence_preview()[
|
|
"sample_evidence_template"
|
|
]
|
|
sample["required_env_vars"]["TAVILY_API_KEY"] = "real-secret-token"
|
|
sample["database_write_executed"] = True
|
|
|
|
evidence = build_mcp_activation_evidence_preview(evidence=sample)
|
|
|
|
assert evidence["activation_evidence_accepted"] is False
|
|
assert "no_secret_literals_in_payload" in evidence["blocked_reasons"]
|
|
assert "no_write_or_scheduler_evidence" in evidence["blocked_reasons"]
|
|
assert evidence["secret_literal_keys"] == ["TAVILY_API_KEY"]
|
|
assert evidence["prohibited_flags"] == ["database_write_executed"]
|
|
assert evidence["database_write_executed"] is False
|
|
assert evidence["payload_persisted"] is False
|
|
|
|
|
|
def test_mcp_activation_evidence_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_activation_evidence")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_evidence_template"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_activation_evidence",
|
|
json={"evidence": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_activation_evidence_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_health_check"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_activation_evidence_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["activation_evidence_accepted"] is True
|
|
assert post_data["payload_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_runtime_smoke_receipt_preview_is_safe_without_payload():
|
|
receipt = build_mcp_runtime_smoke_receipt_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
|
|
assert receipt["mode"] == "mcp_runtime_smoke_receipt_preview"
|
|
assert receipt["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert receipt["receipt_payload_received"] is False
|
|
assert receipt["runtime_smoke_receipt_accepted"] is False
|
|
assert receipt["ready_for_completion_runtime_promotion"] is False
|
|
assert receipt["payload_persisted"] is False
|
|
assert receipt["receipt_persisted"] is False
|
|
assert receipt["api_executes_health_check"] is False
|
|
assert receipt["api_opens_database_connection"] is False
|
|
assert receipt["api_writes_database"] is False
|
|
assert receipt["api_uses_external_network"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["external_network_executed"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert "receipt_payload_received" in receipt["blocked_reasons"]
|
|
assert {item["server"] for item in receipt["sample_receipt_template"]["server_statuses"]} == {
|
|
"postgres",
|
|
"omnisearch",
|
|
"firecrawl",
|
|
"filesystem",
|
|
}
|
|
|
|
|
|
def test_mcp_runtime_smoke_receipt_accepts_complete_readiness_receipt():
|
|
sample = build_mcp_runtime_smoke_receipt_preview()[
|
|
"sample_receipt_template"
|
|
]
|
|
receipt = build_mcp_runtime_smoke_receipt_preview(
|
|
receipt=sample,
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert receipt["mode"] == "mcp_runtime_smoke_receipt_review"
|
|
assert receipt["runtime_smoke_receipt_accepted"] is True
|
|
assert receipt["ready_for_completion_runtime_promotion"] is True
|
|
assert receipt["ready_for_manual_fetch_gate_review"] is True
|
|
assert receipt["external_mcp_runtime_receipt_complete"] is True
|
|
assert receipt["internal_mcp_runtime_receipt_complete"] is True
|
|
assert receipt["blocked_reasons"] == []
|
|
assert receipt["passed_gate_count"] == receipt["gate_count"]
|
|
assert receipt["server_summary"]["all_expected_servers_present"] is True
|
|
assert receipt["server_summary"]["all_servers_health_checked"] is True
|
|
assert receipt["server_summary"]["all_servers_healthy"] is True
|
|
assert receipt["telemetry_summary"]["read_only_query_executed"] is True
|
|
assert receipt["prohibited_flags"] == []
|
|
assert receipt["payload_persisted"] is False
|
|
assert receipt["api_executes_health_check"] is False
|
|
assert receipt["api_writes_database"] is False
|
|
assert receipt["external_network_executed"] is False
|
|
|
|
|
|
def test_mcp_runtime_smoke_receipt_blocks_incomplete_or_write_receipt():
|
|
sample = build_mcp_runtime_smoke_receipt_preview()[
|
|
"sample_receipt_template"
|
|
]
|
|
sample["server_statuses"][2]["healthy"] = False
|
|
sample["telemetry"]["database_write_executed"] = True
|
|
sample["database_write_executed"] = True
|
|
sample["blocked_reasons"] = ["mcp_calls_table_missing"]
|
|
|
|
receipt = build_mcp_runtime_smoke_receipt_preview(receipt=sample)
|
|
|
|
assert receipt["runtime_smoke_receipt_accepted"] is False
|
|
assert "all_servers_healthy" in receipt["blocked_reasons"]
|
|
assert "telemetry_read_only_confirmed" in receipt["blocked_reasons"]
|
|
assert "no_database_write_or_scheduler_flags" in receipt["blocked_reasons"]
|
|
assert "receipt_has_no_blocked_reasons" in receipt["blocked_reasons"]
|
|
assert receipt["prohibited_flags"] == ["database_write_executed"]
|
|
assert receipt["receipt_blocked_reasons"] == ["mcp_calls_table_missing"]
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["payload_persisted"] is False
|
|
|
|
|
|
def test_mcp_runtime_smoke_receipt_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_runtime_smoke_receipt")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_receipt_template"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_runtime_smoke_receipt",
|
|
json={"receipt": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_runtime_smoke_receipt_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_health_check"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_runtime_smoke_receipt_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["runtime_smoke_receipt_accepted"] is True
|
|
assert post_data["receipt_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_runtime_promotion_preview_is_safe_without_payload():
|
|
promotion = build_mcp_runtime_promotion_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
|
|
assert promotion["mode"] == "mcp_runtime_promotion_preview"
|
|
assert promotion["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert promotion["promotion_payload_received"] is False
|
|
assert promotion["runtime_promotion_accepted"] is False
|
|
assert promotion["ready_for_completion_runtime_promotion"] is False
|
|
assert promotion["ready_for_manual_fetch_gate_review"] is False
|
|
assert promotion["fetch_gate_still_requires_separate_review"] is True
|
|
assert promotion["payload_persisted"] is False
|
|
assert promotion["promotion_persisted"] is False
|
|
assert promotion["api_executes_health_check"] is False
|
|
assert promotion["api_opens_database_connection"] is False
|
|
assert promotion["api_writes_database"] is False
|
|
assert promotion["api_uses_external_network"] is False
|
|
assert promotion["database_write_executed"] is False
|
|
assert promotion["external_network_executed"] is False
|
|
assert promotion["scheduler_attached"] is False
|
|
assert "activation_evidence_payload_received" in promotion["blocked_reasons"]
|
|
assert "runtime_receipt_payload_received" in promotion["blocked_reasons"]
|
|
assert "activation_evidence" in promotion["sample_promotion_package"]
|
|
assert "runtime_receipt" in promotion["sample_promotion_package"]
|
|
|
|
|
|
def test_mcp_runtime_promotion_accepts_evidence_and_receipt_package():
|
|
sample = build_mcp_runtime_promotion_preview()[
|
|
"sample_promotion_package"
|
|
]
|
|
promotion = build_mcp_runtime_promotion_preview(
|
|
activation_evidence=sample["activation_evidence"],
|
|
runtime_receipt=sample["runtime_receipt"],
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert promotion["mode"] == "mcp_runtime_promotion_review"
|
|
assert promotion["runtime_promotion_accepted"] is True
|
|
assert promotion["ready_for_completion_runtime_promotion"] is True
|
|
assert promotion["ready_for_manual_fetch_gate_review"] is True
|
|
assert promotion["external_mcp_runtime_promoted_by_receipts"] is True
|
|
assert promotion["internal_mcp_runtime_promoted_by_receipts"] is True
|
|
assert promotion["blocked_reasons"] == []
|
|
assert promotion["passed_gate_count"] == promotion["gate_count"]
|
|
assert promotion["activation_summary"]["accepted"] is True
|
|
assert promotion["runtime_receipt_summary"]["accepted"] is True
|
|
assert promotion["payload_persisted"] is False
|
|
assert promotion["promotion_persisted"] is False
|
|
assert promotion["api_executes_health_check"] is False
|
|
assert promotion["api_writes_database"] is False
|
|
assert promotion["external_network_executed"] is False
|
|
|
|
|
|
def test_mcp_runtime_promotion_blocks_partial_or_unsafe_package():
|
|
sample = build_mcp_runtime_promotion_preview()[
|
|
"sample_promotion_package"
|
|
]
|
|
sample["runtime_receipt"]["database_write_executed"] = True
|
|
|
|
promotion = build_mcp_runtime_promotion_preview(
|
|
activation_evidence=sample["activation_evidence"],
|
|
runtime_receipt=sample["runtime_receipt"],
|
|
)
|
|
|
|
assert promotion["runtime_promotion_accepted"] is False
|
|
assert "runtime_smoke_receipt_accepted" in promotion["blocked_reasons"]
|
|
assert "promotion_payload_not_persisted" not in promotion["blocked_reasons"]
|
|
assert promotion["runtime_receipt_summary"]["accepted"] is False
|
|
assert promotion["database_write_executed"] is False
|
|
assert promotion["payload_persisted"] is False
|
|
|
|
|
|
def test_mcp_runtime_promotion_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_runtime_promotion")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_promotion_package"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_runtime_promotion",
|
|
json={"promotion_package": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_runtime_promotion_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_health_check"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_runtime_promotion_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["runtime_promotion_accepted"] is True
|
|
assert post_data["promotion_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_manual_fetch_handoff_preview_is_safe_without_payload():
|
|
handoff = build_mcp_manual_fetch_handoff_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert handoff["mode"] == "mcp_manual_fetch_handoff_preview"
|
|
assert handoff["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert handoff["handoff_payload_received"] is False
|
|
assert handoff["manual_fetch_handoff_accepted"] is False
|
|
assert handoff["ready_for_manual_fetch_gate_operator_review"] is False
|
|
assert handoff["manual_fetch_gate_opened_by_api"] is False
|
|
assert handoff["network_request_allowed"] is False
|
|
assert handoff["fetch_executed"] is False
|
|
assert handoff["payload_persisted"] is False
|
|
assert handoff["handoff_persisted"] is False
|
|
assert handoff["api_executes_health_check"] is False
|
|
assert handoff["api_opens_database_connection"] is False
|
|
assert handoff["api_writes_database"] is False
|
|
assert handoff["api_uses_external_network"] is False
|
|
assert handoff["database_write_executed"] is False
|
|
assert handoff["external_network_executed"] is False
|
|
assert handoff["scheduler_attached"] is False
|
|
assert "runtime_promotion_payload_or_review_received" in handoff["blocked_reasons"]
|
|
assert "operator_acknowledgements_complete" in handoff["blocked_reasons"]
|
|
assert "promotion_package" in handoff["sample_handoff_package"]
|
|
assert "operator_acknowledgements" in handoff["sample_handoff_package"]
|
|
|
|
|
|
def test_mcp_manual_fetch_handoff_accepts_promotion_and_acknowledgements():
|
|
preview = build_mcp_manual_fetch_handoff_preview()
|
|
sample = preview["sample_handoff_package"]
|
|
handoff = build_mcp_manual_fetch_handoff_preview(
|
|
promotion_package=sample["promotion_package"],
|
|
operator_acknowledgements=sample["operator_acknowledgements"],
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert handoff["mode"] == "mcp_manual_fetch_handoff_review"
|
|
assert handoff["manual_fetch_handoff_accepted"] is True
|
|
assert handoff["ready_for_manual_fetch_gate_operator_review"] is True
|
|
assert handoff["runtime_promotion_accepted"] is True
|
|
assert handoff["operator_acknowledgements_complete"] is True
|
|
assert handoff["blocked_reasons"] == []
|
|
assert handoff["passed_gate_count"] == handoff["gate_count"]
|
|
assert handoff["promotion_summary"]["accepted"] is True
|
|
assert handoff["fetch_gate_summary"]["network_request_allowed"] is False
|
|
assert handoff["manual_fetch_gate_opened_by_api"] is False
|
|
assert handoff["network_request_allowed"] is False
|
|
assert handoff["fetch_executed"] is False
|
|
assert handoff["payload_persisted"] is False
|
|
assert handoff["handoff_persisted"] is False
|
|
assert handoff["api_executes_health_check"] is False
|
|
assert handoff["api_writes_database"] is False
|
|
assert handoff["external_network_executed"] is False
|
|
assert handoff["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_manual_fetch_handoff_blocks_missing_acknowledgement():
|
|
sample = build_mcp_manual_fetch_handoff_preview()["sample_handoff_package"]
|
|
sample["operator_acknowledgements"]["no_scheduler_attach"] = False
|
|
|
|
handoff = build_mcp_manual_fetch_handoff_preview(
|
|
promotion_package=sample["promotion_package"],
|
|
operator_acknowledgements=sample["operator_acknowledgements"],
|
|
)
|
|
|
|
assert handoff["manual_fetch_handoff_accepted"] is False
|
|
assert handoff["runtime_promotion_accepted"] is True
|
|
assert handoff["operator_acknowledgements_complete"] is False
|
|
assert "operator_acknowledgements_complete" in handoff["blocked_reasons"]
|
|
assert "ack_no_scheduler_attach" in handoff["blocked_reasons"]
|
|
assert handoff["network_request_allowed"] is False
|
|
assert handoff["database_write_executed"] is False
|
|
|
|
|
|
def test_mcp_manual_fetch_handoff_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_manual_fetch_handoff")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_handoff_package"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_manual_fetch_handoff",
|
|
json={"handoff_package": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_manual_fetch_handoff_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_health_check"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_manual_fetch_handoff_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["manual_fetch_handoff_accepted"] is True
|
|
assert post_data["manual_fetch_gate_opened_by_api"] is False
|
|
assert post_data["network_request_allowed"] is False
|
|
assert post_data["handoff_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_fetch_target_review_preview_is_safe_without_payload():
|
|
review = build_mcp_fetch_target_review_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert review["mode"] == "mcp_fetch_target_review_preview"
|
|
assert review["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert review["target_payload_received"] is False
|
|
assert review["mcp_fetch_target_review_accepted"] is False
|
|
assert review["ready_for_manual_fetch_run_package_review"] is False
|
|
assert review["adapter_target_count"] >= 4
|
|
assert review["manual_fetch_gate_opened_by_api"] is False
|
|
assert review["network_request_allowed"] is False
|
|
assert review["fetch_executed"] is False
|
|
assert review["payload_persisted"] is False
|
|
assert review["target_review_persisted"] is False
|
|
assert review["api_executes_health_check"] is False
|
|
assert review["api_opens_database_connection"] is False
|
|
assert review["api_writes_database"] is False
|
|
assert review["api_uses_external_network"] is False
|
|
assert review["database_write_executed"] is False
|
|
assert review["external_network_executed"] is False
|
|
assert review["scheduler_attached"] is False
|
|
assert "manual_fetch_handoff_payload_or_review_received" in review["blocked_reasons"]
|
|
assert "target_payload_received" in review["blocked_reasons"]
|
|
assert "handoff_package" in review["sample_target_review_package"]
|
|
assert "target_review" in review["sample_target_review_package"]
|
|
|
|
|
|
def test_mcp_fetch_target_review_accepts_sample_targets():
|
|
sample = build_mcp_fetch_target_review_preview()[
|
|
"sample_target_review_package"
|
|
]
|
|
review = build_mcp_fetch_target_review_preview(
|
|
handoff_package=sample["handoff_package"],
|
|
target_review=sample["target_review"],
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert review["mode"] == "mcp_fetch_target_review"
|
|
assert review["mcp_fetch_target_review_accepted"] is True
|
|
assert review["ready_for_manual_fetch_run_package_review"] is True
|
|
assert review["manual_fetch_handoff_accepted"] is True
|
|
assert review["operator_acknowledgements_complete"] is True
|
|
assert review["blocked_reasons"] == []
|
|
assert review["passed_gate_count"] == review["gate_count"]
|
|
assert review["platform_target_count"] >= 4
|
|
assert review["source_target_count"] >= 8
|
|
assert {item["platform_code"] for item in review["target_summaries"]} >= {
|
|
"momo",
|
|
"pchome",
|
|
"coupang",
|
|
"shopee",
|
|
}
|
|
assert all(item["ready"] for item in review["target_summaries"])
|
|
assert review["manual_fetch_gate_opened_by_api"] is False
|
|
assert review["network_request_allowed"] is False
|
|
assert review["fetch_executed"] is False
|
|
assert review["database_write_executed"] is False
|
|
assert review["target_review_persisted"] is False
|
|
assert review["api_opens_database_connection"] is False
|
|
assert review["api_uses_external_network"] is False
|
|
assert review["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_target_review_blocks_unknown_or_unsafe_target():
|
|
sample = build_mcp_fetch_target_review_preview()[
|
|
"sample_target_review_package"
|
|
]
|
|
target_review = sample["target_review"]
|
|
target_review["platform_targets"][0]["source_keys"] = ["unknown_source"]
|
|
target_review["platform_targets"][0]["delay_seconds"] = 0.1
|
|
target_review["platform_targets"][0]["allow_external_network_in_api"] = True
|
|
target_review["operator_acknowledgements"]["no_api_fetch_execution"] = False
|
|
|
|
review = build_mcp_fetch_target_review_preview(
|
|
handoff_package=sample["handoff_package"],
|
|
target_review=target_review,
|
|
)
|
|
|
|
assert review["mcp_fetch_target_review_accepted"] is False
|
|
assert review["manual_fetch_handoff_accepted"] is True
|
|
assert review["unknown_source_keys"][0]["source_key"] == "unknown_source"
|
|
assert "all_source_keys_known" in review["blocked_reasons"]
|
|
assert "rate_limits_within_policy" in review["blocked_reasons"]
|
|
assert "public_pages_only_confirmed" in review["blocked_reasons"]
|
|
assert "target_review_side_effect_free" in review["blocked_reasons"]
|
|
assert "ack_no_api_fetch_execution" in review["blocked_reasons"]
|
|
assert review["network_request_allowed"] is False
|
|
assert review["api_writes_database"] is False
|
|
assert review["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_target_review_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_fetch_target_review")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_target_review_package"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_fetch_target_review",
|
|
json={"target_review_package": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_fetch_target_review_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_health_check"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert get_data["api_uses_external_network"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_fetch_target_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["mcp_fetch_target_review_accepted"] is True
|
|
assert post_data["manual_fetch_gate_opened_by_api"] is False
|
|
assert post_data["network_request_allowed"] is False
|
|
assert post_data["fetch_executed"] is False
|
|
assert post_data["target_review_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_fetch_run_package_preview_is_safe_without_payload():
|
|
package = build_mcp_fetch_run_package_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert package["mode"] == "mcp_fetch_run_package_preview"
|
|
assert package["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert package["run_payload_received"] is False
|
|
assert package["mcp_fetch_run_package_accepted"] is False
|
|
assert package["ready_for_manual_fetch_run_readiness_review"] is False
|
|
assert package["ready_for_manual_fetch_operator_run"] is False
|
|
assert package["manual_fetch_gate_opened_by_api"] is False
|
|
assert package["network_request_allowed"] is False
|
|
assert package["fetch_executed"] is False
|
|
assert package["cli_executed"] is False
|
|
assert package["payload_persisted"] is False
|
|
assert package["run_package_persisted"] is False
|
|
assert package["command_preview_persisted"] is False
|
|
assert package["package_artifact_created"] is False
|
|
assert package["api_executes_cli"] is False
|
|
assert package["api_opens_database_connection"] is False
|
|
assert package["api_writes_database"] is False
|
|
assert package["api_uses_external_network"] is False
|
|
assert package["database_write_executed"] is False
|
|
assert package["external_network_executed"] is False
|
|
assert package["file_written"] is False
|
|
assert package["scheduler_attached"] is False
|
|
assert "target_review_payload_or_result_received" in package["blocked_reasons"]
|
|
assert "operator_run_controls_received" in package["blocked_reasons"]
|
|
assert "target_review_package" in package["sample_run_package"]
|
|
assert "operator_run_controls" in package["sample_run_package"]
|
|
|
|
|
|
def test_mcp_fetch_run_package_accepts_sample_package():
|
|
sample = build_mcp_fetch_run_package_preview()["sample_run_package"]
|
|
package = build_mcp_fetch_run_package_preview(
|
|
target_review_package=sample["target_review_package"],
|
|
operator_run_controls=sample["operator_run_controls"],
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert package["mode"] == "mcp_fetch_run_package_review"
|
|
assert package["mcp_fetch_run_package_accepted"] is True
|
|
assert package["ready_for_manual_fetch_run_readiness_review"] is True
|
|
assert package["ready_for_manual_fetch_operator_run"] is False
|
|
assert package["target_review_accepted"] is True
|
|
assert package["operator_acknowledgements_complete"] is True
|
|
assert package["blocked_reasons"] == []
|
|
assert package["passed_gate_count"] == package["gate_count"]
|
|
assert package["command_preview_count"] >= 8
|
|
assert all(
|
|
item["command_executed"] is False
|
|
and item["external_network_executed_by_api"] is False
|
|
and item["receipt_written_by_api"] is False
|
|
for item in package["command_previews"]
|
|
)
|
|
assert package["manual_fetch_gate_opened_by_api"] is False
|
|
assert package["network_request_allowed"] is False
|
|
assert package["fetch_executed"] is False
|
|
assert package["cli_executed"] is False
|
|
assert package["package_artifact_created"] is False
|
|
assert package["file_written"] is False
|
|
assert package["database_write_executed"] is False
|
|
assert package["api_uses_external_network"] is False
|
|
assert package["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_run_package_blocks_unsafe_controls():
|
|
sample = build_mcp_fetch_run_package_preview()["sample_run_package"]
|
|
controls = sample["operator_run_controls"]
|
|
controls["artifact_dir"] = "../unsafe"
|
|
controls["max_total_requests"] = 99
|
|
controls["allow_api_execution"] = True
|
|
controls["operator_acknowledgements"]["no_api_execution"] = False
|
|
|
|
package = build_mcp_fetch_run_package_preview(
|
|
target_review_package=sample["target_review_package"],
|
|
operator_run_controls=controls,
|
|
)
|
|
|
|
assert package["mcp_fetch_run_package_accepted"] is False
|
|
assert package["target_review_accepted"] is True
|
|
assert "artifact_dir_safe" in package["blocked_reasons"]
|
|
assert "request_budget_within_target_limit" in package["blocked_reasons"]
|
|
assert "no_api_fetch_execution" in package["blocked_reasons"]
|
|
assert "run_package_side_effect_free" in package["blocked_reasons"]
|
|
assert "ack_no_api_execution" in package["blocked_reasons"]
|
|
assert package["network_request_allowed"] is False
|
|
assert package["api_writes_database"] is False
|
|
assert package["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_run_package_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_fetch_run_package")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_run_package"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_fetch_run_package",
|
|
json={"run_package": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_fetch_run_package_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_cli"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert get_data["api_uses_external_network"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_fetch_run_package_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["mcp_fetch_run_package_accepted"] is True
|
|
assert post_data["ready_for_manual_fetch_operator_run"] is False
|
|
assert post_data["manual_fetch_gate_opened_by_api"] is False
|
|
assert post_data["network_request_allowed"] is False
|
|
assert post_data["fetch_executed"] is False
|
|
assert post_data["cli_executed"] is False
|
|
assert post_data["run_package_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_fetch_run_readiness_preview_is_safe_without_payload():
|
|
readiness = build_mcp_fetch_run_readiness_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert readiness["mode"] == "mcp_fetch_run_readiness_preview"
|
|
assert readiness["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert readiness["run_readiness_payload_received"] is False
|
|
assert readiness["mcp_fetch_run_readiness_accepted"] is False
|
|
assert readiness["run_readiness_ready"] is False
|
|
assert readiness["ready_for_manual_fetch_operator_run"] is False
|
|
assert readiness["ready_for_manual_fetch_run_receipt_gate"] is False
|
|
assert readiness["manual_fetch_gate_opened_by_api"] is False
|
|
assert readiness["network_request_allowed"] is False
|
|
assert readiness["fetch_executed"] is False
|
|
assert readiness["cli_executed"] is False
|
|
assert readiness["payload_persisted"] is False
|
|
assert readiness["run_readiness_persisted"] is False
|
|
assert readiness["run_readiness_artifact_created"] is False
|
|
assert readiness["run_readiness_file_written"] is False
|
|
assert readiness["receipt_file_written"] is False
|
|
assert readiness["api_executes_cli"] is False
|
|
assert readiness["api_opens_database_connection"] is False
|
|
assert readiness["api_writes_database"] is False
|
|
assert readiness["api_uses_external_network"] is False
|
|
assert readiness["database_write_executed"] is False
|
|
assert readiness["external_network_executed"] is False
|
|
assert readiness["file_written"] is False
|
|
assert readiness["scheduler_attached"] is False
|
|
assert "run_package_payload_or_result_received" in readiness["blocked_reasons"]
|
|
assert "operator_readiness_received" in readiness["blocked_reasons"]
|
|
assert "run_package" in readiness["sample_run_readiness_package"]
|
|
assert "operator_readiness" in readiness["sample_run_readiness_package"]
|
|
|
|
|
|
def test_mcp_fetch_run_readiness_accepts_sample_package():
|
|
sample = build_mcp_fetch_run_readiness_preview()["sample_run_readiness_package"]
|
|
readiness = build_mcp_fetch_run_readiness_preview(
|
|
run_package=sample["run_package"],
|
|
run_package_result=sample["run_package_result"],
|
|
operator_readiness=sample["operator_readiness"],
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert readiness["mode"] == "mcp_fetch_run_readiness_review"
|
|
assert readiness["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert readiness["mcp_fetch_run_readiness_accepted"] is True
|
|
assert readiness["run_readiness_ready"] is True
|
|
assert readiness["ready_for_manual_fetch_operator_run"] is True
|
|
assert readiness["ready_for_manual_fetch_run_receipt_gate"] is True
|
|
assert readiness["operator_shell_external_network_required"] is True
|
|
assert readiness["blocked_reasons"] == []
|
|
assert readiness["passed_gate_count"] == readiness["gate_count"]
|
|
assert readiness["run_package_summary"]["accepted"] is True
|
|
assert readiness["run_package_summary"]["command_count"] >= 8
|
|
assert readiness["operator_readiness_summary"]["run_readiness_artifact_path_safe"] is True
|
|
assert readiness["operator_readiness_summary"]["dry_run_receipt_path_safe"] is True
|
|
assert all(
|
|
item["ready_for_operator_shell"] is True
|
|
and item["command_executed"] is False
|
|
and item["external_network_executed_by_api"] is False
|
|
and item["receipt_written_by_api"] is False
|
|
for item in readiness["command_readiness"]
|
|
)
|
|
assert readiness["manual_fetch_gate_opened_by_api"] is False
|
|
assert readiness["network_request_allowed"] is False
|
|
assert readiness["fetch_executed"] is False
|
|
assert readiness["cli_executed"] is False
|
|
assert readiness["run_readiness_artifact_created"] is False
|
|
assert readiness["file_written"] is False
|
|
assert readiness["database_write_executed"] is False
|
|
assert readiness["api_uses_external_network"] is False
|
|
assert readiness["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_run_readiness_blocks_unsafe_operator_payload():
|
|
sample = build_mcp_fetch_run_readiness_preview()["sample_run_readiness_package"]
|
|
operator_readiness = sample["operator_readiness"]
|
|
operator_readiness["run_readiness_artifact_path"] = "../unsafe.json"
|
|
operator_readiness["api_executes_cli"] = True
|
|
operator_readiness["approval_token"] = "do-not-submit"
|
|
operator_readiness["operator_confirmed_no_api_execution"] = False
|
|
|
|
readiness = build_mcp_fetch_run_readiness_preview(
|
|
run_package=sample["run_package"],
|
|
run_package_result=sample["run_package_result"],
|
|
operator_readiness=operator_readiness,
|
|
)
|
|
|
|
assert readiness["mcp_fetch_run_readiness_accepted"] is False
|
|
assert readiness["run_package_accepted"] is True
|
|
assert "run_readiness_artifact_path_safe" in readiness["blocked_reasons"]
|
|
assert "operator_confirmed_shell_only_boundaries" in readiness["blocked_reasons"]
|
|
assert "secret_or_token_not_submitted_to_api" in readiness["blocked_reasons"]
|
|
assert "operator_readiness_side_effect_free" in readiness["blocked_reasons"]
|
|
assert readiness["network_request_allowed"] is False
|
|
assert readiness["api_writes_database"] is False
|
|
assert readiness["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_run_readiness_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_fetch_run_readiness")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_run_readiness_package"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_fetch_run_readiness",
|
|
json={"run_readiness": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_fetch_run_readiness_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_cli"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert get_data["api_uses_external_network"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_fetch_run_readiness_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["mcp_fetch_run_readiness_accepted"] is True
|
|
assert post_data["ready_for_manual_fetch_operator_run"] is True
|
|
assert post_data["manual_fetch_gate_opened_by_api"] is False
|
|
assert post_data["network_request_allowed"] is False
|
|
assert post_data["fetch_executed"] is False
|
|
assert post_data["cli_executed"] is False
|
|
assert post_data["run_readiness_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_fetch_run_receipt_preview_is_safe_without_payload():
|
|
receipt = build_mcp_fetch_run_receipt_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert receipt["mode"] == "mcp_fetch_run_receipt_preview"
|
|
assert receipt["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert receipt["run_receipt_payload_received"] is False
|
|
assert receipt["mcp_fetch_run_receipt_accepted"] is False
|
|
assert receipt["run_receipt_ready"] is False
|
|
assert receipt["ready_for_manual_fetch_result_parser_review"] is False
|
|
assert receipt["ready_for_api_database_write"] is False
|
|
assert receipt["ready_for_scheduler_attach"] is False
|
|
assert receipt["manual_fetch_gate_opened_by_api"] is False
|
|
assert receipt["network_request_allowed"] is False
|
|
assert receipt["fetch_executed"] is False
|
|
assert receipt["fetch_executed_by_api"] is False
|
|
assert receipt["cli_executed"] is False
|
|
assert receipt["payload_persisted"] is False
|
|
assert receipt["run_receipt_persisted"] is False
|
|
assert receipt["receipt_persisted"] is False
|
|
assert receipt["run_receipt_file_written"] is False
|
|
assert receipt["receipt_file_written"] is False
|
|
assert receipt["api_executes_cli"] is False
|
|
assert receipt["api_opens_database_connection"] is False
|
|
assert receipt["api_writes_database"] is False
|
|
assert receipt["api_uses_external_network"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["external_network_executed"] is False
|
|
assert receipt["file_written"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert "run_readiness_payload_or_result_received" in receipt["blocked_reasons"]
|
|
assert "manual_fetch_receipt_received" in receipt["blocked_reasons"]
|
|
assert "run_readiness_package" in receipt["sample_run_receipt_package"]
|
|
assert "manual_fetch_receipt" in receipt["sample_run_receipt_package"]
|
|
|
|
|
|
def test_mcp_fetch_run_receipt_accepts_sample_receipt():
|
|
sample = build_mcp_fetch_run_receipt_preview()["sample_run_receipt_package"]
|
|
receipt = build_mcp_fetch_run_receipt_preview(
|
|
run_readiness_package=sample["run_readiness_package"],
|
|
run_readiness_result=sample["run_readiness_result"],
|
|
manual_fetch_receipt=sample["manual_fetch_receipt"],
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert receipt["mode"] == "mcp_fetch_run_receipt_review"
|
|
assert receipt["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert receipt["mcp_fetch_run_receipt_accepted"] is True
|
|
assert receipt["run_receipt_ready"] is True
|
|
assert receipt["operator_shell_fetch_receipt_received"] is True
|
|
assert receipt["ready_for_manual_fetch_result_parser_review"] is True
|
|
assert receipt["ready_for_api_database_write"] is False
|
|
assert receipt["blocked_reasons"] == []
|
|
assert receipt["passed_gate_count"] == receipt["gate_count"]
|
|
assert receipt["run_readiness_accepted"] is True
|
|
assert receipt["expected_command_count"] >= 8
|
|
assert receipt["receipt_source_count"] == receipt["expected_command_count"]
|
|
assert receipt["manual_fetch_receipt_summary"]["all_urls_public"] is True
|
|
assert receipt["manual_fetch_receipt_summary"]["all_receipt_paths_safe"] is True
|
|
assert receipt["manual_fetch_receipt_summary"]["blocked_side_effects"] == []
|
|
assert receipt["manual_fetch_gate_opened_by_api"] is False
|
|
assert receipt["network_request_allowed"] is False
|
|
assert receipt["fetch_executed"] is False
|
|
assert receipt["fetch_executed_by_api"] is False
|
|
assert receipt["cli_executed"] is False
|
|
assert receipt["run_receipt_file_written"] is False
|
|
assert receipt["file_written"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["api_uses_external_network"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_run_receipt_blocks_unsafe_receipt_payload():
|
|
sample = json.loads(
|
|
json.dumps(build_mcp_fetch_run_receipt_preview()["sample_run_receipt_package"])
|
|
)
|
|
manual_fetch_receipt = sample["manual_fetch_receipt"]
|
|
manual_fetch_receipt["approval_token"] = "do-not-submit"
|
|
manual_fetch_receipt["api_writes_database"] = True
|
|
manual_fetch_receipt["summary"]["request_count"] = 99
|
|
manual_fetch_receipt["operator_confirmed_no_api_execution"] = False
|
|
first_source = manual_fetch_receipt["sources"][0]
|
|
first_source["source_url"] = "http://127.0.0.1/private"
|
|
first_source["receipt_path"] = "../unsafe.json"
|
|
|
|
receipt = build_mcp_fetch_run_receipt_preview(
|
|
run_readiness_package=sample["run_readiness_package"],
|
|
run_readiness_result=sample["run_readiness_result"],
|
|
manual_fetch_receipt=manual_fetch_receipt,
|
|
)
|
|
|
|
assert receipt["mcp_fetch_run_receipt_accepted"] is False
|
|
assert receipt["run_readiness_accepted"] is True
|
|
assert "receipt_paths_match_expected" in receipt["blocked_reasons"]
|
|
assert "receipt_request_budget_within_limit" in receipt["blocked_reasons"]
|
|
assert "receipt_urls_public_http" in receipt["blocked_reasons"]
|
|
assert "receipt_operator_boundaries_confirmed" in receipt["blocked_reasons"]
|
|
assert "receipt_no_secret_or_token_key" in receipt["blocked_reasons"]
|
|
assert "receipt_side_effect_free" in receipt["blocked_reasons"]
|
|
assert receipt["network_request_allowed"] is False
|
|
assert receipt["api_writes_database"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_run_receipt_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_fetch_run_receipt")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_run_receipt_package"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_fetch_run_receipt",
|
|
json={"run_receipt": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_fetch_run_receipt_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_cli"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert get_data["api_uses_external_network"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_fetch_run_receipt_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["mcp_fetch_run_receipt_accepted"] is True
|
|
assert post_data["ready_for_manual_fetch_result_parser_review"] is True
|
|
assert post_data["ready_for_api_database_write"] is False
|
|
assert post_data["manual_fetch_gate_opened_by_api"] is False
|
|
assert post_data["network_request_allowed"] is False
|
|
assert post_data["fetch_executed"] is False
|
|
assert post_data["fetch_executed_by_api"] is False
|
|
assert post_data["cli_executed"] is False
|
|
assert post_data["run_receipt_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_fetch_result_parser_review_preview_is_safe_without_payload():
|
|
parser = build_mcp_fetch_result_parser_review_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert parser["mode"] == "mcp_fetch_result_parser_review_preview"
|
|
assert parser["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert parser["parser_payload_received"] is False
|
|
assert parser["mcp_fetch_result_parser_review_accepted"] is False
|
|
assert parser["result_parser_review_ready"] is False
|
|
assert parser["ready_for_manual_fetch_candidate_handoff_review"] is False
|
|
assert parser["ready_for_api_database_write"] is False
|
|
assert parser["ready_for_scheduler_attach"] is False
|
|
assert parser["manual_fetch_gate_opened_by_api"] is False
|
|
assert parser["network_request_allowed"] is False
|
|
assert parser["parser_executed_by_api"] is False
|
|
assert parser["fetch_executed"] is False
|
|
assert parser["cli_executed"] is False
|
|
assert parser["payload_persisted"] is False
|
|
assert parser["result_parser_persisted"] is False
|
|
assert parser["result_parser_file_written"] is False
|
|
assert parser["candidate_handoff_persisted"] is False
|
|
assert parser["api_executes_cli"] is False
|
|
assert parser["api_opens_database_connection"] is False
|
|
assert parser["api_writes_database"] is False
|
|
assert parser["api_uses_external_network"] is False
|
|
assert parser["database_write_executed"] is False
|
|
assert parser["external_network_executed"] is False
|
|
assert parser["file_written"] is False
|
|
assert parser["scheduler_attached"] is False
|
|
assert "run_receipt_payload_or_result_received" in parser["blocked_reasons"]
|
|
assert "parser_result_received" in parser["blocked_reasons"]
|
|
assert "run_receipt_package" in parser["sample_parser_result_package"]
|
|
assert "parser_result" in parser["sample_parser_result_package"]
|
|
|
|
|
|
def test_mcp_fetch_result_parser_review_accepts_sample_result():
|
|
sample = (
|
|
build_mcp_fetch_result_parser_review_preview()
|
|
["sample_parser_result_package"]
|
|
)
|
|
parser = build_mcp_fetch_result_parser_review_preview(
|
|
run_receipt_package=sample["run_receipt_package"],
|
|
run_receipt_result=sample["run_receipt_result"],
|
|
parser_result=sample["parser_result"],
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert parser["mode"] == "mcp_fetch_result_parser_review"
|
|
assert parser["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert parser["mcp_fetch_result_parser_review_accepted"] is True
|
|
assert parser["result_parser_review_ready"] is True
|
|
assert parser["ready_for_manual_fetch_candidate_handoff_review"] is True
|
|
assert parser["ready_for_api_database_write"] is False
|
|
assert parser["blocked_reasons"] == []
|
|
assert parser["passed_gate_count"] == parser["gate_count"]
|
|
assert parser["run_receipt_accepted"] is True
|
|
assert parser["parser_source_count"] >= 8
|
|
assert parser["candidate_count"] == (
|
|
parser["campaign_candidate_count"] + parser["product_candidate_count"]
|
|
)
|
|
assert parser["parser_result_summary"]["all_candidate_urls_public"] is True
|
|
assert parser["parser_result_summary"]["all_candidate_required_fields_present"] is True
|
|
assert parser["parser_result_summary"]["raw_payload_submitted_to_api"] is False
|
|
assert parser["manual_fetch_gate_opened_by_api"] is False
|
|
assert parser["network_request_allowed"] is False
|
|
assert parser["parser_executed_by_api"] is False
|
|
assert parser["fetch_executed"] is False
|
|
assert parser["cli_executed"] is False
|
|
assert parser["result_parser_file_written"] is False
|
|
assert parser["file_written"] is False
|
|
assert parser["database_write_executed"] is False
|
|
assert parser["api_uses_external_network"] is False
|
|
assert parser["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_result_parser_review_blocks_unsafe_parser_payload():
|
|
sample = json.loads(
|
|
json.dumps(
|
|
build_mcp_fetch_result_parser_review_preview()
|
|
["sample_parser_result_package"]
|
|
)
|
|
)
|
|
parser_result = sample["parser_result"]
|
|
parser_result["approval_token"] = "do-not-submit"
|
|
parser_result["raw_html"] = "<html>raw</html>"
|
|
parser_result["api_writes_database"] = True
|
|
parser_result["operator_confirmed_no_api_execution"] = False
|
|
first_source = parser_result["parsed_sources"][0]
|
|
first_source["parser_artifact_path"] = "../unsafe.json"
|
|
first_source["campaign_candidates"][0]["campaign_url"] = "http://127.0.0.1/private"
|
|
first_source["product_candidates"][0].pop("platform_product_id")
|
|
|
|
parser = build_mcp_fetch_result_parser_review_preview(
|
|
run_receipt_package=sample["run_receipt_package"],
|
|
run_receipt_result=sample["run_receipt_result"],
|
|
parser_result=parser_result,
|
|
)
|
|
|
|
assert parser["mcp_fetch_result_parser_review_accepted"] is False
|
|
assert parser["run_receipt_accepted"] is True
|
|
assert "parser_artifact_paths_safe" in parser["blocked_reasons"]
|
|
assert "parser_candidate_required_fields_present" in parser["blocked_reasons"]
|
|
assert "parser_candidate_urls_public_http" in parser["blocked_reasons"]
|
|
assert "parser_operator_boundaries_confirmed" in parser["blocked_reasons"]
|
|
assert "parser_no_raw_payload" in parser["blocked_reasons"]
|
|
assert "parser_no_secret_or_token_key" in parser["blocked_reasons"]
|
|
assert "parser_side_effect_free" in parser["blocked_reasons"]
|
|
assert parser["network_request_allowed"] is False
|
|
assert parser["api_writes_database"] is False
|
|
assert parser["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_result_parser_review_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_fetch_result_parser_review")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_parser_result_package"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_fetch_result_parser_review",
|
|
json={"parser_review": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_fetch_result_parser_review_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_cli"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert get_data["api_uses_external_network"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_fetch_result_parser_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["mcp_fetch_result_parser_review_accepted"] is True
|
|
assert post_data["ready_for_manual_fetch_candidate_handoff_review"] is True
|
|
assert post_data["ready_for_api_database_write"] is False
|
|
assert post_data["manual_fetch_gate_opened_by_api"] is False
|
|
assert post_data["network_request_allowed"] is False
|
|
assert post_data["parser_executed_by_api"] is False
|
|
assert post_data["fetch_executed"] is False
|
|
assert post_data["cli_executed"] is False
|
|
assert post_data["result_parser_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_fetch_candidate_handoff_review_preview_is_safe_without_payload():
|
|
handoff = build_mcp_fetch_candidate_handoff_review_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert handoff["mode"] == "mcp_fetch_candidate_handoff_review_preview"
|
|
assert handoff["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert handoff["candidate_handoff_payload_received"] is False
|
|
assert handoff["mcp_fetch_candidate_handoff_review_accepted"] is False
|
|
assert handoff["candidate_handoff_review_ready"] is False
|
|
assert handoff["ready_for_manual_candidate_queue_review"] is False
|
|
assert handoff["ready_for_candidate_queue_writer_preflight"] is False
|
|
assert handoff["ready_for_api_database_write"] is False
|
|
assert handoff["ready_for_scheduler_attach"] is False
|
|
assert handoff["manual_fetch_gate_opened_by_api"] is False
|
|
assert handoff["network_request_allowed"] is False
|
|
assert handoff["fetch_executed"] is False
|
|
assert handoff["cli_executed"] is False
|
|
assert handoff["payload_persisted"] is False
|
|
assert handoff["candidate_handoff_persisted"] is False
|
|
assert handoff["candidate_queue_created"] is False
|
|
assert handoff["candidate_queue_persisted"] is False
|
|
assert handoff["api_executes_cli"] is False
|
|
assert handoff["api_opens_database_connection"] is False
|
|
assert handoff["api_writes_database"] is False
|
|
assert handoff["api_uses_external_network"] is False
|
|
assert handoff["database_write_executed"] is False
|
|
assert handoff["external_network_executed"] is False
|
|
assert handoff["file_written"] is False
|
|
assert handoff["scheduler_attached"] is False
|
|
assert "parser_review_payload_or_result_received" in handoff["blocked_reasons"]
|
|
assert "handoff_payload_received" in handoff["blocked_reasons"]
|
|
assert "parser_review_package" in handoff["sample_candidate_handoff_package"]
|
|
assert "candidate_handoff" in handoff["sample_candidate_handoff_package"]
|
|
|
|
|
|
def test_mcp_fetch_candidate_handoff_review_accepts_sample_handoff():
|
|
sample = (
|
|
build_mcp_fetch_candidate_handoff_review_preview()
|
|
["sample_candidate_handoff_package"]
|
|
)
|
|
handoff = build_mcp_fetch_candidate_handoff_review_preview(
|
|
parser_review_package=sample["parser_review_package"],
|
|
parser_review_result=sample["parser_review_result"],
|
|
candidate_handoff=sample["candidate_handoff"],
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert handoff["mode"] == "mcp_fetch_candidate_handoff_review"
|
|
assert handoff["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert handoff["mcp_fetch_candidate_handoff_review_accepted"] is True
|
|
assert handoff["candidate_handoff_review_ready"] is True
|
|
assert handoff["ready_for_manual_candidate_queue_review"] is True
|
|
assert handoff["ready_for_candidate_queue_writer_preflight"] is False
|
|
assert handoff["ready_for_api_database_write"] is False
|
|
assert handoff["blocked_reasons"] == []
|
|
assert handoff["passed_gate_count"] == handoff["gate_count"]
|
|
assert handoff["parser_review_accepted"] is True
|
|
assert handoff["handoff_source_count"] >= 8
|
|
assert handoff["candidate_count"] == (
|
|
handoff["campaign_candidate_count"] + handoff["product_candidate_count"]
|
|
)
|
|
assert handoff["candidate_handoff_summary"]["all_group_paths_safe"] is True
|
|
assert handoff["candidate_handoff_summary"]["all_handoff_statuses_safe"] is True
|
|
assert handoff["candidate_handoff_summary"]["group_counts_match_candidates"] is True
|
|
assert handoff["candidate_handoff_summary"]["raw_payload_submitted_to_api"] is False
|
|
assert handoff["candidate_handoff_summary"]["secret_or_token_submitted_to_api"] is False
|
|
assert handoff["manual_fetch_gate_opened_by_api"] is False
|
|
assert handoff["network_request_allowed"] is False
|
|
assert handoff["fetch_executed"] is False
|
|
assert handoff["cli_executed"] is False
|
|
assert handoff["candidate_queue_created"] is False
|
|
assert handoff["candidate_queue_persisted"] is False
|
|
assert handoff["file_written"] is False
|
|
assert handoff["database_write_executed"] is False
|
|
assert handoff["api_uses_external_network"] is False
|
|
assert handoff["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_candidate_handoff_review_blocks_unsafe_handoff():
|
|
sample = json.loads(
|
|
json.dumps(
|
|
build_mcp_fetch_candidate_handoff_review_preview()
|
|
["sample_candidate_handoff_package"]
|
|
)
|
|
)
|
|
candidate_handoff = sample["candidate_handoff"]
|
|
candidate_handoff["approval_token"] = "do-not-submit"
|
|
candidate_handoff["raw_html"] = "<html>raw</html>"
|
|
candidate_handoff["api_writes_database"] = True
|
|
candidate_handoff["operator_confirmed_no_database_write"] = False
|
|
candidate_handoff["queue_policy"]["write_mode"] = "write_database"
|
|
first_group = candidate_handoff["candidate_groups"][0]
|
|
first_group["parser_artifact_path"] = "../unsafe.json"
|
|
first_group["handoff_status"] = "persisted"
|
|
first_group["product_candidate_keys"].pop()
|
|
|
|
handoff = build_mcp_fetch_candidate_handoff_review_preview(
|
|
parser_review_package=sample["parser_review_package"],
|
|
parser_review_result=sample["parser_review_result"],
|
|
candidate_handoff=candidate_handoff,
|
|
)
|
|
|
|
assert handoff["mcp_fetch_candidate_handoff_review_accepted"] is False
|
|
assert handoff["parser_review_accepted"] is True
|
|
assert "handoff_group_paths_safe" in handoff["blocked_reasons"]
|
|
assert "handoff_status_operator_review_only" in handoff["blocked_reasons"]
|
|
assert "handoff_candidate_counts_match_summary" in handoff["blocked_reasons"]
|
|
assert "handoff_queue_policy_safe" in handoff["blocked_reasons"]
|
|
assert "handoff_operator_boundaries_confirmed" in handoff["blocked_reasons"]
|
|
assert "handoff_no_raw_payload" in handoff["blocked_reasons"]
|
|
assert "handoff_no_secret_or_token_key" in handoff["blocked_reasons"]
|
|
assert "handoff_side_effect_free" in handoff["blocked_reasons"]
|
|
assert handoff["network_request_allowed"] is False
|
|
assert handoff["api_writes_database"] is False
|
|
assert handoff["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_candidate_handoff_review_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_fetch_candidate_handoff_review")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_candidate_handoff_package"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_fetch_candidate_handoff_review",
|
|
json={"candidate_handoff_review": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_fetch_candidate_handoff_review_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_cli"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert get_data["api_uses_external_network"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_fetch_candidate_handoff_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["mcp_fetch_candidate_handoff_review_accepted"] is True
|
|
assert post_data["ready_for_manual_candidate_queue_review"] is True
|
|
assert post_data["ready_for_candidate_queue_writer_preflight"] is False
|
|
assert post_data["manual_fetch_gate_opened_by_api"] is False
|
|
assert post_data["network_request_allowed"] is False
|
|
assert post_data["fetch_executed"] is False
|
|
assert post_data["cli_executed"] is False
|
|
assert post_data["candidate_handoff_persisted"] is False
|
|
assert post_data["candidate_queue_created"] is False
|
|
assert post_data["candidate_queue_persisted"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_mcp_fetch_candidate_queue_review_preview_is_safe_without_payload():
|
|
review = build_mcp_fetch_candidate_queue_review_preview(
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert review["mode"] == "mcp_fetch_candidate_queue_review_preview"
|
|
assert review["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert review["candidate_queue_review_payload_received"] is False
|
|
assert review["mcp_fetch_candidate_queue_review_accepted"] is False
|
|
assert review["candidate_queue_review_ready"] is False
|
|
assert review["ready_for_candidate_queue_writer_preflight"] is False
|
|
assert review["ready_for_api_database_write"] is False
|
|
assert review["ready_for_scheduler_attach"] is False
|
|
assert review["network_request_allowed"] is False
|
|
assert review["fetch_executed"] is False
|
|
assert review["cli_executed"] is False
|
|
assert review["payload_persisted"] is False
|
|
assert review["candidate_queue_created"] is False
|
|
assert review["candidate_queue_persisted"] is False
|
|
assert review["candidate_review_state_updated"] is False
|
|
assert review["api_executes_cli"] is False
|
|
assert review["api_opens_database_connection"] is False
|
|
assert review["api_writes_database"] is False
|
|
assert review["api_uses_external_network"] is False
|
|
assert review["database_write_executed"] is False
|
|
assert review["external_network_executed"] is False
|
|
assert review["file_written"] is False
|
|
assert review["scheduler_attached"] is False
|
|
assert "handoff_review_payload_or_result_received" in review["blocked_reasons"]
|
|
assert "queue_review_payload_received" in review["blocked_reasons"]
|
|
assert "handoff_review_package" in review["sample_candidate_queue_review_package"]
|
|
assert "candidate_queue_review" in review["sample_candidate_queue_review_package"]
|
|
|
|
|
|
def test_mcp_fetch_candidate_queue_review_accepts_sample_review():
|
|
sample = (
|
|
build_mcp_fetch_candidate_queue_review_preview()
|
|
["sample_candidate_queue_review_package"]
|
|
)
|
|
review = build_mcp_fetch_candidate_queue_review_preview(
|
|
handoff_review_package=sample["handoff_review_package"],
|
|
handoff_review_result=sample["handoff_review_result"],
|
|
candidate_queue_review=sample["candidate_queue_review"],
|
|
phase="phase_127_market_intel_mcp_fetch_candidate_queue_review",
|
|
)
|
|
|
|
assert review["mode"] == "mcp_fetch_candidate_queue_review"
|
|
assert review["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert review["mcp_fetch_candidate_queue_review_accepted"] is True
|
|
assert review["candidate_queue_review_ready"] is True
|
|
assert review["ready_for_candidate_queue_writer_preflight"] is True
|
|
assert review["ready_for_api_database_write"] is False
|
|
assert review["blocked_reasons"] == []
|
|
assert review["passed_gate_count"] == review["gate_count"]
|
|
assert review["handoff_review_accepted"] is True
|
|
assert review["review_item_count"] == (
|
|
review["campaign_candidate_count"] + review["product_candidate_count"]
|
|
)
|
|
summary = review["candidate_queue_review_summary"]
|
|
assert summary["all_review_states_safe"] is True
|
|
assert summary["all_required_fields_present"] is True
|
|
assert summary["all_allowed_actions_safe"] is True
|
|
assert summary["all_queue_write_status_preview"] is True
|
|
assert summary["raw_payload_submitted_to_api"] is False
|
|
assert summary["secret_or_token_submitted_to_api"] is False
|
|
assert review["network_request_allowed"] is False
|
|
assert review["fetch_executed"] is False
|
|
assert review["cli_executed"] is False
|
|
assert review["candidate_queue_created"] is False
|
|
assert review["candidate_queue_persisted"] is False
|
|
assert review["candidate_review_state_updated"] is False
|
|
assert review["file_written"] is False
|
|
assert review["database_write_executed"] is False
|
|
assert review["api_uses_external_network"] is False
|
|
assert review["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_candidate_queue_review_blocks_unsafe_review():
|
|
sample = json.loads(
|
|
json.dumps(
|
|
build_mcp_fetch_candidate_queue_review_preview()
|
|
["sample_candidate_queue_review_package"]
|
|
)
|
|
)
|
|
queue_review = sample["candidate_queue_review"]
|
|
queue_review["approval_token"] = "do-not-submit"
|
|
queue_review["raw_html"] = "<html>raw</html>"
|
|
queue_review["api_writes_database"] = True
|
|
queue_review["operator_confirmed_no_database_write"] = False
|
|
first_item = queue_review["review_items"][0]
|
|
first_item["review_state"] = "approved"
|
|
first_item["queue_write_status"] = "persisted"
|
|
first_item["allowed_actions"] = ["auto_write"]
|
|
first_item.pop("candidate_key")
|
|
|
|
review = build_mcp_fetch_candidate_queue_review_preview(
|
|
handoff_review_package=sample["handoff_review_package"],
|
|
handoff_review_result=sample["handoff_review_result"],
|
|
candidate_queue_review=queue_review,
|
|
)
|
|
|
|
assert review["mcp_fetch_candidate_queue_review_accepted"] is False
|
|
assert review["handoff_review_accepted"] is True
|
|
assert "queue_review_candidates_match_handoff" in review["blocked_reasons"]
|
|
assert "queue_review_required_fields_present" in review["blocked_reasons"]
|
|
assert "queue_review_state_needs_review_only" in review["blocked_reasons"]
|
|
assert "queue_review_allowed_actions_safe" in review["blocked_reasons"]
|
|
assert "queue_review_not_persisted" in review["blocked_reasons"]
|
|
assert "queue_review_operator_boundaries_confirmed" in review["blocked_reasons"]
|
|
assert "queue_review_no_raw_payload" in review["blocked_reasons"]
|
|
assert "queue_review_no_secret_or_token_key" in review["blocked_reasons"]
|
|
assert "queue_review_side_effect_free" in review["blocked_reasons"]
|
|
assert review["api_writes_database"] is False
|
|
assert review["candidate_queue_persisted"] is False
|
|
assert review["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_fetch_candidate_queue_review_route_get_and_post_are_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get("/api/market_intel/mcp_fetch_candidate_queue_review")
|
|
get_data = get_response.get_json()
|
|
sample = get_data["sample_candidate_queue_review_package"]
|
|
post_response = client.post(
|
|
"/api/market_intel/mcp_fetch_candidate_queue_review",
|
|
json={"candidate_queue_review": sample},
|
|
)
|
|
post_data = post_response.get_json()
|
|
|
|
assert get_response.status_code == 200
|
|
assert get_data["mode"] == "mcp_fetch_candidate_queue_review_preview"
|
|
assert get_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert get_data["api_executes_cli"] is False
|
|
assert get_data["api_writes_database"] is False
|
|
assert get_data["api_uses_external_network"] is False
|
|
assert post_response.status_code == 200
|
|
assert post_data["mode"] == "mcp_fetch_candidate_queue_review"
|
|
assert post_data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert post_data["mcp_fetch_candidate_queue_review_accepted"] is True
|
|
assert post_data["ready_for_candidate_queue_writer_preflight"] is True
|
|
assert post_data["ready_for_api_database_write"] is False
|
|
assert post_data["network_request_allowed"] is False
|
|
assert post_data["fetch_executed"] is False
|
|
assert post_data["cli_executed"] is False
|
|
assert post_data["candidate_queue_created"] is False
|
|
assert post_data["candidate_queue_persisted"] is False
|
|
assert post_data["candidate_review_state_updated"] is False
|
|
assert post_data["api_opens_database_connection"] is False
|
|
assert post_data["api_uses_external_network"] is False
|
|
|
|
|
|
def test_manual_sample_plan_preview_blocks_fetch_and_write():
|
|
plan = MarketIntelService().build_manual_sample_plan()
|
|
|
|
assert plan["mode"] == "manual_sample_fetch_plan_preview"
|
|
assert plan["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert plan["ready_for_manual_sample_fetch"] is False
|
|
assert plan["sample_fetch_executed"] is False
|
|
assert plan["external_network_executed"] is False
|
|
assert plan["database_session_created"] is False
|
|
assert plan["database_write_executed"] is False
|
|
assert plan["database_commit_executed"] is False
|
|
assert plan["scheduler_attached"] is False
|
|
assert plan["writes_executed"] is False
|
|
assert plan["would_write_database"] is False
|
|
assert plan["platform_count"] == 4
|
|
assert plan["sample_source_total"] == 4
|
|
assert plan["sample_policy"]["max_platforms_per_manual_batch"] == 1
|
|
assert plan["sample_policy"]["first_batch_platform"] == "pchome"
|
|
assert [item["platform_code"] for item in plan["sample_platforms"]] == [
|
|
"pchome",
|
|
"momo",
|
|
"coupang",
|
|
"shopee",
|
|
]
|
|
assert all(
|
|
item["sample_source_count"] == 1
|
|
and item["network_status"] == "not_executed"
|
|
and item["write_status"] == "blocked_preview_only"
|
|
for item in plan["sample_platforms"]
|
|
)
|
|
assert "market_intel_enabled" in plan["blocked_reasons"]
|
|
assert "mcp_fetch_gate_open" in plan["blocked_reasons"]
|
|
assert "sample_fetch_not_executed_by_api" in plan["blocked_reasons"]
|
|
assert "do_not_fetch_from_api_preview" in plan["safe_boundaries"]
|
|
assert "do_not_bypass_anti_bot" in plan["safe_boundaries"]
|
|
|
|
|
|
def test_manual_sample_plan_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/manual_sample_plan")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "manual_sample_fetch_plan_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["sample_fetch_executed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
|
|
|
|
def test_manual_sample_acceptance_preview_blocks_candidate_import():
|
|
acceptance = MarketIntelService().build_manual_sample_acceptance()
|
|
|
|
assert acceptance["mode"] == "manual_sample_acceptance_preview"
|
|
assert acceptance["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert acceptance["contract_ready"] is True
|
|
assert acceptance["sample_result_loaded"] is False
|
|
assert acceptance["sample_result_accepted"] is False
|
|
assert acceptance["candidate_import_allowed"] is False
|
|
assert acceptance["external_network_executed"] is False
|
|
assert acceptance["database_connection_opened"] is False
|
|
assert acceptance["database_session_created"] is False
|
|
assert acceptance["database_write_executed"] is False
|
|
assert acceptance["database_commit_executed"] is False
|
|
assert acceptance["scheduler_attached"] is False
|
|
assert acceptance["writes_executed"] is False
|
|
assert acceptance["would_write_database"] is False
|
|
assert "sample_result_not_loaded" in acceptance["blocked_reasons"]
|
|
assert "manual_review_required_before_import" in acceptance["blocked_reasons"]
|
|
assert "status_code" in acceptance["required_result_fields"]
|
|
assert "campaign_link_candidates" in acceptance["required_diagnostic_fields"]
|
|
assert acceptance["acceptance_thresholds"]["minimum_campaign_candidates"] == 1
|
|
assert acceptance["acceptance_thresholds"]["accepted_candidate_bands"] == ["high", "medium"]
|
|
assert {item["key"] for item in acceptance["reject_conditions"]} >= {
|
|
"anti_bot_or_login_wall",
|
|
"no_campaign_candidates",
|
|
}
|
|
assert "do_not_import_candidates_without_human_review" in acceptance["safe_boundaries"]
|
|
assert "do_not_write_market_tables_from_acceptance_preview" in acceptance["safe_boundaries"]
|
|
|
|
|
|
def test_manual_sample_acceptance_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/manual_sample_acceptance")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "manual_sample_acceptance_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["sample_result_loaded"] is False
|
|
assert data["candidate_import_allowed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
|
|
|
|
def test_manual_sample_review_preview_is_planned_until_result_loaded():
|
|
review = MarketIntelService().build_manual_sample_review()
|
|
|
|
assert review["mode"] == "manual_sample_review_preview"
|
|
assert review["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert review["contract_ready"] is True
|
|
assert review["sample_result_loaded"] is False
|
|
assert review["sample_result_reviewed"] is False
|
|
assert review["sample_result_accepted"] is False
|
|
assert review["ready_for_candidate_preview"] is False
|
|
assert review["candidate_import_allowed"] is False
|
|
assert review["external_network_executed"] is False
|
|
assert review["database_connection_opened"] is False
|
|
assert review["database_session_created"] is False
|
|
assert review["database_write_executed"] is False
|
|
assert review["database_commit_executed"] is False
|
|
assert review["scheduler_attached"] is False
|
|
assert review["writes_executed"] is False
|
|
assert review["would_write_database"] is False
|
|
assert review["review_result"] == "planned_no_sample_result"
|
|
assert "sample_result_not_loaded" in review["blocked_reasons"]
|
|
assert "candidate_import_still_blocked_until_operator_approval" in review["blocked_reasons"]
|
|
assert "do_not_fetch_external_pages_from_review_api" in review["safe_boundaries"]
|
|
assert "do_not_write_market_tables_from_review_preview" in review["safe_boundaries"]
|
|
|
|
|
|
def test_manual_sample_review_evaluator_accepts_good_result_without_import():
|
|
acceptance = MarketIntelService().build_manual_sample_acceptance()
|
|
sample_result = {
|
|
"batch_id": "sample-batch-1",
|
|
"platform_code": "pchome",
|
|
"source_key": "homepage",
|
|
"source_url": "https://24h.pchome.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1200,
|
|
"page_hash": "a" * 64,
|
|
"title": "PChome 活動",
|
|
"diagnostics": {
|
|
"link_count": 3,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 82,
|
|
"url": "https://24h.pchome.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
|
|
result = evaluate_manual_sample_result(sample_result, acceptance)
|
|
|
|
assert result["sample_result_loaded"] is True
|
|
assert result["sample_result_reviewed"] is True
|
|
assert result["sample_result_accepted"] is True
|
|
assert result["ready_for_candidate_preview"] is True
|
|
assert result["candidate_import_allowed"] is False
|
|
assert result["review_result"] == "accepted_for_candidate_preview"
|
|
assert all(check["passed"] for check in result["review_checks"])
|
|
assert result["review_findings"] == []
|
|
assert result["candidate_summary"]["candidate_count"] == 1
|
|
assert result["candidate_summary"]["accepted_candidate_count"] == 1
|
|
|
|
|
|
def test_manual_sample_review_evaluator_rejects_bad_result():
|
|
acceptance = MarketIntelService().build_manual_sample_acceptance()
|
|
sample_result = {
|
|
"batch_id": "sample-batch-2",
|
|
"platform_code": "shopee",
|
|
"source_key": "mall",
|
|
"source_url": "https://shopee.tw/mall",
|
|
"status": "blocked",
|
|
"status_code": 403,
|
|
"content_length": 120,
|
|
"page_hash": "short",
|
|
"title": "",
|
|
"diagnostics": {
|
|
"link_count": 0,
|
|
"same_host_link_count": 0,
|
|
"campaign_link_candidates": [],
|
|
},
|
|
}
|
|
|
|
result = evaluate_manual_sample_result(sample_result, acceptance)
|
|
|
|
assert result["sample_result_loaded"] is True
|
|
assert result["sample_result_reviewed"] is True
|
|
assert result["sample_result_accepted"] is False
|
|
assert result["ready_for_candidate_preview"] is False
|
|
assert result["candidate_import_allowed"] is False
|
|
assert result["review_result"] == "rejected_sample_result"
|
|
assert {item["key"] for item in result["review_findings"]} >= {
|
|
"http_status_ok",
|
|
"content_has_body",
|
|
"candidate_quality_reviewed",
|
|
}
|
|
|
|
|
|
def test_manual_sample_review_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/manual_sample_review")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "manual_sample_review_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["sample_result_loaded"] is False
|
|
assert data["sample_result_reviewed"] is False
|
|
assert data["candidate_import_allowed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
|
|
|
|
def test_manual_sample_review_evaluation_preview_accepts_payload_without_persisting():
|
|
sample_result = {
|
|
"batch_id": "sample-batch-3",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1800,
|
|
"page_hash": "b" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 4,
|
|
"same_host_link_count": 4,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "medium",
|
|
"score": 74,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "活動頁",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
|
|
review = MarketIntelService().build_manual_sample_review_evaluation(
|
|
sample_result=sample_result
|
|
)
|
|
|
|
assert review["mode"] == "manual_sample_review_evaluation_preview"
|
|
assert review["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert review["review_request_type"] == "operator_posted_json"
|
|
assert review["payload_received"] is True
|
|
assert review["payload_valid_json_object"] is True
|
|
assert review["payload_persisted"] is False
|
|
assert review["sample_result_persisted"] is False
|
|
assert review["sample_result_loaded"] is True
|
|
assert review["sample_result_reviewed"] is True
|
|
assert review["sample_result_accepted"] is True
|
|
assert review["ready_for_candidate_preview"] is True
|
|
assert review["candidate_preview_payload_created"] is True
|
|
assert review["candidate_preview_persisted"] is False
|
|
assert review["candidate_import_allowed"] is False
|
|
assert review["external_network_executed"] is False
|
|
assert review["database_write_executed"] is False
|
|
assert review["database_commit_executed"] is False
|
|
assert review["scheduler_attached"] is False
|
|
assert "do_not_persist_posted_review_payload" in review["safe_boundaries"]
|
|
|
|
|
|
def test_manual_sample_review_evaluate_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/evaluate",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-4",
|
|
"platform_code": "pchome",
|
|
"source_key": "homepage",
|
|
"source_url": "https://24h.pchome.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1400,
|
|
"page_hash": "c" * 64,
|
|
"title": "PChome 活動",
|
|
"diagnostics": {
|
|
"link_count": 2,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 88,
|
|
"url": "https://24h.pchome.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "manual_sample_review_evaluation_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["payload_received"] is True
|
|
assert data["payload_valid_json_object"] is True
|
|
assert data["payload_persisted"] is False
|
|
assert data["sample_result_persisted"] is False
|
|
assert data["sample_result_accepted"] is True
|
|
assert data["ready_for_candidate_preview"] is True
|
|
assert data["candidate_import_allowed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
|
|
|
|
def test_manual_sample_review_evaluate_rejects_invalid_json_without_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/evaluate",
|
|
data="not-json",
|
|
content_type="text/plain",
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 400
|
|
assert data["mode"] == "manual_sample_review_evaluation_preview"
|
|
assert data["payload_received"] is False
|
|
assert data["payload_valid_json_object"] is False
|
|
assert data["payload_error"] == "invalid_json_object"
|
|
assert data["payload_persisted"] is False
|
|
assert data["sample_result_persisted"] is False
|
|
assert data["candidate_import_allowed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert "sample_result_payload_invalid" in data["blocked_reasons"]
|
|
|
|
|
|
def test_manual_sample_candidate_handoff_preview_creates_candidates_without_persisting():
|
|
sample_result = {
|
|
"batch_id": "sample-batch-5",
|
|
"platform_code": "pchome",
|
|
"source_key": "homepage",
|
|
"source_url": "https://24h.pchome.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1500,
|
|
"page_hash": "e" * 64,
|
|
"title": "PChome 活動",
|
|
"diagnostics": {
|
|
"link_count": 3,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 91,
|
|
"url": "https://24h.pchome.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
{
|
|
"confidence_band": "low",
|
|
"score": 22,
|
|
"url": "https://24h.pchome.com.tw/search/noise",
|
|
"text": "低信心連結",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
|
|
handoff = MarketIntelService().build_manual_sample_candidate_handoff(
|
|
sample_result=sample_result
|
|
)
|
|
|
|
assert handoff["mode"] == "manual_sample_candidate_handoff_preview"
|
|
assert handoff["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert handoff["payload_received"] is True
|
|
assert handoff["payload_valid_json_object"] is True
|
|
assert handoff["payload_persisted"] is False
|
|
assert handoff["sample_result_persisted"] is False
|
|
assert handoff["handoff_ready"] is True
|
|
assert handoff["candidate_handoff_created"] is True
|
|
assert handoff["candidate_handoff_persisted"] is False
|
|
assert handoff["candidate_import_allowed"] is False
|
|
assert handoff["external_network_executed"] is False
|
|
assert handoff["database_connection_opened"] is False
|
|
assert handoff["database_session_created"] is False
|
|
assert handoff["database_write_executed"] is False
|
|
assert handoff["database_commit_executed"] is False
|
|
assert handoff["scheduler_attached"] is False
|
|
assert handoff["handoff_summary"]["candidate_count"] == 1
|
|
assert handoff["candidates"][0]["review_status"] == "needs_operator_review"
|
|
assert handoff["candidates"][0]["write_status"] == "blocked_preview_only"
|
|
assert handoff["candidates"][0]["import_allowed"] is False
|
|
assert "do_not_persist_candidate_handoff_payload" in handoff["safe_boundaries"]
|
|
|
|
|
|
def test_manual_sample_candidate_handoff_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/candidate_handoff",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-6",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1600,
|
|
"page_hash": "f" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 2,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "medium",
|
|
"score": 76,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "活動頁",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "manual_sample_candidate_handoff_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["payload_received"] is True
|
|
assert data["handoff_ready"] is True
|
|
assert data["candidate_handoff_created"] is True
|
|
assert data["candidate_handoff_persisted"] is False
|
|
assert data["candidate_import_allowed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["handoff_summary"]["candidate_count"] == 1
|
|
|
|
|
|
def test_manual_sample_candidate_handoff_blocks_invalid_payload():
|
|
handoff = MarketIntelService().build_manual_sample_candidate_handoff(
|
|
sample_result=None,
|
|
payload_error="invalid_json_object",
|
|
)
|
|
|
|
assert handoff["mode"] == "manual_sample_candidate_handoff_preview"
|
|
assert handoff["payload_received"] is False
|
|
assert handoff["payload_valid_json_object"] is False
|
|
assert handoff["handoff_ready"] is False
|
|
assert handoff["candidate_handoff_created"] is False
|
|
assert handoff["candidate_handoff_persisted"] is False
|
|
assert handoff["candidate_import_allowed"] is False
|
|
assert handoff["database_write_executed"] is False
|
|
assert "candidate_handoff_not_ready" in handoff["blocked_reasons"]
|
|
|
|
|
|
def test_manual_sample_candidate_queue_draft_preview_builds_review_items_without_persisting():
|
|
sample_result = {
|
|
"batch_id": "sample-batch-7",
|
|
"platform_code": "coupang",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.tw.coupang.com/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1800,
|
|
"page_hash": "a" * 64,
|
|
"title": "酷澎活動",
|
|
"diagnostics": {
|
|
"link_count": 3,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 95,
|
|
"url": "https://www.tw.coupang.com/promotion/sample",
|
|
"text": "限時活動",
|
|
}
|
|
],
|
|
},
|
|
}
|
|
|
|
queue_draft = MarketIntelService().build_manual_sample_candidate_queue_draft(
|
|
sample_result=sample_result
|
|
)
|
|
|
|
assert queue_draft["mode"] == "manual_sample_candidate_queue_draft_preview"
|
|
assert queue_draft["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert queue_draft["payload_received"] is True
|
|
assert queue_draft["payload_valid_json_object"] is True
|
|
assert queue_draft["payload_persisted"] is False
|
|
assert queue_draft["sample_result_persisted"] is False
|
|
assert queue_draft["handoff_ready"] is True
|
|
assert queue_draft["queue_draft_ready"] is True
|
|
assert queue_draft["review_queue_draft_created"] is True
|
|
assert queue_draft["review_queue_created"] is False
|
|
assert queue_draft["review_queue_persisted"] is False
|
|
assert queue_draft["candidate_import_allowed"] is False
|
|
assert queue_draft["external_network_executed"] is False
|
|
assert queue_draft["database_connection_opened"] is False
|
|
assert queue_draft["database_session_created"] is False
|
|
assert queue_draft["database_write_executed"] is False
|
|
assert queue_draft["database_commit_executed"] is False
|
|
assert queue_draft["scheduler_attached"] is False
|
|
assert queue_draft["queue_summary"]["queue_item_count"] == 1
|
|
assert queue_draft["queue_contract"]["table_name"] == "market_alert_review_queue"
|
|
assert queue_draft["queue_items"][0]["review_state"] == "needs_review"
|
|
assert queue_draft["queue_items"][0]["priority_lane"] == "urgent"
|
|
assert queue_draft["queue_items"][0]["threshold_level"] == "high"
|
|
assert queue_draft["queue_items"][0]["source_batch_id"] == "sample-batch-7"
|
|
assert queue_draft["queue_items"][0]["review_priority"] == 80
|
|
assert queue_draft["queue_items"][0]["write_status"] == "blocked_preview_only"
|
|
assert queue_draft["queue_items"][0]["approval_required"] is True
|
|
assert (
|
|
"do_not_persist_candidate_review_queue_draft"
|
|
in queue_draft["safe_boundaries"]
|
|
)
|
|
|
|
|
|
def test_manual_sample_candidate_queue_draft_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/candidate_queue_draft",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-8",
|
|
"platform_code": "shopee",
|
|
"source_key": "homepage",
|
|
"source_url": "https://shopee.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1900,
|
|
"page_hash": "b" * 64,
|
|
"title": "蝦皮活動",
|
|
"diagnostics": {
|
|
"link_count": 2,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "medium",
|
|
"score": 72,
|
|
"url": "https://shopee.tw/m/sample-campaign",
|
|
"text": "商城活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "manual_sample_candidate_queue_draft_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["payload_received"] is True
|
|
assert data["handoff_ready"] is True
|
|
assert data["queue_draft_ready"] is True
|
|
assert data["review_queue_draft_created"] is True
|
|
assert data["review_queue_created"] is False
|
|
assert data["review_queue_persisted"] is False
|
|
assert data["candidate_import_allowed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["queue_summary"]["queue_item_count"] == 1
|
|
|
|
|
|
def test_manual_sample_candidate_queue_draft_blocks_invalid_payload():
|
|
queue_draft = MarketIntelService().build_manual_sample_candidate_queue_draft(
|
|
sample_result=None,
|
|
payload_error="invalid_json_object",
|
|
)
|
|
|
|
assert queue_draft["mode"] == "manual_sample_candidate_queue_draft_preview"
|
|
assert queue_draft["payload_received"] is False
|
|
assert queue_draft["payload_valid_json_object"] is False
|
|
assert queue_draft["handoff_ready"] is False
|
|
assert queue_draft["queue_draft_ready"] is False
|
|
assert queue_draft["review_queue_draft_created"] is False
|
|
assert queue_draft["review_queue_created"] is False
|
|
assert queue_draft["review_queue_persisted"] is False
|
|
assert queue_draft["candidate_import_allowed"] is False
|
|
assert queue_draft["database_write_executed"] is False
|
|
assert "review_queue_draft_not_ready" in queue_draft["blocked_reasons"]
|
|
|
|
|
|
def test_manual_sample_candidate_queue_approval_preview_blocks_write_and_maps_rows():
|
|
sample_result = {
|
|
"batch_id": "sample-batch-9",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "c" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 2,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 92,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
|
|
approval = MarketIntelService().build_manual_sample_candidate_queue_approval(
|
|
sample_result=sample_result
|
|
)
|
|
|
|
assert approval["mode"] == "manual_sample_candidate_queue_approval_preview"
|
|
assert approval["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert approval["payload_received"] is True
|
|
assert approval["payload_valid_json_object"] is True
|
|
assert approval["payload_persisted"] is False
|
|
assert approval["approval_preview_created"] is True
|
|
assert approval["approval_request_created"] is False
|
|
assert approval["approval_record_written"] is False
|
|
assert approval["review_queue_write_allowed"] is False
|
|
assert approval["review_queue_created"] is False
|
|
assert approval["review_queue_persisted"] is False
|
|
assert approval["candidate_import_allowed"] is False
|
|
assert approval["external_network_executed"] is False
|
|
assert approval["database_connection_opened"] is False
|
|
assert approval["database_session_created"] is False
|
|
assert approval["database_write_executed"] is False
|
|
assert approval["database_commit_executed"] is False
|
|
assert approval["scheduler_attached"] is False
|
|
assert approval["approval_summary"]["target_table"] == "market_alert_review_queue"
|
|
assert approval["approval_summary"]["row_preview_count"] == 1
|
|
assert approval["approval_summary"]["gates_passed"] == 3
|
|
assert approval["approval_summary"]["manual_approval_required"] is True
|
|
row = approval["queue_write_preview"]["rows"][0]
|
|
assert row["review_state"] == "needs_review"
|
|
assert row["priority_lane"] == "urgent"
|
|
assert row["threshold_level"] == "high"
|
|
assert row["source_batch_id"] == "sample-batch-9"
|
|
assert row["write_status"] == "blocked_approval_preview_only"
|
|
assert "runtime_write_flags_enabled" in approval["blocked_reasons"]
|
|
assert "manual_operator_approval" in approval["blocked_reasons"]
|
|
assert "review_queue_write_still_blocked" in approval["blocked_reasons"]
|
|
assert (
|
|
"do_not_insert_market_alert_review_queue_from_preview"
|
|
in approval["safe_boundaries"]
|
|
)
|
|
|
|
|
|
def test_manual_sample_candidate_queue_approval_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/candidate_queue_approval",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-10",
|
|
"platform_code": "pchome",
|
|
"source_key": "homepage",
|
|
"source_url": "https://24h.pchome.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1800,
|
|
"page_hash": "d" * 64,
|
|
"title": "PChome 活動",
|
|
"diagnostics": {
|
|
"link_count": 2,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "medium",
|
|
"score": 73,
|
|
"url": "https://24h.pchome.com.tw/activity/sample",
|
|
"text": "活動頁",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "manual_sample_candidate_queue_approval_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["payload_received"] is True
|
|
assert data["approval_preview_created"] is True
|
|
assert data["approval_request_created"] is False
|
|
assert data["approval_record_written"] is False
|
|
assert data["review_queue_write_allowed"] is False
|
|
assert data["review_queue_created"] is False
|
|
assert data["review_queue_persisted"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["queue_write_preview"]["target_table"] == "market_alert_review_queue"
|
|
assert data["queue_write_preview"]["row_count"] == 1
|
|
|
|
|
|
def test_manual_sample_candidate_queue_approval_blocks_invalid_payload():
|
|
approval = MarketIntelService().build_manual_sample_candidate_queue_approval(
|
|
sample_result=None,
|
|
payload_error="invalid_json_object",
|
|
)
|
|
|
|
assert approval["mode"] == "manual_sample_candidate_queue_approval_preview"
|
|
assert approval["payload_received"] is False
|
|
assert approval["payload_valid_json_object"] is False
|
|
assert approval["approval_preview_created"] is False
|
|
assert approval["approval_request_created"] is False
|
|
assert approval["approval_record_written"] is False
|
|
assert approval["review_queue_write_allowed"] is False
|
|
assert approval["review_queue_created"] is False
|
|
assert approval["review_queue_persisted"] is False
|
|
assert approval["database_write_executed"] is False
|
|
assert "review_queue_draft_not_ready" in approval["blocked_reasons"]
|
|
|
|
|
|
def test_manual_sample_candidate_queue_transaction_preview_blocks_execution():
|
|
sample_result = {
|
|
"batch_id": "sample-batch-11",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "e" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 2,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
|
|
assert transaction["mode"] == "manual_sample_candidate_queue_transaction_preview"
|
|
assert transaction["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert transaction["payload_received"] is True
|
|
assert transaction["payload_valid_json_object"] is True
|
|
assert transaction["payload_persisted"] is False
|
|
assert transaction["transaction_preview_created"] is True
|
|
assert transaction["transaction_ready"] is False
|
|
assert transaction["transaction_opened"] is False
|
|
assert transaction["transaction_committed"] is False
|
|
assert transaction["approval_request_created"] is False
|
|
assert transaction["approval_record_written"] is False
|
|
assert transaction["review_queue_write_allowed"] is False
|
|
assert transaction["review_queue_created"] is False
|
|
assert transaction["review_queue_persisted"] is False
|
|
assert transaction["candidate_import_allowed"] is False
|
|
assert transaction["external_network_executed"] is False
|
|
assert transaction["database_connection_opened"] is False
|
|
assert transaction["database_session_created"] is False
|
|
assert transaction["database_write_executed"] is False
|
|
assert transaction["database_commit_executed"] is False
|
|
assert transaction["scheduler_attached"] is False
|
|
assert transaction["transaction_summary"]["target_table"] == "market_alert_review_queue"
|
|
assert transaction["transaction_summary"]["statement_count"] == 1
|
|
assert transaction["transaction_summary"]["conflict_policy"] == "dedupe_key_do_nothing"
|
|
statement = transaction["statements"][0]
|
|
assert statement["operation"] == "insert"
|
|
assert statement["table"] == "market_alert_review_queue"
|
|
assert statement["write_status"] == "blocked_transaction_preview_only"
|
|
assert statement["idempotency_key"].startswith("market_alert_review_queue:")
|
|
assert statement["parameter_preview"]["dedupe_key"].startswith("sample-candidate:")
|
|
assert statement["parameter_preview"]["metadata_json_preview"]["platform_code"] == "momo"
|
|
assert "queue_approval_gates_not_all_passed" in transaction["blocked_reasons"]
|
|
assert "queue_transaction_execution_still_blocked" in transaction["blocked_reasons"]
|
|
assert (
|
|
"do_not_execute_queue_transaction_from_preview"
|
|
in transaction["safe_boundaries"]
|
|
)
|
|
|
|
|
|
def test_manual_sample_candidate_queue_transaction_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/candidate_queue_transaction",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-12",
|
|
"platform_code": "pchome",
|
|
"source_key": "homepage",
|
|
"source_url": "https://24h.pchome.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1800,
|
|
"page_hash": "f" * 64,
|
|
"title": "PChome 活動",
|
|
"diagnostics": {
|
|
"link_count": 2,
|
|
"same_host_link_count": 2,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "medium",
|
|
"score": 74,
|
|
"url": "https://24h.pchome.com.tw/activity/sample",
|
|
"text": "活動頁",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "manual_sample_candidate_queue_transaction_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["payload_received"] is True
|
|
assert data["transaction_preview_created"] is True
|
|
assert data["transaction_ready"] is False
|
|
assert data["transaction_opened"] is False
|
|
assert data["transaction_committed"] is False
|
|
assert data["approval_record_written"] is False
|
|
assert data["review_queue_created"] is False
|
|
assert data["review_queue_persisted"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["transaction_summary"]["statement_count"] == 1
|
|
|
|
|
|
def test_manual_sample_candidate_queue_transaction_blocks_invalid_payload():
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=None,
|
|
payload_error="invalid_json_object",
|
|
)
|
|
|
|
assert transaction["mode"] == "manual_sample_candidate_queue_transaction_preview"
|
|
assert transaction["payload_received"] is False
|
|
assert transaction["payload_valid_json_object"] is False
|
|
assert transaction["transaction_preview_created"] is False
|
|
assert transaction["transaction_ready"] is False
|
|
assert transaction["transaction_opened"] is False
|
|
assert transaction["transaction_committed"] is False
|
|
assert transaction["approval_record_written"] is False
|
|
assert transaction["review_queue_created"] is False
|
|
assert transaction["database_write_executed"] is False
|
|
assert "queue_transaction_preview_not_ready" in transaction["blocked_reasons"]
|
|
|
|
|
|
def test_candidate_queue_writer_cli_gate_blocks_until_preflight_backup_and_smoke_pass():
|
|
from services.market_intel.candidate_queue_writer_cli import (
|
|
build_candidate_queue_writer_cli_plan,
|
|
)
|
|
|
|
sample_result = {
|
|
"batch_id": "sample-batch-13",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "a" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
status = build_candidate_queue_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
execute_requested=True,
|
|
apply_real_write=True,
|
|
approval_token=TEST_APPROVAL_TOKEN,
|
|
approval_token_secret=TEST_APPROVAL_TOKEN,
|
|
)
|
|
|
|
assert status["mode"] == "candidate_queue_writer_cli_blocked"
|
|
assert status["execute_requested"] is True
|
|
assert status["apply_real_write_requested"] is True
|
|
assert status["approval_token_present"] is True
|
|
assert status["approval_token_valid"] is True
|
|
assert status["queue_writer_implementation_enabled"] is True
|
|
assert status["ready_for_real_write"] is False
|
|
assert status["writes_executed"] is False
|
|
assert status["would_write_database"] is False
|
|
assert status["database_connection_opened"] is False
|
|
assert status["database_session_created"] is False
|
|
assert status["explicit_transaction_opened"] is False
|
|
assert status["database_write_executed"] is False
|
|
assert status["database_commit_executed"] is False
|
|
assert status["scheduler_attached"] is False
|
|
assert status["exit_code"] == 2
|
|
assert status["transaction_preview_summary"]["statement_count"] == 1
|
|
assert "approval_token_valid" not in status["blocked_reasons"]
|
|
assert "queue_writer_preflight_ready" in status["blocked_reasons"]
|
|
assert "backup_verified" in status["blocked_reasons"]
|
|
assert "migration_live_smoke_passed" in status["blocked_reasons"]
|
|
assert "queue_writer_implementation_enabled" not in status["blocked_reasons"]
|
|
assert status["safety_contract"]["refuses_api_execution"] is True
|
|
assert (
|
|
"do_not_execute_candidate_queue_writer_from_api"
|
|
in status["safe_boundaries"]
|
|
)
|
|
|
|
|
|
def test_candidate_queue_writer_preflight_planned_maps_payload_without_db():
|
|
from services.market_intel.candidate_queue_writer_preflight import (
|
|
build_candidate_queue_writer_preflight,
|
|
)
|
|
|
|
sample_result = {
|
|
"batch_id": "sample-batch-16",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "d" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
preflight = build_candidate_queue_writer_preflight(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
|
|
assert preflight["mode"] == "candidate_queue_writer_preflight_planned"
|
|
assert preflight["execute_requested"] is False
|
|
assert preflight["read_only_query_executed"] is False
|
|
assert preflight["database_connection_opened"] is False
|
|
assert preflight["database_write_executed"] is False
|
|
assert preflight["database_commit_executed"] is False
|
|
assert preflight["scheduler_attached"] is False
|
|
assert preflight["ready_for_writer_review"] is False
|
|
assert preflight["ready_for_real_write"] is False
|
|
assert preflight["statement_count"] == 1
|
|
assert preflight["payload_column_map"]["metadata_json_preview"] == "metadata_json"
|
|
assert preflight["unmapped_payload_keys"] == []
|
|
assert "metadata_json" in preflight["mapped_insert_columns"]
|
|
assert "queue_writer_preflight_not_loaded" in preflight["blocked_reasons"]
|
|
|
|
|
|
def test_candidate_queue_writer_preflight_sqlite_read_only_validates_columns():
|
|
from services.market_intel.candidate_queue_writer_preflight import (
|
|
build_candidate_queue_writer_preflight,
|
|
)
|
|
|
|
sample_result = {
|
|
"batch_id": "sample-batch-17",
|
|
"platform_code": "pchome",
|
|
"source_key": "homepage",
|
|
"source_url": "https://24h.pchome.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1800,
|
|
"page_hash": "e" * 64,
|
|
"title": "PChome 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "medium",
|
|
"score": 74,
|
|
"url": "https://24h.pchome.com.tw/activity/sample",
|
|
"text": "活動頁",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE market_alert_review_queue (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
alert_candidate_id TEXT NOT NULL UNIQUE,
|
|
review_state TEXT NOT NULL DEFAULT 'draft',
|
|
priority_lane TEXT NOT NULL DEFAULT 'watch',
|
|
threshold_level TEXT NOT NULL,
|
|
total_score FLOAT NOT NULL DEFAULT 0,
|
|
evidence_bundle_id TEXT NOT NULL,
|
|
dedupe_key TEXT NOT NULL,
|
|
source_batch_id TEXT NOT NULL,
|
|
metadata_json TEXT,
|
|
created_at TEXT,
|
|
updated_at TEXT
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"CREATE UNIQUE INDEX ux_market_alert_review_queue_dedupe "
|
|
"ON market_alert_review_queue (dedupe_key)"
|
|
)
|
|
)
|
|
|
|
preflight = build_candidate_queue_writer_preflight(
|
|
transaction_preview=transaction,
|
|
execute_requested=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
|
|
assert preflight["mode"] == "candidate_queue_writer_preflight_read_only"
|
|
assert preflight["execute_requested"] is True
|
|
assert preflight["read_only_query_executed"] is True
|
|
assert preflight["database_connection_opened"] is True
|
|
assert preflight["database_session_created"] is False
|
|
assert preflight["explicit_transaction_opened"] is False
|
|
assert preflight["database_write_executed"] is False
|
|
assert preflight["database_commit_executed"] is False
|
|
assert preflight["scheduler_attached"] is False
|
|
assert preflight["table_exists"] is True
|
|
assert preflight["schema_ready"] is True
|
|
assert preflight["ready_for_writer_review"] is True
|
|
assert preflight["ready_for_real_write"] is False
|
|
assert preflight["missing_insert_columns"] == []
|
|
assert preflight["dedupe_unique_index_present"] is True
|
|
assert preflight["unmapped_payload_keys"] == []
|
|
assert preflight["blocked_reasons"] == []
|
|
|
|
|
|
def test_candidate_queue_writer_cli_sqlite_transaction_is_idempotent():
|
|
from services.market_intel.candidate_queue_writer_cli import (
|
|
build_candidate_queue_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_preflight import (
|
|
build_candidate_queue_writer_preflight,
|
|
)
|
|
|
|
sample_result = {
|
|
"batch_id": "sample-batch-19",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "1" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE market_alert_review_queue (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
alert_candidate_id TEXT NOT NULL UNIQUE,
|
|
review_state TEXT NOT NULL DEFAULT 'draft',
|
|
priority_lane TEXT NOT NULL DEFAULT 'watch',
|
|
threshold_level TEXT NOT NULL,
|
|
total_score FLOAT NOT NULL DEFAULT 0,
|
|
evidence_bundle_id TEXT NOT NULL,
|
|
dedupe_key TEXT NOT NULL,
|
|
source_batch_id TEXT NOT NULL,
|
|
metadata_json TEXT,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"CREATE UNIQUE INDEX ux_market_alert_review_queue_dedupe "
|
|
"ON market_alert_review_queue (dedupe_key)"
|
|
)
|
|
)
|
|
|
|
preflight = build_candidate_queue_writer_preflight(
|
|
transaction_preview=transaction,
|
|
execute_requested=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
first_run = build_candidate_queue_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
execute_requested=True,
|
|
apply_real_write=True,
|
|
approval_token=TEST_APPROVAL_TOKEN,
|
|
approval_token_secret=TEST_APPROVAL_TOKEN,
|
|
backup_verified=True,
|
|
migration_live_smoke_passed=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
second_run = build_candidate_queue_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
execute_requested=True,
|
|
apply_real_write=True,
|
|
approval_token=TEST_APPROVAL_TOKEN,
|
|
approval_token_secret=TEST_APPROVAL_TOKEN,
|
|
backup_verified=True,
|
|
migration_live_smoke_passed=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
with engine.connect() as conn:
|
|
rows = conn.execute(
|
|
text(
|
|
"""
|
|
SELECT alert_candidate_id, review_state, dedupe_key, metadata_json
|
|
FROM market_alert_review_queue
|
|
"""
|
|
)
|
|
).fetchall()
|
|
|
|
assert first_run["mode"] == "candidate_queue_writer_cli_executed"
|
|
assert first_run["ready_for_real_write"] is True
|
|
assert first_run["writes_executed"] is True
|
|
assert first_run["would_write_database"] is True
|
|
assert first_run["database_connection_opened"] is True
|
|
assert first_run["database_session_created"] is False
|
|
assert first_run["explicit_transaction_opened"] is True
|
|
assert first_run["database_write_executed"] is True
|
|
assert first_run["database_commit_executed"] is True
|
|
assert first_run["database_rollback_executed"] is False
|
|
assert first_run["scheduler_attached"] is False
|
|
assert first_run["inserted_count"] == 1
|
|
assert first_run["skipped_count"] == 0
|
|
assert first_run["blocked_reasons"] == []
|
|
assert first_run["exit_code"] == 0
|
|
assert len(rows) == 1
|
|
assert rows[0]._mapping["review_state"] == "needs_review"
|
|
assert "platform_code" in rows[0]._mapping["metadata_json"]
|
|
|
|
assert second_run["mode"] == "candidate_queue_writer_cli_executed"
|
|
assert second_run["inserted_count"] == 0
|
|
assert second_run["skipped_count"] == 1
|
|
assert second_run["database_commit_executed"] is True
|
|
|
|
|
|
def test_candidate_queue_writer_postwrite_smoke_planned_without_db():
|
|
from services.market_intel.candidate_queue_writer_postwrite_smoke import (
|
|
build_candidate_queue_writer_postwrite_smoke,
|
|
)
|
|
|
|
sample_result = {
|
|
"batch_id": "sample-batch-20",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "2" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
smoke = build_candidate_queue_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
|
|
assert smoke["mode"] == "candidate_queue_writer_postwrite_smoke_planned"
|
|
assert smoke["execute_requested"] is False
|
|
assert smoke["read_only_query_executed"] is False
|
|
assert smoke["database_connection_opened"] is False
|
|
assert smoke["database_session_created"] is False
|
|
assert smoke["explicit_transaction_opened"] is False
|
|
assert smoke["database_write_executed"] is False
|
|
assert smoke["database_commit_executed"] is False
|
|
assert smoke["scheduler_attached"] is False
|
|
assert smoke["expected_dedupe_key_count"] == 1
|
|
assert smoke["found_count"] == 0
|
|
assert smoke["missing_count"] == 1
|
|
assert smoke["postwrite_smoke_passed"] is False
|
|
assert "candidate_queue_writer_postwrite_smoke_not_loaded" in smoke["blocked_reasons"]
|
|
|
|
|
|
def test_candidate_queue_writer_postwrite_smoke_sqlite_read_only_finds_rows():
|
|
from services.market_intel.candidate_queue_writer_cli import (
|
|
build_candidate_queue_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_postwrite_smoke import (
|
|
build_candidate_queue_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_preflight import (
|
|
build_candidate_queue_writer_preflight,
|
|
)
|
|
|
|
sample_result = {
|
|
"batch_id": "sample-batch-21",
|
|
"platform_code": "pchome",
|
|
"source_key": "homepage",
|
|
"source_url": "https://24h.pchome.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1800,
|
|
"page_hash": "3" * 64,
|
|
"title": "PChome 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "medium",
|
|
"score": 74,
|
|
"url": "https://24h.pchome.com.tw/activity/sample",
|
|
"text": "活動頁",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE market_alert_review_queue (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
alert_candidate_id TEXT NOT NULL UNIQUE,
|
|
review_state TEXT NOT NULL DEFAULT 'draft',
|
|
priority_lane TEXT NOT NULL DEFAULT 'watch',
|
|
threshold_level TEXT NOT NULL,
|
|
total_score FLOAT NOT NULL DEFAULT 0,
|
|
evidence_bundle_id TEXT NOT NULL,
|
|
dedupe_key TEXT NOT NULL,
|
|
source_batch_id TEXT NOT NULL,
|
|
metadata_json TEXT,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"CREATE UNIQUE INDEX ux_market_alert_review_queue_dedupe "
|
|
"ON market_alert_review_queue (dedupe_key)"
|
|
)
|
|
)
|
|
preflight = build_candidate_queue_writer_preflight(
|
|
transaction_preview=transaction,
|
|
execute_requested=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
writer = build_candidate_queue_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
execute_requested=True,
|
|
apply_real_write=True,
|
|
approval_token=TEST_APPROVAL_TOKEN,
|
|
approval_token_secret=TEST_APPROVAL_TOKEN,
|
|
backup_verified=True,
|
|
migration_live_smoke_passed=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
smoke = build_candidate_queue_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
|
|
assert writer["inserted_count"] == 1
|
|
assert smoke["mode"] == "candidate_queue_writer_postwrite_smoke_read_only"
|
|
assert smoke["execute_requested"] is True
|
|
assert smoke["read_only_query_executed"] is True
|
|
assert smoke["database_connection_opened"] is True
|
|
assert smoke["database_session_created"] is False
|
|
assert smoke["explicit_transaction_opened"] is False
|
|
assert smoke["database_write_executed"] is False
|
|
assert smoke["database_commit_executed"] is False
|
|
assert smoke["scheduler_attached"] is False
|
|
assert smoke["expected_dedupe_key_count"] == 1
|
|
assert smoke["found_count"] == 1
|
|
assert smoke["missing_count"] == 0
|
|
assert smoke["missing_dedupe_keys"] == []
|
|
assert smoke["postwrite_smoke_passed"] is True
|
|
assert smoke["ready_for_operator_review"] is True
|
|
assert smoke["blocked_reasons"] == []
|
|
assert smoke["row_summaries"][0]["review_state"] == "needs_review"
|
|
|
|
|
|
def test_candidate_queue_writer_operator_drill_preview_is_safe():
|
|
from services.market_intel.candidate_queue_writer_cli import (
|
|
build_candidate_queue_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_operator_drill import (
|
|
build_candidate_queue_writer_operator_drill,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_postwrite_smoke import (
|
|
build_candidate_queue_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_preflight import (
|
|
build_candidate_queue_writer_preflight,
|
|
)
|
|
|
|
sample_result = {
|
|
"batch_id": "sample-batch-23",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "5" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
preflight = build_candidate_queue_writer_preflight(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
writer_status = build_candidate_queue_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
)
|
|
postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
drill = build_candidate_queue_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
)
|
|
|
|
assert drill["mode"] == "candidate_queue_writer_operator_drill_preview"
|
|
assert drill["operator_drill_ready"] is True
|
|
assert drill["api_executes_cli"] is False
|
|
assert drill["api_reads_approval_token"] is False
|
|
assert drill["api_writes_database"] is False
|
|
assert drill["database_connection_opened"] is False
|
|
assert drill["database_session_created"] is False
|
|
assert drill["explicit_transaction_opened"] is False
|
|
assert drill["database_write_executed"] is False
|
|
assert drill["database_commit_executed"] is False
|
|
assert drill["scheduler_attached"] is False
|
|
assert drill["writes_executed"] is False
|
|
assert drill["statement_summary"]["statement_count"] == 1
|
|
assert len(drill["command_sequence"]) == 5
|
|
assert any(item["executes_database"] for item in drill["command_sequence"])
|
|
assert "backup_verified_by_operator" in drill["blocked_reasons"]
|
|
assert "one_time_token_supplied_in_shell_only" in drill["blocked_reasons"]
|
|
assert "do_not_execute_cli_from_api" in drill["safe_boundaries"]
|
|
|
|
|
|
def test_candidate_queue_writer_run_package_preview_is_safe():
|
|
from services.market_intel.candidate_queue_writer_cli import (
|
|
build_candidate_queue_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_operator_drill import (
|
|
build_candidate_queue_writer_operator_drill,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_postwrite_smoke import (
|
|
build_candidate_queue_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_preflight import (
|
|
build_candidate_queue_writer_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_package import (
|
|
build_candidate_queue_writer_run_package,
|
|
)
|
|
|
|
sample_result = {
|
|
"batch_id": "sample-batch-25",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "7" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
preflight = build_candidate_queue_writer_preflight(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
writer_status = build_candidate_queue_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
)
|
|
postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
operator_drill = build_candidate_queue_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
)
|
|
run_package = build_candidate_queue_writer_run_package(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
operator_drill=operator_drill,
|
|
)
|
|
|
|
assert run_package["mode"] == "candidate_queue_writer_run_package_preview"
|
|
assert run_package["package_ready"] is True
|
|
assert run_package["package_artifact_created"] is False
|
|
assert run_package["api_writes_file"] is False
|
|
assert run_package["api_executes_cli"] is False
|
|
assert run_package["api_reads_approval_token"] is False
|
|
assert run_package["api_writes_database"] is False
|
|
assert run_package["database_connection_opened"] is False
|
|
assert run_package["database_session_created"] is False
|
|
assert run_package["explicit_transaction_opened"] is False
|
|
assert run_package["database_write_executed"] is False
|
|
assert run_package["database_commit_executed"] is False
|
|
assert run_package["scheduler_attached"] is False
|
|
assert run_package["writes_executed"] is False
|
|
assert run_package["would_write_database"] is False
|
|
assert run_package["payload_manifest"]["payload_count"] == 1
|
|
assert len(run_package["payload_manifest"]["manifest_hash"]) == 64
|
|
assert len(run_package["required_artifacts"]) == 5
|
|
assert all(
|
|
item["created_by_api"] is False
|
|
for item in run_package["required_artifacts"]
|
|
)
|
|
assert len(run_package["command_bundle"]) == 5
|
|
assert any(item["executes_database"] for item in run_package["command_bundle"])
|
|
assert "real_sample_payload_saved_by_operator" in run_package["blocked_reasons"]
|
|
assert "one_time_token_supplied_in_shell_only" in run_package["blocked_reasons"]
|
|
assert "do_not_create_run_artifacts_from_api" in run_package["safe_boundaries"]
|
|
|
|
|
|
def test_candidate_queue_writer_run_readiness_preview_checks_operator_evidence():
|
|
from services.market_intel.candidate_queue_writer_cli import (
|
|
build_candidate_queue_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_operator_drill import (
|
|
build_candidate_queue_writer_operator_drill,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_postwrite_smoke import (
|
|
build_candidate_queue_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_preflight import (
|
|
build_candidate_queue_writer_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_package import (
|
|
build_candidate_queue_writer_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_readiness import (
|
|
build_candidate_queue_writer_run_readiness,
|
|
)
|
|
|
|
sample_result = {
|
|
"batch_id": "sample-batch-27",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "9" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
preflight = build_candidate_queue_writer_preflight(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
writer_status = build_candidate_queue_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
)
|
|
postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
operator_drill = build_candidate_queue_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
)
|
|
run_package = build_candidate_queue_writer_run_package(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
operator_drill=operator_drill,
|
|
)
|
|
|
|
missing = build_candidate_queue_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
operator_drill=operator_drill,
|
|
run_package=run_package,
|
|
)
|
|
ready = build_candidate_queue_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
operator_drill=operator_drill,
|
|
run_package=run_package,
|
|
operator_evidence={
|
|
"reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": "artifacts/market_intel/preflight.json",
|
|
"migration_live_smoke_passed": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
},
|
|
)
|
|
token_leak = build_candidate_queue_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
operator_drill=operator_drill,
|
|
run_package=run_package,
|
|
operator_evidence={
|
|
"reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": "artifacts/market_intel/preflight.json",
|
|
"migration_live_smoke_passed": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
|
|
assert missing["mode"] == "candidate_queue_writer_run_readiness_preview"
|
|
assert missing["ready_for_cli_operator_run"] is False
|
|
assert missing["ready_for_api_database_write"] is False
|
|
assert missing["api_executes_cli"] is False
|
|
assert missing["api_reads_approval_token"] is False
|
|
assert missing["api_writes_file"] is False
|
|
assert missing["database_connection_opened"] is False
|
|
assert missing["database_write_executed"] is False
|
|
assert missing["database_commit_executed"] is False
|
|
assert missing["scheduler_attached"] is False
|
|
assert "reviewed_sample_json_path_recorded" in missing["blocked_reasons"]
|
|
assert "backup_artifact_path_recorded" in missing["blocked_reasons"]
|
|
assert "operator_acknowledged_shell_only_token" in missing["blocked_reasons"]
|
|
assert ready["ready_for_cli_operator_run"] is True
|
|
assert ready["ready_for_api_database_write"] is False
|
|
assert ready["database_write_executed"] is False
|
|
assert ready["operator_evidence_summary"]["artifact_path_count"] == 3
|
|
assert token_leak["ready_for_cli_operator_run"] is False
|
|
assert token_leak["operator_evidence_summary"]["approval_token_submitted_to_api"] is True
|
|
assert "approval_token_not_submitted_to_api" in token_leak["blocked_reasons"]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
assert "do_not_read_approval_token_from_api" in ready["safe_boundaries"]
|
|
|
|
|
|
def test_candidate_queue_writer_run_receipt_preview_checks_writer_and_smoke_artifacts():
|
|
from services.market_intel.candidate_queue_writer_run_receipt import (
|
|
build_candidate_queue_writer_run_receipt,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture()
|
|
receipt = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=fixture["transaction"],
|
|
run_readiness=fixture["run_readiness"],
|
|
writer_output=fixture["writer_output"],
|
|
postwrite_smoke_result=fixture["postwrite_smoke_result"],
|
|
operator_evidence=fixture["operator_evidence"],
|
|
)
|
|
token_leak = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=fixture["transaction"],
|
|
run_readiness=fixture["run_readiness"],
|
|
writer_output={
|
|
**fixture["writer_output"],
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
postwrite_smoke_result=fixture["postwrite_smoke_result"],
|
|
operator_evidence={
|
|
**fixture["operator_evidence"],
|
|
"market_intel_queue_write_approval": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
malformed_receipt = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=fixture["transaction"],
|
|
run_readiness=fixture["run_readiness"],
|
|
writer_output={
|
|
"inserted_count": "not-a-number",
|
|
"affected_dedupe_keys": fixture["expected_keys"][0],
|
|
},
|
|
postwrite_smoke_result={
|
|
"found_count": "not-a-number",
|
|
"found_dedupe_keys": fixture["expected_keys"][0],
|
|
},
|
|
operator_evidence=fixture["operator_evidence"],
|
|
)
|
|
|
|
assert receipt["mode"] == "candidate_queue_writer_run_receipt_preview"
|
|
assert receipt["receipt_passed"] is True
|
|
assert receipt["ready_for_next_manual_review"] is True
|
|
assert receipt["ready_for_api_database_write"] is False
|
|
assert receipt["ready_for_scheduler_attach"] is False
|
|
assert receipt["api_executes_cli"] is False
|
|
assert receipt["api_reads_approval_token"] is False
|
|
assert receipt["api_writes_file"] is False
|
|
assert receipt["api_writes_database"] is False
|
|
assert receipt["database_connection_opened"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["database_commit_executed"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert receipt["expected_dedupe_keys"] == fixture["expected_keys"]
|
|
assert receipt["writer_output_summary"]["database_commit_executed"] is True
|
|
assert receipt["writer_output_summary"]["dedupe_keys_match_expected"] is True
|
|
assert receipt["postwrite_smoke_summary"]["read_only_query_executed"] is True
|
|
assert receipt["postwrite_smoke_summary"]["dedupe_keys_match_expected"] is True
|
|
assert receipt["operator_evidence_summary"][
|
|
"writer_output_json_path_recorded"
|
|
] is True
|
|
assert receipt["operator_evidence_summary"][
|
|
"postwrite_smoke_json_path_recorded"
|
|
] is True
|
|
assert receipt["operator_evidence_summary"][
|
|
"operator_confirmed_no_token_in_artifacts"
|
|
] is True
|
|
assert receipt["blocked_reasons"] == []
|
|
assert "do_not_execute_cli_from_receipt_preview" in receipt["safe_boundaries"]
|
|
assert "do_not_read_approval_token_from_api" in receipt["safe_boundaries"]
|
|
assert token_leak["receipt_passed"] is False
|
|
assert token_leak["writer_output_summary"]["approval_token_key_detected"] is True
|
|
assert token_leak["operator_evidence_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "writer_output_no_approval_token_key" in token_leak["blocked_reasons"]
|
|
assert "operator_confirmed_no_token_in_artifacts" in token_leak["blocked_reasons"]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
assert malformed_receipt["receipt_passed"] is False
|
|
assert malformed_receipt["writer_output_summary"]["inserted_count"] == 0
|
|
assert malformed_receipt["postwrite_smoke_summary"]["found_count"] == 0
|
|
assert "writer_output_executed_and_committed" in malformed_receipt[
|
|
"blocked_reasons"
|
|
]
|
|
|
|
|
|
def test_candidate_queue_writer_run_closeout_preview_promotes_only_manual_phase():
|
|
from services.market_intel.candidate_queue_writer_run_closeout import (
|
|
build_candidate_queue_writer_run_closeout,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_receipt import (
|
|
build_candidate_queue_writer_run_receipt,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture()
|
|
closeout_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"closeout_notes": "ready for read-only inventory",
|
|
}
|
|
receipt = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=fixture["transaction"],
|
|
run_readiness=fixture["run_readiness"],
|
|
writer_output=fixture["writer_output"],
|
|
postwrite_smoke_result=fixture["postwrite_smoke_result"],
|
|
operator_evidence=fixture["operator_evidence"],
|
|
)
|
|
closeout = build_candidate_queue_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=receipt,
|
|
operator_evidence=closeout_evidence,
|
|
)
|
|
missing = build_candidate_queue_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=receipt,
|
|
operator_evidence=fixture["operator_evidence"],
|
|
)
|
|
token_leak = build_candidate_queue_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=receipt,
|
|
operator_evidence={
|
|
**closeout_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
|
|
assert closeout["mode"] == "candidate_queue_writer_run_closeout_preview"
|
|
assert closeout["closeout_passed"] is True
|
|
assert closeout["ready_for_next_manual_phase"] is True
|
|
assert closeout["ready_for_api_database_write"] is False
|
|
assert closeout["ready_for_scheduler_attach"] is False
|
|
assert closeout["api_executes_cli"] is False
|
|
assert closeout["api_reads_approval_token"] is False
|
|
assert closeout["api_writes_file"] is False
|
|
assert closeout["api_writes_database"] is False
|
|
assert closeout["database_connection_opened"] is False
|
|
assert closeout["database_write_executed"] is False
|
|
assert closeout["database_commit_executed"] is False
|
|
assert closeout["scheduler_attached"] is False
|
|
assert closeout["receipt_summary"]["receipt_passed"] is True
|
|
assert closeout["receipt_summary"]["safe_boundaries_complete"] is True
|
|
assert closeout["operator_closeout_summary"][
|
|
"closeout_artifact_path_recorded"
|
|
] is True
|
|
assert closeout["promotion_gate"]["allowed"] is True
|
|
assert closeout["promotion_gate"]["requires_real_db_write"] is False
|
|
assert closeout["blocked_reasons"] == []
|
|
assert "do_not_write_queue_from_closeout_preview" in closeout["safe_boundaries"]
|
|
assert missing["closeout_passed"] is False
|
|
assert "closeout_artifact_path_recorded" in missing["blocked_reasons"]
|
|
assert "operator_confirmed_queue_review_next" in missing["blocked_reasons"]
|
|
assert token_leak["closeout_passed"] is False
|
|
assert token_leak["operator_closeout_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "closeout_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_handoff_preview_is_manual_only():
|
|
from services.market_intel.candidate_queue_review_handoff import (
|
|
build_candidate_queue_review_handoff,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_closeout import (
|
|
build_candidate_queue_writer_run_closeout,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_receipt import (
|
|
build_candidate_queue_writer_run_receipt,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture()
|
|
operator_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
}
|
|
receipt = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=fixture["transaction"],
|
|
run_readiness=fixture["run_readiness"],
|
|
writer_output=fixture["writer_output"],
|
|
postwrite_smoke_result=fixture["postwrite_smoke_result"],
|
|
operator_evidence=fixture["operator_evidence"],
|
|
)
|
|
closeout = build_candidate_queue_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=receipt,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
handoff = build_candidate_queue_review_handoff(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
token_leak = build_candidate_queue_review_handoff(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
|
|
assert handoff["mode"] == "candidate_queue_review_handoff_preview"
|
|
assert handoff["handoff_ready"] is True
|
|
assert handoff["ready_for_manual_queue_review"] is True
|
|
assert handoff["ready_for_live_inventory_read_only"] is True
|
|
assert handoff["ready_for_api_database_write"] is False
|
|
assert handoff["ready_for_scheduler_attach"] is False
|
|
assert handoff["api_executes_cli"] is False
|
|
assert handoff["api_reads_approval_token"] is False
|
|
assert handoff["api_writes_database"] is False
|
|
assert handoff["api_updates_review_state"] is False
|
|
assert handoff["read_only_query_executed"] is False
|
|
assert handoff["database_connection_opened"] is False
|
|
assert handoff["database_write_executed"] is False
|
|
assert handoff["database_commit_executed"] is False
|
|
assert handoff["scheduler_attached"] is False
|
|
assert handoff["expected_dedupe_keys"] == fixture["expected_keys"]
|
|
assert handoff["review_contract"]["expected_review_state"] == "needs_review"
|
|
assert "update_review_state" in handoff["review_contract"]["forbidden_api_actions"]
|
|
assert "do_not_update_review_state_from_api" in handoff["safe_boundaries"]
|
|
assert handoff["blocked_reasons"] == []
|
|
assert token_leak["handoff_ready"] is False
|
|
assert token_leak["operator_handoff_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "handoff_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_inventory_preview_is_read_only():
|
|
from services.market_intel.candidate_queue_review_handoff import (
|
|
build_candidate_queue_review_handoff,
|
|
)
|
|
from services.market_intel.candidate_queue_review_inventory import (
|
|
build_candidate_queue_review_inventory,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_closeout import (
|
|
build_candidate_queue_writer_run_closeout,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_receipt import (
|
|
build_candidate_queue_writer_run_receipt,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture()
|
|
operator_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
}
|
|
receipt = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=fixture["transaction"],
|
|
run_readiness=fixture["run_readiness"],
|
|
writer_output=fixture["writer_output"],
|
|
postwrite_smoke_result=fixture["postwrite_smoke_result"],
|
|
operator_evidence=fixture["operator_evidence"],
|
|
)
|
|
closeout = build_candidate_queue_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=receipt,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
handoff = build_candidate_queue_review_handoff(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
postwrite_smoke = {
|
|
**fixture["postwrite_smoke_result"],
|
|
"database_commit_executed": False,
|
|
"row_summaries": [
|
|
{
|
|
"dedupe_key": fixture["expected_keys"][0],
|
|
"review_state": "needs_review",
|
|
"priority_lane": "review",
|
|
"total_score": 94,
|
|
"source_batch_id": fixture["sample_result"]["batch_id"],
|
|
}
|
|
],
|
|
}
|
|
live_db_inventory = {
|
|
"mode": "live_db_inventory_read_only",
|
|
"summary_ready": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"migration_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"table_statuses": [
|
|
{
|
|
"table": "market_alert_review_queue",
|
|
"exists": True,
|
|
"row_count": 1,
|
|
"status": "loaded",
|
|
}
|
|
],
|
|
"total_rows": 1,
|
|
"alert_review_state_breakdown": [
|
|
{
|
|
"review_state": "needs_review",
|
|
"priority_lane": "review",
|
|
"alert_count": 1,
|
|
}
|
|
],
|
|
}
|
|
inventory = build_candidate_queue_review_inventory(
|
|
review_handoff=handoff,
|
|
postwrite_smoke=postwrite_smoke,
|
|
live_db_inventory=live_db_inventory,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_inventory(
|
|
review_handoff=handoff,
|
|
postwrite_smoke=postwrite_smoke,
|
|
live_db_inventory=live_db_inventory,
|
|
operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert inventory["mode"] == "candidate_queue_review_inventory_preview"
|
|
assert inventory["review_inventory_ready"] is True
|
|
assert inventory["ready_for_human_decision_review"] is True
|
|
assert inventory["ready_for_api_review_state_update"] is False
|
|
assert inventory["ready_for_api_database_write"] is False
|
|
assert inventory["ready_for_scheduler_attach"] is False
|
|
assert inventory["api_executes_cli"] is False
|
|
assert inventory["api_reads_approval_token"] is False
|
|
assert inventory["api_writes_database"] is False
|
|
assert inventory["api_updates_review_state"] is False
|
|
assert inventory["read_only_query_executed"] is True
|
|
assert inventory["database_connection_opened"] is True
|
|
assert inventory["database_write_executed"] is False
|
|
assert inventory["database_commit_executed"] is False
|
|
assert inventory["scheduler_attached"] is False
|
|
assert inventory["expected_dedupe_keys"] == fixture["expected_keys"]
|
|
assert inventory["found_dedupe_keys"] == fixture["expected_keys"]
|
|
assert inventory["missing_dedupe_keys"] == []
|
|
assert inventory["row_summaries"][0]["review_state"] == "needs_review"
|
|
assert inventory["alert_review_queue_table"]["exists"] is True
|
|
assert inventory["blocked_reasons"] == []
|
|
assert "do_not_update_review_state_from_api" in inventory["safe_boundaries"]
|
|
assert token_leak["review_inventory_ready"] is False
|
|
assert token_leak["operator_inventory_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "review_inventory_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_inventory_preview_is_read_only_manual_gate():
|
|
from services.market_intel.candidate_queue_review_handoff import (
|
|
build_candidate_queue_review_handoff,
|
|
)
|
|
from services.market_intel.candidate_queue_review_inventory import (
|
|
build_candidate_queue_review_inventory,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_closeout import (
|
|
build_candidate_queue_writer_run_closeout,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_receipt import (
|
|
build_candidate_queue_writer_run_receipt,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-inventory"
|
|
)
|
|
operator_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
}
|
|
receipt = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=fixture["transaction"],
|
|
run_readiness=fixture["run_readiness"],
|
|
writer_output=fixture["writer_output"],
|
|
postwrite_smoke_result=fixture["postwrite_smoke_result"],
|
|
operator_evidence=fixture["operator_evidence"],
|
|
)
|
|
closeout = build_candidate_queue_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=receipt,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
handoff = build_candidate_queue_review_handoff(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
live_inventory = {
|
|
"mode": "live_db_inventory_read_only",
|
|
"summary_ready": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"migration_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"total_rows": len(fixture["expected_keys"]),
|
|
"table_statuses": [
|
|
{
|
|
"table": "market_alert_review_queue",
|
|
"exists": True,
|
|
"row_count": len(fixture["expected_keys"]),
|
|
"status": "loaded",
|
|
}
|
|
],
|
|
"alert_review_state_breakdown": [
|
|
{
|
|
"review_state": "needs_review",
|
|
"priority_lane": "watch",
|
|
"alert_count": len(fixture["expected_keys"]),
|
|
}
|
|
],
|
|
}
|
|
|
|
inventory = build_candidate_queue_review_inventory(
|
|
review_handoff=handoff,
|
|
postwrite_smoke=fixture["postwrite_smoke_result"],
|
|
live_db_inventory=live_inventory,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_inventory(
|
|
review_handoff=handoff,
|
|
postwrite_smoke=fixture["postwrite_smoke_result"],
|
|
live_db_inventory=live_inventory,
|
|
operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert inventory["mode"] == "candidate_queue_review_inventory_preview"
|
|
assert inventory["review_inventory_ready"] is True
|
|
assert inventory["ready_for_human_decision_review"] is True
|
|
assert inventory["ready_for_api_review_state_update"] is False
|
|
assert inventory["ready_for_api_database_write"] is False
|
|
assert inventory["ready_for_scheduler_attach"] is False
|
|
assert inventory["api_executes_cli"] is False
|
|
assert inventory["api_reads_approval_token"] is False
|
|
assert inventory["api_writes_database"] is False
|
|
assert inventory["api_updates_review_state"] is False
|
|
assert inventory["read_only_query_executed"] is True
|
|
assert inventory["database_write_executed"] is False
|
|
assert inventory["database_commit_executed"] is False
|
|
assert inventory["scheduler_attached"] is False
|
|
assert inventory["expected_dedupe_keys"] == fixture["expected_keys"]
|
|
assert inventory["found_dedupe_keys"] == fixture["expected_keys"]
|
|
assert inventory["missing_dedupe_keys"] == []
|
|
assert inventory["row_summaries"][0]["review_state"] == "needs_review"
|
|
assert inventory["alert_review_queue_table"]["exists"] is True
|
|
assert "do_not_update_review_state_from_api" in inventory["safe_boundaries"]
|
|
assert inventory["blocked_reasons"] == []
|
|
assert token_leak["review_inventory_ready"] is False
|
|
assert "review_inventory_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_decision_preview_is_manual_only():
|
|
from services.market_intel.candidate_queue_review_decision import (
|
|
build_candidate_queue_review_decision,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision"
|
|
)
|
|
inventory = {
|
|
"mode": "candidate_queue_review_inventory_preview",
|
|
"review_inventory_ready": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"scheduler_attached": False,
|
|
"expected_dedupe_keys": fixture["expected_keys"],
|
|
"row_summaries": [
|
|
{
|
|
"dedupe_key": fixture["expected_keys"][0],
|
|
"review_state": "needs_review",
|
|
"priority_lane": "watch",
|
|
"total_score": 82.5,
|
|
}
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "evidence reviewed manually",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
}
|
|
decision = build_candidate_queue_review_decision(
|
|
review_inventory=inventory,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
token_leak = build_candidate_queue_review_decision(
|
|
review_inventory=inventory,
|
|
operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
|
|
assert decision["mode"] == "candidate_queue_review_decision_preview"
|
|
assert decision["decision_ready"] is True
|
|
assert decision["ready_for_human_decision_record"] is True
|
|
assert decision["ready_for_api_review_state_update"] is False
|
|
assert decision["ready_for_api_database_write"] is False
|
|
assert decision["ready_for_scheduler_attach"] is False
|
|
assert decision["api_executes_cli"] is False
|
|
assert decision["api_reads_approval_token"] is False
|
|
assert decision["api_writes_database"] is False
|
|
assert decision["api_updates_review_state"] is False
|
|
assert decision["decision_record_written"] is False
|
|
assert decision["review_state_update_executed"] is False
|
|
assert decision["database_write_executed"] is False
|
|
assert decision["database_commit_executed"] is False
|
|
assert decision["scheduler_attached"] is False
|
|
assert decision["decision_rows"][0]["current_review_state"] == "needs_review"
|
|
assert decision["decision_rows"][0]["proposed_review_state"] == "confirmed"
|
|
assert decision["decision_contract"]["allowed_next_states"] == [
|
|
"confirmed",
|
|
"rejected",
|
|
"deferred",
|
|
]
|
|
assert "update_review_state" in decision["decision_contract"]["forbidden_api_actions"]
|
|
assert "do_not_write_decision_record_from_api" in decision["safe_boundaries"]
|
|
assert decision["blocked_reasons"] == []
|
|
assert token_leak["decision_ready"] is False
|
|
assert token_leak["operator_decision_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "decision_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_decision_approval_preview_is_cli_only():
|
|
from services.market_intel.candidate_queue_review_decision import (
|
|
build_candidate_queue_review_decision,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_approval import (
|
|
build_candidate_queue_review_decision_approval,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-approval"
|
|
)
|
|
inventory = {
|
|
"mode": "candidate_queue_review_inventory_preview",
|
|
"review_inventory_ready": True,
|
|
"expected_dedupe_keys": fixture["expected_keys"],
|
|
"row_summaries": [
|
|
{
|
|
"dedupe_key": fixture["expected_keys"][0],
|
|
"review_state": "needs_review",
|
|
"priority_lane": "watch",
|
|
"total_score": 82.5,
|
|
}
|
|
],
|
|
}
|
|
decision_operator_evidence = {
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "evidence reviewed manually",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
}
|
|
approval_operator_evidence = {
|
|
**decision_operator_evidence,
|
|
"decision_approval_notes": "approved for cli-only transaction preview",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
}
|
|
decision = build_candidate_queue_review_decision(
|
|
review_inventory=inventory,
|
|
operator_evidence=decision_operator_evidence,
|
|
)
|
|
approval = build_candidate_queue_review_decision_approval(
|
|
review_decision=decision,
|
|
operator_evidence=approval_operator_evidence,
|
|
)
|
|
token_leak = build_candidate_queue_review_decision_approval(
|
|
review_decision=decision,
|
|
operator_evidence={
|
|
**approval_operator_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
|
|
assert approval["mode"] == "candidate_queue_review_decision_approval_preview"
|
|
assert approval["approval_ready"] is True
|
|
assert approval["ready_for_review_state_transaction_preview"] is True
|
|
assert approval["ready_for_cli_decision_writer"] is True
|
|
assert approval["ready_for_api_review_state_update"] is False
|
|
assert approval["ready_for_api_database_write"] is False
|
|
assert approval["review_state_update_allowed_from_api"] is False
|
|
assert approval["decision_apply_allowed_from_api"] is False
|
|
assert approval["api_executes_cli"] is False
|
|
assert approval["api_reads_approval_token"] is False
|
|
assert approval["api_writes_database"] is False
|
|
assert approval["api_updates_review_state"] is False
|
|
assert approval["approval_record_written"] is False
|
|
assert approval["decision_record_written"] is False
|
|
assert approval["review_state_update_executed"] is False
|
|
assert approval["database_write_executed"] is False
|
|
assert approval["database_commit_executed"] is False
|
|
assert approval["scheduler_attached"] is False
|
|
assert approval["decision_update_preview"][0][
|
|
"expected_current_review_state"
|
|
] == "needs_review"
|
|
assert approval["decision_update_preview"][0][
|
|
"approved_next_review_state"
|
|
] == "confirmed"
|
|
assert approval["approval_contract"]["next_stage"] == (
|
|
"candidate_queue_review_decision_transaction_preview"
|
|
)
|
|
assert "update_review_state" in approval["approval_contract"][
|
|
"forbidden_api_actions"
|
|
]
|
|
assert "do_not_update_review_state_from_approval_api" in approval[
|
|
"safe_boundaries"
|
|
]
|
|
assert approval["blocked_reasons"] == []
|
|
assert token_leak["approval_ready"] is False
|
|
assert token_leak["operator_approval_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "approval_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_decision_transaction_preview_is_shell_only():
|
|
from services.market_intel.candidate_queue_review_decision import (
|
|
build_candidate_queue_review_decision,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_approval import (
|
|
build_candidate_queue_review_decision_approval,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_transaction import (
|
|
build_candidate_queue_review_decision_transaction,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-transaction"
|
|
)
|
|
inventory = {
|
|
"mode": "candidate_queue_review_inventory_preview",
|
|
"review_inventory_ready": True,
|
|
"expected_dedupe_keys": fixture["expected_keys"],
|
|
"row_summaries": [
|
|
{
|
|
"dedupe_key": fixture["expected_keys"][0],
|
|
"review_state": "needs_review",
|
|
"priority_lane": "watch",
|
|
"total_score": 82.5,
|
|
}
|
|
],
|
|
}
|
|
decision_operator_evidence = {
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "evidence reviewed manually",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
}
|
|
approval_operator_evidence = {
|
|
**decision_operator_evidence,
|
|
"decision_approval_notes": "approved for cli-only transaction preview",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
}
|
|
transaction_operator_evidence = {
|
|
**approval_operator_evidence,
|
|
"decision_transaction_notes": "payload reviewed for shell transaction",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
}
|
|
decision = build_candidate_queue_review_decision(
|
|
review_inventory=inventory,
|
|
operator_evidence=decision_operator_evidence,
|
|
)
|
|
approval = build_candidate_queue_review_decision_approval(
|
|
review_decision=decision,
|
|
operator_evidence=approval_operator_evidence,
|
|
)
|
|
transaction = build_candidate_queue_review_decision_transaction(
|
|
decision_approval=approval,
|
|
operator_evidence=transaction_operator_evidence,
|
|
)
|
|
token_leak = build_candidate_queue_review_decision_transaction(
|
|
decision_approval=approval,
|
|
operator_evidence={
|
|
**transaction_operator_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
|
|
assert transaction["mode"] == "candidate_queue_review_decision_transaction_preview"
|
|
assert transaction["transaction_preview_created"] is True
|
|
assert transaction["transaction_ready"] is True
|
|
assert transaction["ready_for_manual_shell_update_window"] is True
|
|
assert transaction["ready_for_cli_decision_writer"] is True
|
|
assert transaction["ready_for_api_review_state_update"] is False
|
|
assert transaction["ready_for_api_database_write"] is False
|
|
assert transaction["ready_for_scheduler_attach"] is False
|
|
assert transaction["api_executes_cli"] is False
|
|
assert transaction["api_reads_approval_token"] is False
|
|
assert transaction["api_writes_database"] is False
|
|
assert transaction["api_updates_review_state"] is False
|
|
assert transaction["approval_record_written"] is False
|
|
assert transaction["decision_record_written"] is False
|
|
assert transaction["review_state_update_executed"] is False
|
|
assert transaction["database_connection_opened"] is False
|
|
assert transaction["database_session_created"] is False
|
|
assert transaction["explicit_transaction_opened"] is False
|
|
assert transaction["transaction_opened"] is False
|
|
assert transaction["transaction_committed"] is False
|
|
assert transaction["database_write_executed"] is False
|
|
assert transaction["database_commit_executed"] is False
|
|
assert transaction["database_rollback_executed"] is False
|
|
assert transaction["scheduler_attached"] is False
|
|
assert transaction["statements"][0]["table"] == "market_alert_review_queue"
|
|
assert transaction["statements"][0]["operation"] == "update"
|
|
assert transaction["statements"][0]["statement_type"] == "update_review_state"
|
|
assert transaction["statements"][0]["expected_current_review_state"] == (
|
|
"needs_review"
|
|
)
|
|
assert transaction["statements"][0]["next_review_state"] == "confirmed"
|
|
assert transaction["statements"][0]["parameter_keys"] == [
|
|
"dedupe_key",
|
|
"expected_current_review_state",
|
|
"next_review_state",
|
|
]
|
|
assert "UPDATE market_alert_review_queue" in transaction["statements"][0][
|
|
"sql_template"
|
|
]
|
|
assert transaction["transaction_preview_summary"]["api_write_allowed"] is False
|
|
assert transaction["transaction_preview_summary"]["manual_cli_required"] is True
|
|
assert transaction["transaction_contract"]["next_stage"] == (
|
|
"manual_shell_review_state_update_window"
|
|
)
|
|
assert "update_review_state" in transaction["transaction_contract"][
|
|
"forbidden_api_actions"
|
|
]
|
|
assert "do_not_update_review_state_from_transaction_api" in transaction[
|
|
"safe_boundaries"
|
|
]
|
|
assert transaction["blocked_reasons"] == []
|
|
assert token_leak["transaction_ready"] is False
|
|
assert token_leak["operator_transaction_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "transaction_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_cli_gate_is_non_writing():
|
|
from services.market_intel.candidate_queue_review_decision_writer_cli import (
|
|
APPROVAL_ENV_VAR,
|
|
build_candidate_queue_review_decision_writer_cli_plan,
|
|
)
|
|
|
|
transaction, _ = _build_ready_review_decision_transaction()
|
|
plan = build_candidate_queue_review_decision_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
execute_requested=True,
|
|
apply_real_write=True,
|
|
approval_token=TEST_APPROVAL_TOKEN,
|
|
approval_token_secret=TEST_APPROVAL_TOKEN,
|
|
backup_verified=True,
|
|
review_inventory_smoke_passed=True,
|
|
)
|
|
payload = json.dumps(plan, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert plan["mode"] == "candidate_queue_review_decision_writer_cli_blocked"
|
|
assert plan["target_table"] == "market_alert_review_queue"
|
|
assert plan["target_operation"] == "update_review_state"
|
|
assert plan["script_path"] == "scripts/market_intel_review_decision_writer.py"
|
|
assert plan["approval_env_var"] == APPROVAL_ENV_VAR
|
|
assert plan["execute_requested"] is True
|
|
assert plan["apply_real_write_requested"] is True
|
|
assert plan["approval_token_present"] is True
|
|
assert plan["approval_token_valid"] is True
|
|
assert plan["writer_implementation_enabled"] is False
|
|
assert plan["ready_for_real_write"] is False
|
|
assert plan["ready_for_api_review_state_update"] is False
|
|
assert plan["ready_for_api_database_write"] is False
|
|
assert plan["api_executes_cli"] is False
|
|
assert plan["api_reads_approval_token"] is False
|
|
assert plan["api_writes_database"] is False
|
|
assert plan["api_updates_review_state"] is False
|
|
assert plan["review_state_update_executed"] is False
|
|
assert plan["database_connection_opened"] is False
|
|
assert plan["database_session_created"] is False
|
|
assert plan["explicit_transaction_opened"] is False
|
|
assert plan["transaction_opened"] is False
|
|
assert plan["transaction_committed"] is False
|
|
assert plan["database_write_executed"] is False
|
|
assert plan["database_commit_executed"] is False
|
|
assert plan["scheduler_attached"] is False
|
|
assert plan["writes_executed"] is False
|
|
assert plan["would_write_database"] is False
|
|
assert plan["statement_summary"]["statement_count"] == 1
|
|
assert plan["statement_summary"]["review_state_updates"][0][
|
|
"next_review_state"
|
|
] == "confirmed"
|
|
assert "review_decision_writer_implementation_enabled" in plan[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_update_review_state_from_api_writer_status" in plan[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_preflight_is_payload_only():
|
|
from services.market_intel.candidate_queue_review_decision_writer_cli import (
|
|
build_candidate_queue_review_decision_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_preflight import (
|
|
build_candidate_queue_review_decision_writer_preflight,
|
|
)
|
|
|
|
transaction, operator_evidence = _build_ready_review_decision_transaction()
|
|
writer_status = build_candidate_queue_review_decision_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
apply_real_write=False,
|
|
)
|
|
preflight = build_candidate_queue_review_decision_writer_preflight(
|
|
writer_status=writer_status,
|
|
transaction_preview=transaction,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"operator_confirmed_review_state_preflight_only": True,
|
|
},
|
|
)
|
|
token_leak = build_candidate_queue_review_decision_writer_preflight(
|
|
writer_status=writer_status,
|
|
transaction_preview=transaction,
|
|
operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
payload = json.dumps(preflight, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert preflight["mode"] == (
|
|
"candidate_queue_review_decision_writer_preflight_preview"
|
|
)
|
|
assert preflight["target_table"] == "market_alert_review_queue"
|
|
assert preflight["target_operation"] == "update_review_state"
|
|
assert preflight["execute_requested"] is False
|
|
assert preflight["apply_real_write_requested"] is False
|
|
assert preflight["preflight_payload_ready"] is True
|
|
assert preflight["writer_status_safe"] is True
|
|
assert preflight["writer_implementation_enabled"] is False
|
|
assert preflight["preflight_ready"] is False
|
|
assert preflight["ready_for_real_write"] is False
|
|
assert preflight["ready_for_api_review_state_update"] is False
|
|
assert preflight["ready_for_api_database_write"] is False
|
|
assert preflight["api_executes_cli"] is False
|
|
assert preflight["api_reads_approval_token"] is False
|
|
assert preflight["api_writes_database"] is False
|
|
assert preflight["api_updates_review_state"] is False
|
|
assert preflight["review_state_update_executed"] is False
|
|
assert preflight["read_only_query_executed"] is False
|
|
assert preflight["database_connection_opened"] is False
|
|
assert preflight["database_session_created"] is False
|
|
assert preflight["transaction_opened"] is False
|
|
assert preflight["transaction_committed"] is False
|
|
assert preflight["database_write_executed"] is False
|
|
assert preflight["database_commit_executed"] is False
|
|
assert preflight["scheduler_attached"] is False
|
|
assert preflight["writes_executed"] is False
|
|
assert preflight["would_write_database"] is False
|
|
assert preflight["statement_summary"]["statement_count"] == 1
|
|
assert preflight["statement_summary"]["invalid_statement_count"] == 0
|
|
assert preflight["statement_summary"]["review_state_updates"][0][
|
|
"next_review_state"
|
|
] == "confirmed"
|
|
assert preflight["update_contract"]["expected_current_review_state"] == (
|
|
"needs_review"
|
|
)
|
|
assert preflight["catalog_probe_plan"]["read_only_query_executed"] is False
|
|
assert "review_decision_writer_implementation_enabled" in preflight[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_update_review_state_from_review_state_preflight" in preflight[
|
|
"safe_boundaries"
|
|
]
|
|
assert "preflight_no_token_submitted_to_api" in token_leak["blocked_reasons"]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_postwrite_smoke_is_read_only():
|
|
from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
|
|
build_candidate_queue_review_decision_writer_postwrite_smoke,
|
|
)
|
|
|
|
transaction, _operator_evidence = _build_ready_review_decision_transaction()
|
|
statement = transaction["statements"][0]
|
|
dedupe_key = statement["lookup"]["dedupe_key"]
|
|
expected_state = statement["next_review_state"]
|
|
plan = build_candidate_queue_review_decision_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE market_alert_review_queue (
|
|
id INTEGER PRIMARY KEY,
|
|
alert_candidate_id INTEGER,
|
|
review_state TEXT,
|
|
priority_lane TEXT,
|
|
threshold_level TEXT,
|
|
total_score REAL,
|
|
evidence_bundle_id TEXT,
|
|
dedupe_key TEXT UNIQUE,
|
|
source_batch_id TEXT,
|
|
reviewed_at TEXT,
|
|
created_at TEXT,
|
|
updated_at TEXT
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
INSERT INTO market_alert_review_queue (
|
|
alert_candidate_id,
|
|
review_state,
|
|
priority_lane,
|
|
threshold_level,
|
|
total_score,
|
|
evidence_bundle_id,
|
|
dedupe_key,
|
|
source_batch_id,
|
|
reviewed_at,
|
|
created_at,
|
|
updated_at
|
|
)
|
|
VALUES (
|
|
101,
|
|
:review_state,
|
|
'urgent',
|
|
'high',
|
|
91.5,
|
|
'evidence-1',
|
|
:dedupe_key,
|
|
'sample-batch',
|
|
'2026-05-19T12:00:00',
|
|
'2026-05-19T11:00:00',
|
|
'2026-05-19T12:00:00'
|
|
)
|
|
"""
|
|
),
|
|
{"review_state": expected_state, "dedupe_key": dedupe_key},
|
|
)
|
|
smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
payload = json.dumps(smoke, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert plan["mode"] == (
|
|
"candidate_queue_review_decision_writer_postwrite_smoke_planned"
|
|
)
|
|
assert plan["read_only_query_executed"] is False
|
|
assert plan["database_connection_opened"] is False
|
|
assert plan["review_state_update_executed"] is False
|
|
assert plan["api_updates_review_state"] is False
|
|
assert plan["database_write_executed"] is False
|
|
assert plan["database_commit_executed"] is False
|
|
assert "review_decision_writer_postwrite_smoke_not_loaded" in plan[
|
|
"blocked_reasons"
|
|
]
|
|
assert smoke["mode"] == (
|
|
"candidate_queue_review_decision_writer_postwrite_smoke_read_only"
|
|
)
|
|
assert smoke["read_only_query_executed"] is True
|
|
assert smoke["database_connection_opened"] is True
|
|
assert smoke["database_session_created"] is False
|
|
assert smoke["explicit_transaction_opened"] is False
|
|
assert smoke["transaction_committed"] is False
|
|
assert smoke["database_write_executed"] is False
|
|
assert smoke["database_commit_executed"] is False
|
|
assert smoke["review_state_update_executed"] is False
|
|
assert smoke["api_updates_review_state"] is False
|
|
assert smoke["scheduler_attached"] is False
|
|
assert smoke["postwrite_smoke_passed"] is True
|
|
assert smoke["review_state_update_verified"] is True
|
|
assert smoke["missing_count"] == 0
|
|
assert smoke["state_mismatch_count"] == 0
|
|
assert smoke["found_dedupe_keys"] == [dedupe_key]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_operator_drill_preview_is_safe():
|
|
from services.market_intel.candidate_queue_review_decision_writer_cli import (
|
|
build_candidate_queue_review_decision_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_preflight import (
|
|
build_candidate_queue_review_decision_writer_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
|
|
build_candidate_queue_review_decision_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
|
|
build_candidate_queue_review_decision_writer_operator_drill,
|
|
)
|
|
|
|
transaction, operator_evidence = _build_ready_review_decision_transaction()
|
|
operator_evidence = {
|
|
**operator_evidence,
|
|
"operator_confirmed_manual_shell_window": True,
|
|
"operator_confirmed_post_update_inventory_planned": True,
|
|
"operator_drill_notes": "review_state shell drill reviewed",
|
|
}
|
|
writer_status = build_candidate_queue_review_decision_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
preflight = build_candidate_queue_review_decision_writer_preflight(
|
|
writer_status=writer_status,
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
drill = build_candidate_queue_review_decision_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
token_leak = build_candidate_queue_review_decision_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
payload = json.dumps(drill, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert drill["mode"] == (
|
|
"candidate_queue_review_decision_writer_operator_drill_preview"
|
|
)
|
|
assert drill["target_table"] == "market_alert_review_queue"
|
|
assert drill["target_operation"] == "update_review_state"
|
|
assert drill["operator_drill_ready"] is True
|
|
assert drill["ready_for_api_review_state_update"] is False
|
|
assert drill["ready_for_api_database_write"] is False
|
|
assert drill["ready_for_scheduler_attach"] is False
|
|
assert drill["api_executes_cli"] is False
|
|
assert drill["api_reads_approval_token"] is False
|
|
assert drill["api_writes_file"] is False
|
|
assert drill["api_writes_database"] is False
|
|
assert drill["api_updates_review_state"] is False
|
|
assert drill["review_state_update_executed"] is False
|
|
assert drill["database_connection_opened"] is False
|
|
assert drill["database_session_created"] is False
|
|
assert drill["transaction_opened"] is False
|
|
assert drill["transaction_committed"] is False
|
|
assert drill["database_write_executed"] is False
|
|
assert drill["database_commit_executed"] is False
|
|
assert drill["scheduler_attached"] is False
|
|
assert drill["statement_summary"]["statement_count"] == 1
|
|
assert drill["statement_summary"]["invalid_statement_count"] == 0
|
|
assert drill["input_summaries"]["writer_preflight_mode"] == (
|
|
"candidate_queue_review_decision_writer_preflight_preview"
|
|
)
|
|
assert drill["input_summaries"]["postwrite_smoke_mode"] == (
|
|
"candidate_queue_review_decision_writer_postwrite_smoke_planned"
|
|
)
|
|
assert len(drill["command_sequence"]) == 5
|
|
assert any(item["key"] == "run_cli_review_state_writer" for item in drill["command_sequence"])
|
|
assert "backup_verified_by_operator" in drill["blocked_reasons"]
|
|
assert "do_not_update_review_state_from_review_state_operator_drill" in drill[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["operator_drill_ready"] is False
|
|
assert "operator_drill_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_run_package_preview_is_safe():
|
|
from services.market_intel.candidate_queue_review_decision_writer_cli import (
|
|
build_candidate_queue_review_decision_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_preflight import (
|
|
build_candidate_queue_review_decision_writer_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
|
|
build_candidate_queue_review_decision_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
|
|
build_candidate_queue_review_decision_writer_operator_drill,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_package import (
|
|
build_candidate_queue_review_decision_writer_run_package,
|
|
)
|
|
|
|
transaction, operator_evidence = _build_ready_review_decision_transaction()
|
|
operator_evidence = {
|
|
**operator_evidence,
|
|
"operator_confirmed_manual_shell_window": True,
|
|
"operator_confirmed_post_update_inventory_planned": True,
|
|
"operator_drill_notes": "review_state shell drill reviewed",
|
|
}
|
|
writer_status = build_candidate_queue_review_decision_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
preflight = build_candidate_queue_review_decision_writer_preflight(
|
|
writer_status=writer_status,
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
drill = build_candidate_queue_review_decision_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
package = build_candidate_queue_review_decision_writer_run_package(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_drill=drill,
|
|
)
|
|
payload = json.dumps(package, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert package["mode"] == (
|
|
"candidate_queue_review_decision_writer_run_package_preview"
|
|
)
|
|
assert package["target_table"] == "market_alert_review_queue"
|
|
assert package["target_operation"] == "update_review_state"
|
|
assert package["package_ready"] is False
|
|
assert package["package_artifact_created"] is False
|
|
assert package["ready_for_api_review_state_update"] is False
|
|
assert package["ready_for_api_database_write"] is False
|
|
assert package["ready_for_scheduler_attach"] is False
|
|
assert package["api_writes_file"] is False
|
|
assert package["api_executes_cli"] is False
|
|
assert package["api_reads_approval_token"] is False
|
|
assert package["api_writes_database"] is False
|
|
assert package["api_updates_review_state"] is False
|
|
assert package["review_state_update_executed"] is False
|
|
assert package["database_connection_opened"] is False
|
|
assert package["database_session_created"] is False
|
|
assert package["transaction_opened"] is False
|
|
assert package["transaction_committed"] is False
|
|
assert package["database_write_executed"] is False
|
|
assert package["database_commit_executed"] is False
|
|
assert package["scheduler_attached"] is False
|
|
assert package["payload_manifest"]["payload_count"] == 1
|
|
assert package["payload_manifest"]["payloads"][0]["next_review_state"] == "confirmed"
|
|
assert len(package["required_artifacts"]) == 5
|
|
assert len(package["command_bundle"]) == 5
|
|
assert "backup_artifact_path_recorded" in package["blocked_reasons"]
|
|
assert "one_time_token_supplied_in_shell_only" in package["blocked_reasons"]
|
|
assert "do_not_update_review_state_from_review_state_run_package" in package[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_run_readiness_preview_checks_operator_evidence():
|
|
from services.market_intel.candidate_queue_review_decision_writer_cli import (
|
|
build_candidate_queue_review_decision_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_preflight import (
|
|
build_candidate_queue_review_decision_writer_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
|
|
build_candidate_queue_review_decision_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
|
|
build_candidate_queue_review_decision_writer_operator_drill,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_package import (
|
|
build_candidate_queue_review_decision_writer_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_readiness import (
|
|
build_candidate_queue_review_decision_writer_run_readiness,
|
|
)
|
|
|
|
transaction, operator_evidence = _build_ready_review_decision_transaction()
|
|
operator_evidence = {
|
|
**operator_evidence,
|
|
"operator_confirmed_manual_shell_window": True,
|
|
"operator_confirmed_post_update_inventory_planned": True,
|
|
"operator_drill_notes": "review_state shell drill reviewed",
|
|
}
|
|
writer_status = build_candidate_queue_review_decision_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
preflight = build_candidate_queue_review_decision_writer_preflight(
|
|
writer_status=writer_status,
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
drill = build_candidate_queue_review_decision_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
package = build_candidate_queue_review_decision_writer_run_package(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_drill=drill,
|
|
)
|
|
missing = build_candidate_queue_review_decision_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_drill=drill,
|
|
run_package=package,
|
|
)
|
|
ready = build_candidate_queue_review_decision_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_drill=drill,
|
|
run_package=package,
|
|
operator_evidence={
|
|
"review_state_transaction_json_path": (
|
|
"artifacts/market_intel/review-state-transaction.json"
|
|
),
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": (
|
|
"artifacts/market_intel/review-state-preflight.json"
|
|
),
|
|
"operator_confirmed_review_state_preflight_only": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
},
|
|
)
|
|
token_leak = build_candidate_queue_review_decision_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_drill=drill,
|
|
run_package=package,
|
|
operator_evidence={
|
|
"review_state_transaction_json_path": (
|
|
"artifacts/market_intel/review-state-transaction.json"
|
|
),
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": (
|
|
"artifacts/market_intel/review-state-preflight.json"
|
|
),
|
|
"operator_confirmed_review_state_preflight_only": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
|
|
assert missing["mode"] == (
|
|
"candidate_queue_review_decision_writer_run_readiness_preview"
|
|
)
|
|
assert missing["target_table"] == "market_alert_review_queue"
|
|
assert missing["target_operation"] == "update_review_state"
|
|
assert missing["ready_for_cli_operator_run"] is False
|
|
assert missing["ready_for_api_review_state_update"] is False
|
|
assert missing["ready_for_api_database_write"] is False
|
|
assert missing["ready_for_scheduler_attach"] is False
|
|
assert missing["api_executes_cli"] is False
|
|
assert missing["api_reads_approval_token"] is False
|
|
assert missing["api_writes_file"] is False
|
|
assert missing["api_updates_review_state"] is False
|
|
assert missing["review_state_update_executed"] is False
|
|
assert missing["database_connection_opened"] is False
|
|
assert missing["database_write_executed"] is False
|
|
assert missing["database_commit_executed"] is False
|
|
assert missing["scheduler_attached"] is False
|
|
assert "review_state_transaction_json_path_recorded" in missing[
|
|
"blocked_reasons"
|
|
]
|
|
assert "operator_acknowledged_shell_only_token" in missing["blocked_reasons"]
|
|
assert ready["ready_for_cli_operator_run"] is True
|
|
assert ready["ready_for_api_review_state_update"] is False
|
|
assert ready["database_write_executed"] is False
|
|
assert ready["run_package_summary"]["package_ready"] is False
|
|
assert ready["run_package_summary"]["payload_count"] == 1
|
|
assert ready["operator_evidence_summary"]["artifact_path_count"] == 3
|
|
assert token_leak["ready_for_cli_operator_run"] is False
|
|
assert token_leak["operator_evidence_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "approval_token_not_submitted_to_api" in token_leak["blocked_reasons"]
|
|
assert "do_not_update_review_state_from_review_state_run_readiness" in ready[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_run_receipt_preview_reviews_operator_artifacts():
|
|
from services.market_intel.candidate_queue_review_decision_writer_cli import (
|
|
build_candidate_queue_review_decision_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_preflight import (
|
|
build_candidate_queue_review_decision_writer_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_postwrite_smoke import (
|
|
build_candidate_queue_review_decision_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_operator_drill import (
|
|
build_candidate_queue_review_decision_writer_operator_drill,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_package import (
|
|
build_candidate_queue_review_decision_writer_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_readiness import (
|
|
build_candidate_queue_review_decision_writer_run_readiness,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_receipt import (
|
|
build_candidate_queue_review_decision_writer_run_receipt,
|
|
)
|
|
|
|
transaction, operator_evidence = _build_ready_review_decision_transaction()
|
|
expected_key = transaction["statements"][0]["lookup"]["dedupe_key"]
|
|
operator_evidence = {
|
|
**operator_evidence,
|
|
"operator_confirmed_manual_shell_window": True,
|
|
"operator_confirmed_post_update_inventory_planned": True,
|
|
"operator_drill_notes": "review_state shell drill reviewed",
|
|
}
|
|
writer_status = build_candidate_queue_review_decision_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
preflight = build_candidate_queue_review_decision_writer_preflight(
|
|
writer_status=writer_status,
|
|
transaction_preview=transaction,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
smoke = build_candidate_queue_review_decision_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
drill = build_candidate_queue_review_decision_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
package = build_candidate_queue_review_decision_writer_run_package(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_drill=drill,
|
|
)
|
|
receipt_evidence = {
|
|
**operator_evidence,
|
|
"review_state_transaction_json_path": (
|
|
"artifacts/market_intel/review-state-transaction.json"
|
|
),
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": (
|
|
"artifacts/market_intel/review-state-preflight.json"
|
|
),
|
|
"operator_confirmed_review_state_preflight_only": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
"review_state_writer_output_json_path": (
|
|
"artifacts/market_intel/review-state-writer-output.json"
|
|
),
|
|
"review_state_postwrite_smoke_json_path": (
|
|
"artifacts/market_intel/review-state-postwrite-smoke.json"
|
|
),
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
"receipt_notes": "review_state receipt reviewed",
|
|
}
|
|
readiness = build_candidate_queue_review_decision_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=smoke,
|
|
operator_drill=drill,
|
|
run_package=package,
|
|
operator_evidence=receipt_evidence,
|
|
)
|
|
writer_output = {
|
|
"mode": "candidate_queue_review_decision_writer_cli_executed",
|
|
"exit_code": 0,
|
|
"approval_token_present": True,
|
|
"approval_token_valid": True,
|
|
"approval_token_secret_configured": True,
|
|
"approval_env_var": "MARKET_INTEL_QUEUE_WRITE_APPROVAL",
|
|
"writes_executed": True,
|
|
"would_write_database": True,
|
|
"database_connection_opened": True,
|
|
"explicit_transaction_opened": True,
|
|
"database_write_executed": True,
|
|
"database_commit_executed": True,
|
|
"database_rollback_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"api_updates_review_state": False,
|
|
"review_state_update_executed": True,
|
|
"updated_count": 1,
|
|
"skipped_count": 0,
|
|
"affected_dedupe_keys": [expected_key],
|
|
"skipped_dedupe_keys": [],
|
|
}
|
|
postwrite_smoke_result = {
|
|
"mode": "candidate_queue_review_decision_writer_postwrite_smoke_read_only",
|
|
"postwrite_smoke_passed": True,
|
|
"review_state_update_verified": True,
|
|
"ready_for_operator_review": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"expected_dedupe_key_count": 1,
|
|
"found_count": 1,
|
|
"missing_count": 0,
|
|
"state_mismatch_count": 0,
|
|
"found_dedupe_keys": [expected_key],
|
|
"missing_dedupe_keys": [],
|
|
"state_mismatches": [],
|
|
}
|
|
receipt = build_candidate_queue_review_decision_writer_run_receipt(
|
|
transaction_preview=transaction,
|
|
run_readiness=readiness,
|
|
writer_output=writer_output,
|
|
postwrite_smoke_result=postwrite_smoke_result,
|
|
operator_evidence=receipt_evidence,
|
|
)
|
|
token_leak = build_candidate_queue_review_decision_writer_run_receipt(
|
|
transaction_preview=transaction,
|
|
run_readiness=readiness,
|
|
writer_output={**writer_output, "approval_token": TEST_APPROVAL_TOKEN},
|
|
postwrite_smoke_result=postwrite_smoke_result,
|
|
operator_evidence=receipt_evidence,
|
|
)
|
|
|
|
assert receipt["mode"] == (
|
|
"candidate_queue_review_decision_writer_run_receipt_preview"
|
|
)
|
|
assert receipt["target_operation"] == "update_review_state"
|
|
assert receipt["receipt_passed"] is True
|
|
assert receipt["ready_for_next_manual_phase"] is True
|
|
assert receipt["ready_for_api_review_state_update"] is False
|
|
assert receipt["ready_for_api_database_write"] is False
|
|
assert receipt["ready_for_scheduler_attach"] is False
|
|
assert receipt["api_executes_cli"] is False
|
|
assert receipt["api_reads_approval_token"] is False
|
|
assert receipt["api_writes_file"] is False
|
|
assert receipt["api_updates_review_state"] is False
|
|
assert receipt["review_state_update_executed"] is False
|
|
assert receipt["database_connection_opened"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["database_commit_executed"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert receipt["writer_output_summary"]["review_state_update_executed"] is True
|
|
assert receipt["writer_output_summary"]["dedupe_keys_match_expected"] is True
|
|
assert receipt["postwrite_smoke_summary"]["dedupe_keys_match_expected"] is True
|
|
assert receipt["postwrite_smoke_summary"]["review_state_update_verified"] is True
|
|
assert receipt["operator_evidence_summary"][
|
|
"writer_output_json_path_recorded"
|
|
] is True
|
|
assert receipt["blocked_reasons"] == []
|
|
assert token_leak["receipt_passed"] is False
|
|
assert token_leak["writer_output_summary"]["approval_token_key_detected"] is True
|
|
assert "writer_output_no_approval_token_key" in token_leak["blocked_reasons"]
|
|
assert "do_not_update_review_state_from_review_state_receipt" in receipt[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_run_closeout_preview_blocks_api_write_and_tokens():
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
|
|
build_candidate_queue_review_decision_writer_run_closeout,
|
|
)
|
|
|
|
fixture = _build_review_decision_writer_receipt_fixture(
|
|
"sample-batch-review-state-closeout"
|
|
)
|
|
closeout_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"review_state_closeout_artifact_path": (
|
|
"artifacts/market_intel/review-state-closeout.json"
|
|
),
|
|
"operator_confirmed_review_state_closeout_next": True,
|
|
"operator_confirmed_post_closeout_inventory_read_only": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"closeout_notes": "review_state closeout reviewed",
|
|
}
|
|
closeout = build_candidate_queue_review_decision_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
operator_evidence=closeout_evidence,
|
|
)
|
|
token_leak = build_candidate_queue_review_decision_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
operator_evidence={
|
|
**closeout_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
|
|
assert closeout["mode"] == (
|
|
"candidate_queue_review_decision_writer_run_closeout_preview"
|
|
)
|
|
assert closeout["target_operation"] == "update_review_state"
|
|
assert closeout["closeout_passed"] is True
|
|
assert closeout["ready_for_next_manual_phase"] is True
|
|
assert closeout["ready_for_review_inventory"] is True
|
|
assert closeout["ready_for_api_review_state_update"] is False
|
|
assert closeout["ready_for_api_database_write"] is False
|
|
assert closeout["ready_for_scheduler_attach"] is False
|
|
assert closeout["api_executes_cli"] is False
|
|
assert closeout["api_reads_approval_token"] is False
|
|
assert closeout["api_writes_file"] is False
|
|
assert closeout["api_writes_database"] is False
|
|
assert closeout["api_updates_review_state"] is False
|
|
assert closeout["review_state_update_executed"] is False
|
|
assert closeout["database_connection_opened"] is False
|
|
assert closeout["database_write_executed"] is False
|
|
assert closeout["database_commit_executed"] is False
|
|
assert closeout["scheduler_attached"] is False
|
|
assert closeout["blocked_reasons"] == []
|
|
assert closeout["receipt_summary"]["target_operation"] == "update_review_state"
|
|
assert closeout["receipt_summary"]["receipt_passed"] is True
|
|
assert closeout["receipt_summary"]["safe_boundaries_complete"] is True
|
|
assert closeout["operator_closeout_summary"][
|
|
"closeout_artifact_path_recorded"
|
|
] is True
|
|
assert closeout["promotion_gate"]["requires_real_db_write"] is False
|
|
assert "do_not_update_review_state_from_review_state_closeout" in closeout[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["closeout_passed"] is False
|
|
assert token_leak["operator_closeout_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "closeout_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_decision_post_closeout_inventory_is_read_only():
|
|
from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
|
|
build_candidate_queue_review_decision_post_closeout_inventory,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
|
|
build_candidate_queue_review_decision_writer_run_closeout,
|
|
)
|
|
|
|
fixture = _build_review_decision_writer_receipt_fixture(
|
|
"sample-batch-review-state-post-closeout"
|
|
)
|
|
closeout_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"review_state_closeout_artifact_path": (
|
|
"artifacts/market_intel/review-state-closeout.json"
|
|
),
|
|
"operator_confirmed_review_state_closeout_next": True,
|
|
"operator_confirmed_post_closeout_inventory_read_only": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"closeout_notes": "review_state closeout reviewed",
|
|
}
|
|
closeout = build_candidate_queue_review_decision_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
operator_evidence=closeout_evidence,
|
|
)
|
|
live_inventory = {
|
|
"mode": "live_db_inventory_loaded",
|
|
"summary_ready": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"migration_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"total_rows": 1,
|
|
"table_statuses": [
|
|
{
|
|
"table": "market_alert_review_queue",
|
|
"exists": True,
|
|
"row_count": 1,
|
|
"status": "loaded",
|
|
}
|
|
],
|
|
"alert_review_state_breakdown": [
|
|
{
|
|
"review_state": "confirmed",
|
|
"priority_lane": "watch",
|
|
"alert_count": 1,
|
|
}
|
|
],
|
|
}
|
|
inventory = build_candidate_queue_review_decision_post_closeout_inventory(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
postwrite_smoke=fixture["postwrite_smoke_result"],
|
|
live_db_inventory=live_inventory,
|
|
operator_evidence=closeout_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_decision_post_closeout_inventory(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
postwrite_smoke=fixture["postwrite_smoke_result"],
|
|
live_db_inventory=live_inventory,
|
|
operator_evidence={
|
|
**closeout_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert inventory["mode"] == (
|
|
"candidate_queue_review_decision_post_closeout_inventory_preview"
|
|
)
|
|
assert inventory["target_operation"] == "verify_review_state_after_closeout"
|
|
assert inventory["post_closeout_inventory_ready"] is True
|
|
assert inventory["ready_for_review_completion_archive"] is True
|
|
assert inventory["ready_for_api_review_state_update"] is False
|
|
assert inventory["ready_for_api_database_write"] is False
|
|
assert inventory["ready_for_scheduler_attach"] is False
|
|
assert inventory["api_executes_cli"] is False
|
|
assert inventory["api_reads_approval_token"] is False
|
|
assert inventory["api_writes_database"] is False
|
|
assert inventory["api_updates_review_state"] is False
|
|
assert inventory["review_state_update_executed"] is False
|
|
assert inventory["database_write_executed"] is False
|
|
assert inventory["database_commit_executed"] is False
|
|
assert inventory["scheduler_attached"] is False
|
|
assert inventory["read_only_query_executed"] is True
|
|
assert inventory["expected_dedupe_keys"] == fixture["receipt"][
|
|
"expected_dedupe_keys"
|
|
]
|
|
assert inventory["found_dedupe_keys"] == fixture["receipt"][
|
|
"expected_dedupe_keys"
|
|
]
|
|
assert inventory["state_mismatches"] == []
|
|
assert inventory["alert_review_queue_table"]["exists"] is True
|
|
assert inventory["blocked_reasons"] == []
|
|
assert "post_closeout_inventory_read_only" in inventory["safe_boundaries"]
|
|
assert token_leak["post_closeout_inventory_ready"] is False
|
|
assert token_leak["operator_inventory_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "post_closeout_inventory_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_completion_archive_is_preview_only():
|
|
from services.market_intel.candidate_queue_review_completion_archive import (
|
|
build_candidate_queue_review_completion_archive,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
|
|
build_candidate_queue_review_decision_post_closeout_inventory,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
|
|
build_candidate_queue_review_decision_writer_run_closeout,
|
|
)
|
|
|
|
fixture = _build_review_decision_writer_receipt_fixture(
|
|
"sample-batch-review-completion-archive"
|
|
)
|
|
archive_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"review_state_receipt_artifact_path": (
|
|
"artifacts/market_intel/review-state-receipt.json"
|
|
),
|
|
"review_state_closeout_artifact_path": (
|
|
"artifacts/market_intel/review-state-closeout.json"
|
|
),
|
|
"post_closeout_inventory_artifact_path": (
|
|
"artifacts/market_intel/post-closeout-inventory.json"
|
|
),
|
|
"review_completion_archive_path": (
|
|
"artifacts/market_intel/review-completion-archive.json"
|
|
),
|
|
"operator_confirmed_review_state_closeout_next": True,
|
|
"operator_confirmed_post_closeout_inventory_read_only": True,
|
|
"operator_confirmed_review_completion_archive": True,
|
|
"operator_confirmed_archive_is_read_only": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
}
|
|
closeout = build_candidate_queue_review_decision_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
operator_evidence=archive_evidence,
|
|
)
|
|
live_inventory = {
|
|
"mode": "live_db_inventory_loaded",
|
|
"summary_ready": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"migration_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"total_rows": 1,
|
|
"table_statuses": [
|
|
{
|
|
"table": "market_alert_review_queue",
|
|
"exists": True,
|
|
"row_count": 1,
|
|
"status": "loaded",
|
|
}
|
|
],
|
|
}
|
|
inventory = build_candidate_queue_review_decision_post_closeout_inventory(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
postwrite_smoke=fixture["postwrite_smoke_result"],
|
|
live_db_inventory=live_inventory,
|
|
operator_evidence=archive_evidence,
|
|
execute_requested=True,
|
|
)
|
|
archive = build_candidate_queue_review_completion_archive(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
run_closeout=closeout,
|
|
post_closeout_inventory=inventory,
|
|
operator_evidence=archive_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_completion_archive(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
run_closeout=closeout,
|
|
post_closeout_inventory=inventory,
|
|
operator_evidence={
|
|
**archive_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert archive["mode"] == "candidate_queue_review_completion_archive_preview"
|
|
assert archive["target_operation"] == "archive_review_completion_evidence"
|
|
assert archive["review_completion_archive_ready"] is True
|
|
assert archive["archive_manifest_ready"] is True
|
|
assert archive["ready_for_api_review_state_update"] is False
|
|
assert archive["ready_for_api_database_write"] is False
|
|
assert archive["ready_for_scheduler_attach"] is False
|
|
assert archive["api_writes_file"] is False
|
|
assert archive["api_executes_cli"] is False
|
|
assert archive["api_reads_approval_token"] is False
|
|
assert archive["api_writes_database"] is False
|
|
assert archive["api_updates_review_state"] is False
|
|
assert archive["archive_file_written"] is False
|
|
assert archive["archive_record_written"] is False
|
|
assert archive["archive_manifest_written"] is False
|
|
assert archive["review_state_update_executed"] is False
|
|
assert archive["database_write_executed"] is False
|
|
assert archive["database_commit_executed"] is False
|
|
assert archive["scheduler_attached"] is False
|
|
assert archive["expected_dedupe_keys"] == fixture["receipt"][
|
|
"expected_dedupe_keys"
|
|
]
|
|
assert archive["found_dedupe_keys"] == fixture["receipt"][
|
|
"expected_dedupe_keys"
|
|
]
|
|
assert archive["row_summary_count"] == 1
|
|
assert archive["blocked_reasons"] == []
|
|
assert "review_completion_archive_preview_only" in archive["safe_boundaries"]
|
|
assert token_leak["review_completion_archive_ready"] is False
|
|
assert token_leak["operator_archive_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "archive_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_archive_summary_blocks_llm_and_writes():
|
|
from services.market_intel.candidate_queue_review_archive_summary import (
|
|
build_candidate_queue_review_archive_summary,
|
|
)
|
|
from services.market_intel.candidate_queue_review_completion_archive import (
|
|
build_candidate_queue_review_completion_archive,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
|
|
build_candidate_queue_review_decision_post_closeout_inventory,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
|
|
build_candidate_queue_review_decision_writer_run_closeout,
|
|
)
|
|
|
|
fixture = _build_review_decision_writer_receipt_fixture(
|
|
"sample-batch-review-archive-summary"
|
|
)
|
|
summary_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"review_state_receipt_artifact_path": (
|
|
"artifacts/market_intel/review-state-receipt.json"
|
|
),
|
|
"review_state_closeout_artifact_path": (
|
|
"artifacts/market_intel/review-state-closeout.json"
|
|
),
|
|
"post_closeout_inventory_artifact_path": (
|
|
"artifacts/market_intel/post-closeout-inventory.json"
|
|
),
|
|
"review_completion_archive_path": (
|
|
"artifacts/market_intel/review-completion-archive.json"
|
|
),
|
|
"archive_summary_artifact_path": (
|
|
"artifacts/market_intel/review-archive-summary.json"
|
|
),
|
|
"operator_confirmed_review_state_closeout_next": True,
|
|
"operator_confirmed_post_closeout_inventory_read_only": True,
|
|
"operator_confirmed_review_completion_archive": True,
|
|
"operator_confirmed_archive_is_read_only": True,
|
|
"operator_confirmed_ai_summary_review": True,
|
|
"operator_confirmed_summary_is_read_only": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
}
|
|
closeout = build_candidate_queue_review_decision_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
operator_evidence=summary_evidence,
|
|
)
|
|
inventory = build_candidate_queue_review_decision_post_closeout_inventory(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
postwrite_smoke=fixture["postwrite_smoke_result"],
|
|
live_db_inventory={
|
|
"mode": "live_db_inventory_loaded",
|
|
"summary_ready": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"migration_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"table_statuses": [
|
|
{
|
|
"table": "market_alert_review_queue",
|
|
"exists": True,
|
|
"row_count": 1,
|
|
"status": "loaded",
|
|
}
|
|
],
|
|
},
|
|
operator_evidence=summary_evidence,
|
|
execute_requested=True,
|
|
)
|
|
archive = build_candidate_queue_review_completion_archive(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
run_closeout=closeout,
|
|
post_closeout_inventory=inventory,
|
|
operator_evidence=summary_evidence,
|
|
execute_requested=True,
|
|
)
|
|
summary = build_candidate_queue_review_archive_summary(
|
|
review_completion_archive=archive,
|
|
operator_evidence=summary_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_archive_summary(
|
|
review_completion_archive=archive,
|
|
operator_evidence={
|
|
**summary_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert summary["mode"] == "candidate_queue_review_archive_summary_preview"
|
|
assert summary["target_operation"] == "prepare_archive_summary_input"
|
|
assert summary["archive_summary_ready"] is True
|
|
assert summary["summary_input_ready"] is True
|
|
assert summary["ready_for_ai_summary_review"] is True
|
|
assert summary["ready_for_ai_summary_generation"] is False
|
|
assert summary["ready_for_llm_call"] is False
|
|
assert summary["ready_for_telegram_dispatch"] is False
|
|
assert summary["ai_summary_generated"] is False
|
|
assert summary["llm_call_executed"] is False
|
|
assert summary["ollama_call_executed"] is False
|
|
assert summary["gemini_call_executed"] is False
|
|
assert summary["telegram_dispatched"] is False
|
|
assert summary["summary_file_written"] is False
|
|
assert summary["summary_record_written"] is False
|
|
assert summary["summary_manifest_written"] is False
|
|
assert summary["database_write_executed"] is False
|
|
assert summary["database_commit_executed"] is False
|
|
assert summary["review_state_update_executed"] is False
|
|
assert summary["scheduler_attached"] is False
|
|
assert summary["expected_dedupe_keys"] == fixture["receipt"][
|
|
"expected_dedupe_keys"
|
|
]
|
|
assert summary["summary_sections"]
|
|
assert summary["blocked_reasons"] == []
|
|
assert "do_not_call_llm_from_archive_summary_gate" in summary[
|
|
"safe_boundaries"
|
|
]
|
|
assert "ollama_first_only_for_future_llm_summary" in summary[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["archive_summary_ready"] is False
|
|
assert token_leak["operator_summary_review"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "archive_summary_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_preflight_is_ollama_first_preview():
|
|
from services.market_intel.candidate_queue_review_ai_summary_preflight import (
|
|
build_candidate_queue_review_ai_summary_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_review_archive_summary import (
|
|
build_candidate_queue_review_archive_summary,
|
|
)
|
|
from services.market_intel.candidate_queue_review_completion_archive import (
|
|
build_candidate_queue_review_completion_archive,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
|
|
build_candidate_queue_review_decision_post_closeout_inventory,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
|
|
build_candidate_queue_review_decision_writer_run_closeout,
|
|
)
|
|
|
|
fixture = _build_review_decision_writer_receipt_fixture(
|
|
"sample-batch-review-ai-summary-preflight"
|
|
)
|
|
preflight_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"review_state_receipt_artifact_path": (
|
|
"artifacts/market_intel/review-state-receipt.json"
|
|
),
|
|
"review_state_closeout_artifact_path": (
|
|
"artifacts/market_intel/review-state-closeout.json"
|
|
),
|
|
"post_closeout_inventory_artifact_path": (
|
|
"artifacts/market_intel/post-closeout-inventory.json"
|
|
),
|
|
"review_completion_archive_path": (
|
|
"artifacts/market_intel/review-completion-archive.json"
|
|
),
|
|
"archive_summary_artifact_path": (
|
|
"artifacts/market_intel/review-archive-summary.json"
|
|
),
|
|
"ai_summary_preflight_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-preflight.json"
|
|
),
|
|
"operator_confirmed_review_state_closeout_next": True,
|
|
"operator_confirmed_post_closeout_inventory_read_only": True,
|
|
"operator_confirmed_review_completion_archive": True,
|
|
"operator_confirmed_archive_is_read_only": True,
|
|
"operator_confirmed_ai_summary_review": True,
|
|
"operator_confirmed_summary_is_read_only": True,
|
|
"operator_confirmed_ai_summary_preflight": True,
|
|
"operator_confirmed_ollama_first": True,
|
|
"operator_confirmed_gemini_backup_only": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
}
|
|
closeout = build_candidate_queue_review_decision_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
operator_evidence=preflight_evidence,
|
|
)
|
|
inventory = build_candidate_queue_review_decision_post_closeout_inventory(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
postwrite_smoke=fixture["postwrite_smoke_result"],
|
|
live_db_inventory={
|
|
"mode": "live_db_inventory_loaded",
|
|
"summary_ready": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"migration_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"table_statuses": [
|
|
{
|
|
"table": "market_alert_review_queue",
|
|
"exists": True,
|
|
"row_count": 1,
|
|
"status": "loaded",
|
|
}
|
|
],
|
|
},
|
|
operator_evidence=preflight_evidence,
|
|
execute_requested=True,
|
|
)
|
|
archive = build_candidate_queue_review_completion_archive(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
run_closeout=closeout,
|
|
post_closeout_inventory=inventory,
|
|
operator_evidence=preflight_evidence,
|
|
execute_requested=True,
|
|
)
|
|
archive_summary = build_candidate_queue_review_archive_summary(
|
|
review_completion_archive=archive,
|
|
operator_evidence=preflight_evidence,
|
|
execute_requested=True,
|
|
)
|
|
preflight = build_candidate_queue_review_ai_summary_preflight(
|
|
archive_summary=archive_summary,
|
|
operator_evidence=preflight_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_preflight(
|
|
archive_summary=archive_summary,
|
|
operator_evidence={
|
|
**preflight_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert preflight["mode"] == "candidate_queue_review_ai_summary_preflight_preview"
|
|
assert preflight["target_operation"] == "preflight_ollama_first_ai_summary"
|
|
assert preflight["ai_summary_preflight_ready"] is True
|
|
assert preflight["ready_for_manual_ollama_summary_run"] is True
|
|
assert preflight["ready_for_ai_summary_generation"] is False
|
|
assert preflight["ready_for_llm_call"] is False
|
|
assert preflight["ready_for_telegram_dispatch"] is False
|
|
assert preflight["api_reads_approval_token"] is False
|
|
assert preflight["api_writes_file"] is False
|
|
assert preflight["api_writes_database"] is False
|
|
assert preflight["api_updates_review_state"] is False
|
|
assert preflight["summary_file_written"] is False
|
|
assert preflight["summary_record_written"] is False
|
|
assert preflight["summary_manifest_written"] is False
|
|
assert preflight["ai_summary_generated"] is False
|
|
assert preflight["llm_call_executed"] is False
|
|
assert preflight["ollama_call_executed"] is False
|
|
assert preflight["gemini_call_executed"] is False
|
|
assert preflight["telegram_dispatched"] is False
|
|
assert preflight["database_write_executed"] is False
|
|
assert preflight["database_commit_executed"] is False
|
|
assert preflight["scheduler_attached"] is False
|
|
assert preflight["blocked_reasons"] == []
|
|
assert preflight["model_route_policy"]["primary_policy"] == "ollama_first"
|
|
assert len(preflight["model_route_policy"]["primary_cascade"]) == 3
|
|
assert (
|
|
preflight["model_route_policy"]["fallback_policy"]
|
|
== "gemini_backup_only_after_ollama_cascade_failure"
|
|
)
|
|
assert (
|
|
preflight["model_route_policy"]["app_host_forbidden_as_ollama_node"]
|
|
== "192.168.0.188"
|
|
)
|
|
assert "ollama_cascade_must_use_gcp_a_then_gcp_b_then_111" in preflight[
|
|
"safe_boundaries"
|
|
]
|
|
assert "host_188_forbidden_as_ollama_node" in preflight["safe_boundaries"]
|
|
assert "do_not_call_llm_from_ai_summary_preflight" in preflight[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["ai_summary_preflight_ready"] is False
|
|
assert token_leak["operator_ai_summary_preflight"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "ai_summary_preflight_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_run_package_is_manual_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_preflight import (
|
|
build_candidate_queue_review_ai_summary_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_review_ai_summary_run_package import (
|
|
build_candidate_queue_review_ai_summary_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_review_archive_summary import (
|
|
build_candidate_queue_review_archive_summary,
|
|
)
|
|
from services.market_intel.candidate_queue_review_completion_archive import (
|
|
build_candidate_queue_review_completion_archive,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
|
|
build_candidate_queue_review_decision_post_closeout_inventory,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
|
|
build_candidate_queue_review_decision_writer_run_closeout,
|
|
)
|
|
|
|
fixture = _build_review_decision_writer_receipt_fixture(
|
|
"sample-batch-review-ai-summary-run-package"
|
|
)
|
|
run_package_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"review_state_receipt_artifact_path": (
|
|
"artifacts/market_intel/review-state-receipt.json"
|
|
),
|
|
"review_state_closeout_artifact_path": (
|
|
"artifacts/market_intel/review-state-closeout.json"
|
|
),
|
|
"post_closeout_inventory_artifact_path": (
|
|
"artifacts/market_intel/post-closeout-inventory.json"
|
|
),
|
|
"review_completion_archive_path": (
|
|
"artifacts/market_intel/review-completion-archive.json"
|
|
),
|
|
"archive_summary_artifact_path": (
|
|
"artifacts/market_intel/review-archive-summary.json"
|
|
),
|
|
"ai_summary_preflight_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-preflight.json"
|
|
),
|
|
"ai_summary_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-run-package.json"
|
|
),
|
|
"ai_summary_output_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-output.json"
|
|
),
|
|
"operator_confirmed_review_state_closeout_next": True,
|
|
"operator_confirmed_post_closeout_inventory_read_only": True,
|
|
"operator_confirmed_review_completion_archive": True,
|
|
"operator_confirmed_archive_is_read_only": True,
|
|
"operator_confirmed_ai_summary_review": True,
|
|
"operator_confirmed_summary_is_read_only": True,
|
|
"operator_confirmed_ai_summary_preflight": True,
|
|
"operator_confirmed_ai_summary_run_package": True,
|
|
"operator_confirmed_ollama_first": True,
|
|
"operator_confirmed_gemini_backup_only": True,
|
|
"operator_confirmed_manual_llm_only": True,
|
|
"operator_confirmed_no_api_llm_call": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
}
|
|
closeout = build_candidate_queue_review_decision_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
operator_evidence=run_package_evidence,
|
|
)
|
|
inventory = build_candidate_queue_review_decision_post_closeout_inventory(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
postwrite_smoke=fixture["postwrite_smoke_result"],
|
|
live_db_inventory={
|
|
"mode": "live_db_inventory_loaded",
|
|
"summary_ready": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"migration_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"table_statuses": [
|
|
{
|
|
"table": "market_alert_review_queue",
|
|
"exists": True,
|
|
"row_count": 1,
|
|
"status": "loaded",
|
|
}
|
|
],
|
|
},
|
|
operator_evidence=run_package_evidence,
|
|
execute_requested=True,
|
|
)
|
|
archive = build_candidate_queue_review_completion_archive(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
run_closeout=closeout,
|
|
post_closeout_inventory=inventory,
|
|
operator_evidence=run_package_evidence,
|
|
execute_requested=True,
|
|
)
|
|
archive_summary = build_candidate_queue_review_archive_summary(
|
|
review_completion_archive=archive,
|
|
operator_evidence=run_package_evidence,
|
|
execute_requested=True,
|
|
)
|
|
preflight = build_candidate_queue_review_ai_summary_preflight(
|
|
archive_summary=archive_summary,
|
|
operator_evidence=run_package_evidence,
|
|
execute_requested=True,
|
|
)
|
|
run_package = build_candidate_queue_review_ai_summary_run_package(
|
|
archive_summary=archive_summary,
|
|
ai_summary_preflight=preflight,
|
|
operator_evidence=run_package_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_run_package(
|
|
archive_summary=archive_summary,
|
|
ai_summary_preflight=preflight,
|
|
operator_evidence={
|
|
**run_package_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert run_package["mode"] == "candidate_queue_review_ai_summary_run_package_preview"
|
|
assert (
|
|
run_package["target_operation"]
|
|
== "package_ollama_first_ai_summary_manual_run"
|
|
)
|
|
assert run_package["ai_summary_run_package_ready"] is True
|
|
assert run_package["ready_for_manual_ollama_summary_run"] is True
|
|
assert run_package["ready_for_ai_summary_generation"] is False
|
|
assert run_package["ready_for_llm_call"] is False
|
|
assert run_package["ready_for_telegram_dispatch"] is False
|
|
assert run_package["api_executes_llm"] is False
|
|
assert run_package["api_reads_approval_token"] is False
|
|
assert run_package["api_writes_file"] is False
|
|
assert run_package["api_writes_database"] is False
|
|
assert run_package["api_updates_review_state"] is False
|
|
assert run_package["run_package_file_written"] is False
|
|
assert run_package["summary_file_written"] is False
|
|
assert run_package["summary_record_written"] is False
|
|
assert run_package["summary_manifest_written"] is False
|
|
assert run_package["ai_summary_generated"] is False
|
|
assert run_package["llm_call_executed"] is False
|
|
assert run_package["ollama_call_executed"] is False
|
|
assert run_package["gemini_call_executed"] is False
|
|
assert run_package["telegram_dispatched"] is False
|
|
assert run_package["database_write_executed"] is False
|
|
assert run_package["database_commit_executed"] is False
|
|
assert run_package["scheduler_attached"] is False
|
|
assert run_package["blocked_reasons"] == []
|
|
assert run_package["prompt_contract"]["contract_version"] == (
|
|
"market_intel_ai_summary_prompt_v1"
|
|
)
|
|
assert run_package["summary_output_schema"]["schema_version"] == (
|
|
"market_intel_ai_summary_v1"
|
|
)
|
|
assert "evidence_refs" in run_package["summary_output_schema"][
|
|
"required_fields"
|
|
]
|
|
assert run_package["model_route_policy"]["primary_policy"] == "ollama_first"
|
|
assert "manual_ollama_summary_run_only" in run_package["safe_boundaries"]
|
|
assert "do_not_call_llm_from_ai_summary_run_package" in run_package[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["ai_summary_run_package_ready"] is False
|
|
assert token_leak["operator_ai_summary_run_package"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "ai_summary_run_package_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_output_receipt_validates_manual_output():
|
|
from services.market_intel.candidate_queue_review_ai_summary_output_receipt import (
|
|
build_candidate_queue_review_ai_summary_output_receipt,
|
|
)
|
|
from services.market_intel.candidate_queue_review_ai_summary_preflight import (
|
|
build_candidate_queue_review_ai_summary_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_review_ai_summary_run_package import (
|
|
build_candidate_queue_review_ai_summary_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_review_archive_summary import (
|
|
build_candidate_queue_review_archive_summary,
|
|
)
|
|
from services.market_intel.candidate_queue_review_completion_archive import (
|
|
build_candidate_queue_review_completion_archive,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_post_closeout_inventory import (
|
|
build_candidate_queue_review_decision_post_closeout_inventory,
|
|
)
|
|
from services.market_intel.candidate_queue_review_decision_writer_run_closeout import (
|
|
build_candidate_queue_review_decision_writer_run_closeout,
|
|
)
|
|
|
|
fixture = _build_review_decision_writer_receipt_fixture(
|
|
"sample-batch-review-ai-summary-output-receipt"
|
|
)
|
|
expected_key = fixture["receipt"]["expected_dedupe_keys"][0]
|
|
receipt_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"review_state_receipt_artifact_path": (
|
|
"artifacts/market_intel/review-state-receipt.json"
|
|
),
|
|
"review_state_closeout_artifact_path": (
|
|
"artifacts/market_intel/review-state-closeout.json"
|
|
),
|
|
"post_closeout_inventory_artifact_path": (
|
|
"artifacts/market_intel/post-closeout-inventory.json"
|
|
),
|
|
"review_completion_archive_path": (
|
|
"artifacts/market_intel/review-completion-archive.json"
|
|
),
|
|
"archive_summary_artifact_path": (
|
|
"artifacts/market_intel/review-archive-summary.json"
|
|
),
|
|
"ai_summary_preflight_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-preflight.json"
|
|
),
|
|
"ai_summary_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-run-package.json"
|
|
),
|
|
"ai_summary_output_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-output.json"
|
|
),
|
|
"ai_summary_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-output-receipt.json"
|
|
),
|
|
"operator_confirmed_review_state_closeout_next": True,
|
|
"operator_confirmed_post_closeout_inventory_read_only": True,
|
|
"operator_confirmed_review_completion_archive": True,
|
|
"operator_confirmed_archive_is_read_only": True,
|
|
"operator_confirmed_ai_summary_review": True,
|
|
"operator_confirmed_summary_is_read_only": True,
|
|
"operator_confirmed_ai_summary_preflight": True,
|
|
"operator_confirmed_ai_summary_run_package": True,
|
|
"operator_confirmed_ai_summary_output_receipt": True,
|
|
"operator_confirmed_ollama_first": True,
|
|
"operator_confirmed_gemini_backup_only": True,
|
|
"operator_confirmed_manual_llm_only": True,
|
|
"operator_confirmed_manual_output_only": True,
|
|
"operator_confirmed_no_api_llm_call": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"ai_summary_output": {
|
|
"headline": "市場情報人工摘要驗收",
|
|
"executive_summary": "此摘要僅根據 archive summary facts。",
|
|
"key_findings": [
|
|
{
|
|
"text": "review_state 已完成人工驗收",
|
|
"evidence_refs": [expected_key],
|
|
}
|
|
],
|
|
"risk_flags": [],
|
|
"recommended_actions": [
|
|
{
|
|
"text": "進入 summary persistence preflight",
|
|
"evidence_refs": [expected_key, "review_scope"],
|
|
}
|
|
],
|
|
"evidence_refs": [expected_key, "review_scope"],
|
|
"model_route": {
|
|
"provider": "ollama",
|
|
"host": "34.143.170.20:11434",
|
|
"model": "qwen2.5-coder:7b",
|
|
},
|
|
},
|
|
}
|
|
closeout = build_candidate_queue_review_decision_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
operator_evidence=receipt_evidence,
|
|
)
|
|
inventory = build_candidate_queue_review_decision_post_closeout_inventory(
|
|
transaction_preview=fixture["transaction"],
|
|
run_closeout=closeout,
|
|
postwrite_smoke=fixture["postwrite_smoke_result"],
|
|
live_db_inventory={
|
|
"mode": "live_db_inventory_loaded",
|
|
"summary_ready": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"migration_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"table_statuses": [
|
|
{
|
|
"table": "market_alert_review_queue",
|
|
"exists": True,
|
|
"row_count": 1,
|
|
"status": "loaded",
|
|
}
|
|
],
|
|
},
|
|
operator_evidence=receipt_evidence,
|
|
execute_requested=True,
|
|
)
|
|
archive = build_candidate_queue_review_completion_archive(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=fixture["receipt"],
|
|
run_closeout=closeout,
|
|
post_closeout_inventory=inventory,
|
|
operator_evidence=receipt_evidence,
|
|
execute_requested=True,
|
|
)
|
|
archive_summary = build_candidate_queue_review_archive_summary(
|
|
review_completion_archive=archive,
|
|
operator_evidence=receipt_evidence,
|
|
execute_requested=True,
|
|
)
|
|
preflight = build_candidate_queue_review_ai_summary_preflight(
|
|
archive_summary=archive_summary,
|
|
operator_evidence=receipt_evidence,
|
|
execute_requested=True,
|
|
)
|
|
run_package = build_candidate_queue_review_ai_summary_run_package(
|
|
archive_summary=archive_summary,
|
|
ai_summary_preflight=preflight,
|
|
operator_evidence=receipt_evidence,
|
|
execute_requested=True,
|
|
)
|
|
receipt = build_candidate_queue_review_ai_summary_output_receipt(
|
|
ai_summary_run_package=run_package,
|
|
operator_evidence=receipt_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_output_receipt(
|
|
ai_summary_run_package=run_package,
|
|
operator_evidence={
|
|
**receipt_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert receipt["mode"] == "candidate_queue_review_ai_summary_output_receipt_preview"
|
|
assert receipt["target_operation"] == "review_manual_ollama_ai_summary_output"
|
|
assert receipt["ai_summary_output_receipt_ready"] is True
|
|
assert receipt["ready_for_summary_persistence_review"] is True
|
|
assert receipt["manual_ai_summary_output_provided"] is True
|
|
assert receipt["summary_output_schema_valid"] is True
|
|
assert receipt["summary_output_evidence_refs_grounded"] is True
|
|
assert receipt["summary_output_model_route_accepted"] is True
|
|
assert receipt["ready_for_ai_summary_generation"] is False
|
|
assert receipt["ready_for_llm_call"] is False
|
|
assert receipt["ready_for_telegram_dispatch"] is False
|
|
assert receipt["api_executes_llm"] is False
|
|
assert receipt["api_reads_approval_token"] is False
|
|
assert receipt["api_writes_file"] is False
|
|
assert receipt["summary_receipt_file_written"] is False
|
|
assert receipt["summary_file_written"] is False
|
|
assert receipt["summary_record_written"] is False
|
|
assert receipt["ai_summary_generated"] is False
|
|
assert receipt["llm_call_executed"] is False
|
|
assert receipt["ollama_call_executed"] is False
|
|
assert receipt["gemini_call_executed"] is False
|
|
assert receipt["telegram_dispatched"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["database_commit_executed"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert receipt["blocked_reasons"] == []
|
|
assert receipt["summary_output_validation"]["evidence_refs"] == [
|
|
expected_key,
|
|
"review_scope",
|
|
]
|
|
assert "manual_ai_summary_output_only" in receipt["safe_boundaries"]
|
|
assert "do_not_call_llm_from_ai_summary_output_receipt" in receipt[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["ai_summary_output_receipt_ready"] is False
|
|
assert token_leak["operator_ai_summary_output_receipt"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "ai_summary_output_receipt_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_preflight_prepares_metadata_contract():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_preflight import (
|
|
build_candidate_queue_review_ai_summary_persistence_preflight,
|
|
)
|
|
|
|
expected_key = "market-alert-review:sample-batch:sku-001"
|
|
receipt = {
|
|
"mode": "candidate_queue_review_ai_summary_output_receipt_preview",
|
|
"ai_summary_output_receipt_ready": True,
|
|
"ready_for_summary_persistence_review": True,
|
|
"manual_ai_summary_output_provided": True,
|
|
"summary_output_schema_valid": True,
|
|
"summary_output_evidence_refs_grounded": True,
|
|
"summary_output_model_route_accepted": True,
|
|
"expected_dedupe_keys": [expected_key],
|
|
"summary_section_keys": ["review_scope"],
|
|
"summary_output_validation": {
|
|
"evidence_refs": [expected_key, "review_scope"],
|
|
},
|
|
"model_route_policy": {"primary_policy": "ollama_first"},
|
|
"llm_call_executed": False,
|
|
"ollama_call_executed": False,
|
|
"gemini_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
}
|
|
operator_evidence = {
|
|
"ai_summary_output_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-output.json"
|
|
),
|
|
"ai_summary_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-output-receipt.json"
|
|
),
|
|
"ai_summary_persistence_preflight_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-preflight.json"
|
|
),
|
|
"operator_confirmed_ai_summary_persistence_preflight": True,
|
|
"operator_confirmed_summary_persistence_is_cli_only": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"ai_summary_output": {
|
|
"headline": "市場情報人工摘要驗收",
|
|
"executive_summary": "此摘要僅根據 archive summary facts。",
|
|
"key_findings": [
|
|
{
|
|
"text": "review_state 已完成人工驗收",
|
|
"evidence_refs": [expected_key],
|
|
}
|
|
],
|
|
"risk_flags": [],
|
|
"recommended_actions": [
|
|
{
|
|
"text": "進入 summary persistence transaction preview",
|
|
"evidence_refs": [expected_key, "review_scope"],
|
|
}
|
|
],
|
|
"evidence_refs": [expected_key, "review_scope"],
|
|
"model_route": {
|
|
"provider": "ollama",
|
|
"host": "34.143.170.20:11434",
|
|
"model": "qwen2.5-coder:7b",
|
|
},
|
|
},
|
|
}
|
|
preflight = build_candidate_queue_review_ai_summary_persistence_preflight(
|
|
ai_summary_output_receipt=receipt,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_preflight(
|
|
ai_summary_output_receipt=receipt,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert preflight["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_preflight_preview"
|
|
)
|
|
assert preflight["target_table"] == "market_alert_review_queue"
|
|
assert preflight["target_operation"] == "preflight_ai_summary_metadata_persistence"
|
|
assert preflight["summary_persistence_preflight_ready"] is True
|
|
assert preflight["ready_for_summary_transaction_preview"] is True
|
|
assert preflight["ready_for_summary_persistence_cli_run"] is False
|
|
assert preflight["ready_for_telegram_dispatch"] is False
|
|
assert preflight["ready_for_api_database_write"] is False
|
|
assert preflight["api_executes_llm"] is False
|
|
assert preflight["api_reads_approval_token"] is False
|
|
assert preflight["api_writes_file"] is False
|
|
assert preflight["api_writes_database"] is False
|
|
assert preflight["api_updates_review_state"] is False
|
|
assert preflight["summary_persistence_preflight_file_written"] is False
|
|
assert preflight["summary_record_written"] is False
|
|
assert preflight["summary_persistence_record_written"] is False
|
|
assert preflight["metadata_patch_written"] is False
|
|
assert preflight["llm_call_executed"] is False
|
|
assert preflight["ollama_call_executed"] is False
|
|
assert preflight["gemini_call_executed"] is False
|
|
assert preflight["telegram_dispatched"] is False
|
|
assert preflight["database_connection_opened"] is False
|
|
assert preflight["database_write_executed"] is False
|
|
assert preflight["database_commit_executed"] is False
|
|
assert preflight["review_state_update_executed"] is False
|
|
assert preflight["scheduler_attached"] is False
|
|
assert preflight["writes_executed"] is False
|
|
assert preflight["would_write_database"] is False
|
|
assert preflight["blocked_reasons"] == []
|
|
assert len(preflight["summary_payload_hash"]) == 64
|
|
assert preflight["summary_persistence_contract"]["target_column"] == "metadata_json"
|
|
assert preflight["summary_persistence_contract"]["target_json_path"] == [
|
|
"ai_summary_review"
|
|
]
|
|
assert preflight["summary_persistence_contract"]["planned_update_count"] == 1
|
|
assert preflight["summary_persistence_contract"]["api_write_allowed"] is False
|
|
assert preflight["summary_record_preview"]["headline"] == "市場情報人工摘要驗收"
|
|
assert preflight["summary_record_preview"]["key_finding_count"] == 1
|
|
assert preflight["summary_record_preview"]["risk_flag_count"] == 0
|
|
assert preflight["metadata_patch_preview"]["statement_preview_created"] is False
|
|
assert preflight["metadata_patch_preview"]["metadata_patch_preview_created"] is True
|
|
assert "future_summary_persistence_must_use_cli_only_gate" in preflight[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["summary_persistence_preflight_ready"] is False
|
|
assert token_leak["operator_ai_summary_persistence_preflight"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert (
|
|
"summary_persistence_preflight_no_approval_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_transaction_previews_update_statements():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_transaction import (
|
|
build_candidate_queue_review_ai_summary_persistence_transaction,
|
|
)
|
|
|
|
expected_key = "market-alert-review:sample-batch:sku-001"
|
|
preflight = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_preflight_preview",
|
|
"summary_persistence_preflight_ready": True,
|
|
"ready_for_summary_transaction_preview": True,
|
|
"expected_dedupe_keys": [expected_key],
|
|
"summary_payload_hash": "f" * 64,
|
|
"summary_persistence_contract": {
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"target_json_path": ["ai_summary_review"],
|
|
"api_write_allowed": False,
|
|
},
|
|
"summary_record_preview": {
|
|
"headline": "市場情報人工摘要驗收",
|
|
"payload_hash": "f" * 64,
|
|
},
|
|
"metadata_patch_preview": {
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"target_json_path": ["ai_summary_review"],
|
|
"statement_preview_created": False,
|
|
"metadata_patch_preview_created": True,
|
|
"api_write_allowed": False,
|
|
},
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
}
|
|
operator_evidence = {
|
|
"ai_summary_output_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-output.json"
|
|
),
|
|
"ai_summary_persistence_preflight_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-preflight.json"
|
|
),
|
|
"ai_summary_persistence_transaction_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-transaction.json"
|
|
),
|
|
"operator_confirmed_ai_summary_persistence_transaction": True,
|
|
"operator_confirmed_metadata_merge_reviewed": True,
|
|
"operator_confirmed_summary_persistence_is_cli_only": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
}
|
|
transaction = build_candidate_queue_review_ai_summary_persistence_transaction(
|
|
ai_summary_persistence_preflight=preflight,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_transaction(
|
|
ai_summary_persistence_preflight=preflight,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
|
|
assert transaction["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_transaction_preview"
|
|
)
|
|
assert transaction["target_operation"] == "update_ai_summary_metadata_json"
|
|
assert transaction["summary_persistence_transaction_ready"] is True
|
|
assert transaction["ready_for_summary_persistence_writer_gate"] is True
|
|
assert transaction["ready_for_summary_persistence_cli_run"] is False
|
|
assert transaction["ready_for_api_database_write"] is False
|
|
assert transaction["ready_for_telegram_dispatch"] is False
|
|
assert transaction["api_executes_cli"] is False
|
|
assert transaction["api_reads_approval_token"] is False
|
|
assert transaction["api_writes_file"] is False
|
|
assert transaction["api_writes_database"] is False
|
|
assert transaction["api_updates_review_state"] is False
|
|
assert transaction["summary_persistence_transaction_file_written"] is False
|
|
assert transaction["summary_persistence_record_written"] is False
|
|
assert transaction["metadata_patch_written"] is False
|
|
assert transaction["transaction_file_written"] is False
|
|
assert transaction["llm_call_executed"] is False
|
|
assert transaction["telegram_dispatched"] is False
|
|
assert transaction["database_connection_opened"] is False
|
|
assert transaction["database_write_executed"] is False
|
|
assert transaction["database_commit_executed"] is False
|
|
assert transaction["review_state_update_executed"] is False
|
|
assert transaction["scheduler_attached"] is False
|
|
assert transaction["writes_executed"] is False
|
|
assert transaction["would_write_database"] is False
|
|
assert transaction["blocked_reasons"] == []
|
|
assert transaction["statement_count"] == 1
|
|
statement = transaction["statements"][0]
|
|
assert statement["table"] == "market_alert_review_queue"
|
|
assert statement["target_column"] == "metadata_json"
|
|
assert statement["where"]["dedupe_key"] == expected_key
|
|
assert statement["parameter_preview"]["payload_hash"] == "f" * 64
|
|
assert statement["execute_in_api"] is False
|
|
assert transaction["transaction_summary"]["api_write_allowed"] is False
|
|
assert transaction["transaction_summary"]["manual_cli_required"] is True
|
|
assert len(transaction["rollback_plan"]) == 3
|
|
assert "future_summary_persistence_write_must_use_cli_only_gate" in transaction[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["summary_persistence_transaction_ready"] is False
|
|
assert token_leak["operator_ai_summary_persistence_transaction"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert (
|
|
"summary_persistence_transaction_no_approval_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_writer_preflight_gates_cli_only_write():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_writer_preflight import (
|
|
build_candidate_queue_review_ai_summary_persistence_writer_preflight,
|
|
)
|
|
|
|
expected_key = "market-alert-review:sample-batch:sku-001"
|
|
transaction = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_transaction_preview",
|
|
"summary_persistence_transaction_ready": True,
|
|
"ready_for_summary_persistence_writer_gate": True,
|
|
"statement_count": 1,
|
|
"expected_dedupe_keys": [expected_key],
|
|
"summary_payload_hash": "f" * 64,
|
|
"transaction_summary": {
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"statement_count": 1,
|
|
"metadata_key": "ai_summary_review",
|
|
"payload_hash": "f" * 64,
|
|
"manual_cli_required": True,
|
|
"api_write_allowed": False,
|
|
},
|
|
"statements": [
|
|
{
|
|
"statement_type": "UPDATE",
|
|
"table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"where": {"dedupe_key": expected_key},
|
|
"parameter_preview": {
|
|
"dedupe_key": expected_key,
|
|
"metadata_key": "ai_summary_review",
|
|
"payload_hash": "f" * 64,
|
|
},
|
|
"requires_existing_metadata_merge": True,
|
|
"execute_in_api": False,
|
|
}
|
|
],
|
|
"rollback_plan": [
|
|
{"key": "backup_metadata_json_before_update"},
|
|
{"key": "restore_metadata_json_by_dedupe_key"},
|
|
{"key": "do_not_change_review_state"},
|
|
],
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"scheduler_attached": False,
|
|
"writes_executed": False,
|
|
"would_write_database": False,
|
|
}
|
|
operator_evidence = {
|
|
"ai_summary_persistence_transaction_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-transaction.json"
|
|
),
|
|
"metadata_json_backup_artifact_path": (
|
|
"artifacts/market_intel/metadata-json-backup.json"
|
|
),
|
|
"postwrite_smoke_plan_path": (
|
|
"artifacts/market_intel/summary-persistence-postwrite-smoke.json"
|
|
),
|
|
"operator_confirmed_ai_summary_persistence_writer_preflight": True,
|
|
"operator_confirmed_summary_persistence_is_cli_only": True,
|
|
"operator_confirmed_metadata_json_backup_required": True,
|
|
"operator_confirmed_postwrite_smoke_required": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
}
|
|
preflight = build_candidate_queue_review_ai_summary_persistence_writer_preflight(
|
|
ai_summary_persistence_transaction=transaction,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_writer_preflight(
|
|
ai_summary_persistence_transaction=transaction,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_writer_preflight(
|
|
ai_summary_persistence_transaction=transaction,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert preflight["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_writer_preflight_preview"
|
|
)
|
|
assert preflight["target_operation"] == "persist_ai_summary_metadata_json"
|
|
assert preflight["summary_persistence_writer_preflight_ready"] is True
|
|
assert preflight["ready_for_summary_persistence_run_package"] is True
|
|
assert preflight["ready_for_summary_persistence_cli_run"] is False
|
|
assert preflight["ready_for_real_write"] is False
|
|
assert preflight["ready_for_api_database_write"] is False
|
|
assert preflight["ready_for_telegram_dispatch"] is False
|
|
assert preflight["api_executes_cli"] is False
|
|
assert preflight["api_reads_approval_token"] is False
|
|
assert preflight["api_writes_file"] is False
|
|
assert preflight["api_writes_database"] is False
|
|
assert preflight["summary_persistence_writer_preflight_file_written"] is False
|
|
assert preflight["writer_preflight_file_written"] is False
|
|
assert preflight["metadata_patch_written"] is False
|
|
assert preflight["database_connection_opened"] is False
|
|
assert preflight["database_write_executed"] is False
|
|
assert preflight["database_commit_executed"] is False
|
|
assert preflight["llm_call_executed"] is False
|
|
assert preflight["telegram_dispatched"] is False
|
|
assert preflight["scheduler_attached"] is False
|
|
assert preflight["writes_executed"] is False
|
|
assert preflight["would_write_database"] is False
|
|
assert preflight["blocked_reasons"] == []
|
|
assert preflight["statement_count"] == 1
|
|
assert preflight["invalid_statement_count"] == 0
|
|
assert preflight["statement_payloads"][0]["dedupe_key"] == expected_key
|
|
assert preflight["writer_preflight_contract"]["api_write_allowed"] is False
|
|
assert preflight["writer_preflight_contract"]["manual_cli_required"] is True
|
|
assert preflight["writer_preflight_contract"]["requires_metadata_json_backup"] is True
|
|
assert preflight["writer_preflight_contract"]["requires_postwrite_smoke"] is True
|
|
assert "future_summary_persistence_write_must_use_cli_only_gate" in preflight[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["summary_persistence_writer_preflight_ready"] is False
|
|
assert token_leak["operator_ai_summary_persistence_writer_preflight"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert (
|
|
"summary_persistence_writer_preflight_no_approval_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"summary_persistence_writer_preflight_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_run_package_previews_cli_bundle():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_run_package import (
|
|
build_candidate_queue_review_ai_summary_persistence_run_package,
|
|
)
|
|
|
|
expected_key = "market-alert-review:sample-batch:sku-001"
|
|
writer_preflight = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_writer_preflight_preview",
|
|
"summary_persistence_writer_preflight_ready": True,
|
|
"ready_for_summary_persistence_run_package": True,
|
|
"statement_count": 1,
|
|
"invalid_statement_count": 0,
|
|
"expected_dedupe_keys": [expected_key],
|
|
"summary_payload_hash": "f" * 64,
|
|
"statement_payloads": [
|
|
{
|
|
"statement_type": "UPDATE",
|
|
"table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"dedupe_key": expected_key,
|
|
"metadata_key": "ai_summary_review",
|
|
"payload_hash": "f" * 64,
|
|
"execute_in_api": False,
|
|
}
|
|
],
|
|
"writer_preflight_contract": {
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"target_json_path": ["ai_summary_review"],
|
|
"manual_cli_required": True,
|
|
"api_write_allowed": False,
|
|
"requires_metadata_json_backup": True,
|
|
"requires_postwrite_smoke": True,
|
|
},
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"scheduler_attached": False,
|
|
"writes_executed": False,
|
|
"would_write_database": False,
|
|
}
|
|
operator_evidence = {
|
|
"ai_summary_persistence_transaction_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-transaction.json"
|
|
),
|
|
"ai_summary_persistence_writer_preflight_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-writer-preflight.json"
|
|
),
|
|
"ai_summary_persistence_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-run-package.json"
|
|
),
|
|
"metadata_json_backup_artifact_path": (
|
|
"artifacts/market_intel/metadata-json-backup.json"
|
|
),
|
|
"operator_confirmed_ai_summary_persistence_run_package": True,
|
|
"operator_confirmed_payload_manifest_reviewed": True,
|
|
"operator_confirmed_cli_command_reviewed": True,
|
|
"operator_confirmed_summary_persistence_is_cli_only": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
}
|
|
package = build_candidate_queue_review_ai_summary_persistence_run_package(
|
|
ai_summary_persistence_writer_preflight=writer_preflight,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_run_package(
|
|
ai_summary_persistence_writer_preflight=writer_preflight,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
execute_requested=True,
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_run_package(
|
|
ai_summary_persistence_writer_preflight=writer_preflight,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert package["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_package_preview"
|
|
)
|
|
assert package["target_operation"] == "persist_ai_summary_metadata_json"
|
|
assert package["package_ready"] is True
|
|
assert package["ready_for_summary_persistence_run_readiness"] is True
|
|
assert package["ready_for_summary_persistence_cli_run"] is False
|
|
assert package["ready_for_real_write"] is False
|
|
assert package["ready_for_api_database_write"] is False
|
|
assert package["ready_for_telegram_dispatch"] is False
|
|
assert package["package_artifact_created"] is False
|
|
assert package["summary_persistence_run_package_file_written"] is False
|
|
assert package["run_package_file_written"] is False
|
|
assert package["api_executes_cli"] is False
|
|
assert package["api_reads_approval_token"] is False
|
|
assert package["api_writes_file"] is False
|
|
assert package["api_writes_database"] is False
|
|
assert package["database_connection_opened"] is False
|
|
assert package["database_write_executed"] is False
|
|
assert package["database_commit_executed"] is False
|
|
assert package["llm_call_executed"] is False
|
|
assert package["telegram_dispatched"] is False
|
|
assert package["scheduler_attached"] is False
|
|
assert package["writes_executed"] is False
|
|
assert package["would_write_database"] is False
|
|
assert package["blocked_reasons"] == []
|
|
assert package["statement_count"] == 1
|
|
assert package["payload_manifest"]["payload_count"] == 1
|
|
assert package["payload_manifest"]["dedupe_keys"] == [expected_key]
|
|
assert package["payload_manifest"]["payloads"][0]["execute_in_api"] is False
|
|
assert len(package["required_artifacts"]) == 5
|
|
assert len(package["command_bundle"]) == 5
|
|
assert package["command_bundle"][3]["executes_database"] is True
|
|
assert package["command_bundle"][3]["executed"] is False
|
|
assert "future_summary_persistence_write_must_use_cli_only_gate" in package[
|
|
"safe_boundaries"
|
|
]
|
|
assert token_leak["package_ready"] is False
|
|
assert token_leak["operator_ai_summary_persistence_run_package"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert (
|
|
"summary_persistence_run_package_no_approval_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"summary_persistence_run_package_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_run_readiness_checks_operator_artifacts():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_run_package import (
|
|
build_candidate_queue_review_ai_summary_persistence_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_run_readiness import (
|
|
build_candidate_queue_review_ai_summary_persistence_run_readiness,
|
|
)
|
|
|
|
expected_key = "market-alert-review:sample-batch:sku-001"
|
|
writer_preflight = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_writer_preflight_preview",
|
|
"summary_persistence_writer_preflight_ready": True,
|
|
"ready_for_summary_persistence_run_package": True,
|
|
"statement_count": 1,
|
|
"invalid_statement_count": 0,
|
|
"expected_dedupe_keys": [expected_key],
|
|
"summary_payload_hash": "f" * 64,
|
|
"statement_payloads": [
|
|
{
|
|
"statement_type": "UPDATE",
|
|
"table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"dedupe_key": expected_key,
|
|
"metadata_key": "ai_summary_review",
|
|
"payload_hash": "f" * 64,
|
|
"execute_in_api": False,
|
|
}
|
|
],
|
|
"writer_preflight_contract": {
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"target_json_path": ["ai_summary_review"],
|
|
"manual_cli_required": True,
|
|
"api_write_allowed": False,
|
|
"requires_metadata_json_backup": True,
|
|
"requires_postwrite_smoke": True,
|
|
},
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"scheduler_attached": False,
|
|
"writes_executed": False,
|
|
"would_write_database": False,
|
|
}
|
|
operator_evidence = {
|
|
"ai_summary_persistence_transaction_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-transaction.json"
|
|
),
|
|
"ai_summary_persistence_writer_preflight_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-writer-preflight.json"
|
|
),
|
|
"ai_summary_persistence_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-run-package.json"
|
|
),
|
|
"metadata_json_backup_artifact_path": (
|
|
"artifacts/market_intel/metadata-json-backup.json"
|
|
),
|
|
"ai_summary_persistence_postwrite_smoke_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-postwrite-smoke.json"
|
|
),
|
|
"operator_confirmed_ai_summary_persistence_run_package": True,
|
|
"operator_confirmed_payload_manifest_reviewed": True,
|
|
"operator_confirmed_summary_persistence_is_cli_only": True,
|
|
"operator_confirmed_ai_summary_persistence_run_readiness": True,
|
|
"operator_confirmed_run_package_artifact_reviewed": True,
|
|
"operator_confirmed_backup_artifact_reviewed": True,
|
|
"operator_confirmed_writer_preflight_reviewed": True,
|
|
"operator_confirmed_cli_command_reviewed": True,
|
|
"operator_confirmed_one_time_token_shell_only": True,
|
|
"operator_confirmed_postwrite_smoke_required": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
}
|
|
run_package = build_candidate_queue_review_ai_summary_persistence_run_package(
|
|
ai_summary_persistence_writer_preflight=writer_preflight,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
readiness = build_candidate_queue_review_ai_summary_persistence_run_readiness(
|
|
ai_summary_persistence_run_package=run_package,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_run_readiness(
|
|
ai_summary_persistence_run_package=run_package,
|
|
operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
|
|
execute_requested=True,
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_run_readiness(
|
|
ai_summary_persistence_run_package=run_package,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert run_package["package_ready"] is True
|
|
assert readiness["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_readiness_preview"
|
|
)
|
|
assert readiness["run_readiness_ready"] is True
|
|
assert readiness["summary_persistence_run_readiness_ready"] is True
|
|
assert readiness["ready_for_cli_operator_run"] is True
|
|
assert readiness["ready_for_summary_persistence_cli_run"] is False
|
|
assert readiness["ready_for_real_write"] is False
|
|
assert readiness["ready_for_api_database_write"] is False
|
|
assert readiness["ready_for_telegram_dispatch"] is False
|
|
assert readiness["summary_persistence_run_readiness_file_written"] is False
|
|
assert readiness["run_readiness_file_written"] is False
|
|
assert readiness["api_executes_cli"] is False
|
|
assert readiness["api_reads_approval_token"] is False
|
|
assert readiness["api_writes_file"] is False
|
|
assert readiness["api_writes_database"] is False
|
|
assert readiness["database_connection_opened"] is False
|
|
assert readiness["database_write_executed"] is False
|
|
assert readiness["database_commit_executed"] is False
|
|
assert readiness["llm_call_executed"] is False
|
|
assert readiness["telegram_dispatched"] is False
|
|
assert readiness["scheduler_attached"] is False
|
|
assert readiness["writes_executed"] is False
|
|
assert readiness["would_write_database"] is False
|
|
assert readiness["statement_count"] == 1
|
|
assert readiness["run_package_summary"]["payload_count"] == 1
|
|
assert readiness["run_package_summary"]["writer_command_present"] is True
|
|
assert readiness["operator_ai_summary_persistence_run_readiness"][
|
|
"artifact_path_count"
|
|
] == 5
|
|
assert readiness["blocked_reasons"] == []
|
|
assert token_leak["run_readiness_ready"] is False
|
|
assert token_leak["operator_ai_summary_persistence_run_readiness"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert (
|
|
"summary_persistence_run_readiness_no_approval_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"summary_persistence_run_readiness_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_run_receipt_reviews_cli_output():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_run_package import (
|
|
build_candidate_queue_review_ai_summary_persistence_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_run_readiness import (
|
|
build_candidate_queue_review_ai_summary_persistence_run_readiness,
|
|
)
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_run_receipt import (
|
|
build_candidate_queue_review_ai_summary_persistence_run_receipt,
|
|
)
|
|
|
|
expected_key = "market-alert-review:sample-batch:sku-001"
|
|
expected_hash = "f" * 64
|
|
writer_preflight = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_writer_preflight_preview",
|
|
"summary_persistence_writer_preflight_ready": True,
|
|
"ready_for_summary_persistence_run_package": True,
|
|
"statement_count": 1,
|
|
"invalid_statement_count": 0,
|
|
"expected_dedupe_keys": [expected_key],
|
|
"summary_payload_hash": expected_hash,
|
|
"statement_payloads": [
|
|
{
|
|
"statement_type": "UPDATE",
|
|
"table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"dedupe_key": expected_key,
|
|
"metadata_key": "ai_summary_review",
|
|
"payload_hash": expected_hash,
|
|
"execute_in_api": False,
|
|
}
|
|
],
|
|
"writer_preflight_contract": {
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"target_json_path": ["ai_summary_review"],
|
|
"manual_cli_required": True,
|
|
"api_write_allowed": False,
|
|
"requires_metadata_json_backup": True,
|
|
"requires_postwrite_smoke": True,
|
|
},
|
|
}
|
|
operator_evidence = {
|
|
"ai_summary_persistence_transaction_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-transaction.json"
|
|
),
|
|
"ai_summary_persistence_writer_preflight_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-writer-preflight.json"
|
|
),
|
|
"ai_summary_persistence_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-run-package.json"
|
|
),
|
|
"metadata_json_backup_artifact_path": (
|
|
"artifacts/market_intel/metadata-json-backup.json"
|
|
),
|
|
"ai_summary_persistence_postwrite_smoke_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-postwrite-smoke.json"
|
|
),
|
|
"ai_summary_persistence_writer_output_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-writer-output.json"
|
|
),
|
|
"operator_confirmed_ai_summary_persistence_run_package": True,
|
|
"operator_confirmed_payload_manifest_reviewed": True,
|
|
"operator_confirmed_summary_persistence_is_cli_only": True,
|
|
"operator_confirmed_ai_summary_persistence_run_readiness": True,
|
|
"operator_confirmed_run_package_artifact_reviewed": True,
|
|
"operator_confirmed_backup_artifact_reviewed": True,
|
|
"operator_confirmed_writer_preflight_reviewed": True,
|
|
"operator_confirmed_cli_command_reviewed": True,
|
|
"operator_confirmed_one_time_token_shell_only": True,
|
|
"operator_confirmed_postwrite_smoke_required": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
"receipt_notes": "CLI output and smoke artifacts reviewed.",
|
|
}
|
|
run_package = build_candidate_queue_review_ai_summary_persistence_run_package(
|
|
ai_summary_persistence_writer_preflight=writer_preflight,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
readiness = build_candidate_queue_review_ai_summary_persistence_run_readiness(
|
|
ai_summary_persistence_run_package=run_package,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
writer_output = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_writer_cli_executed",
|
|
"exit_code": 0,
|
|
"writes_executed": True,
|
|
"would_write_database": True,
|
|
"database_connection_opened": True,
|
|
"explicit_transaction_opened": True,
|
|
"database_write_executed": True,
|
|
"database_commit_executed": True,
|
|
"database_rollback_executed": False,
|
|
"metadata_json_update_executed": True,
|
|
"updated_count": 1,
|
|
"affected_dedupe_keys": [expected_key],
|
|
"summary_payload_hash": expected_hash,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
}
|
|
postwrite_smoke_result = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_postwrite_smoke_read_only",
|
|
"postwrite_smoke_passed": True,
|
|
"metadata_json_update_verified": True,
|
|
"ready_for_operator_review": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"found_dedupe_keys": [expected_key],
|
|
"missing_dedupe_keys": [],
|
|
"expected_dedupe_key_count": 1,
|
|
"found_count": 1,
|
|
"missing_count": 0,
|
|
"summary_payload_hash": expected_hash,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
}
|
|
receipt = build_candidate_queue_review_ai_summary_persistence_run_receipt(
|
|
ai_summary_persistence_run_readiness=readiness,
|
|
writer_output=writer_output,
|
|
postwrite_smoke_result=postwrite_smoke_result,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_run_receipt(
|
|
ai_summary_persistence_run_readiness=readiness,
|
|
writer_output={**writer_output, "approval_token": TEST_APPROVAL_TOKEN},
|
|
postwrite_smoke_result=postwrite_smoke_result,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_run_receipt(
|
|
ai_summary_persistence_run_readiness=readiness,
|
|
writer_output=writer_output,
|
|
postwrite_smoke_result=postwrite_smoke_result,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert readiness["run_readiness_ready"] is True
|
|
assert receipt["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_receipt_preview"
|
|
)
|
|
assert receipt["run_receipt_passed"] is True
|
|
assert receipt["summary_persistence_run_receipt_passed"] is True
|
|
assert receipt["ready_for_summary_persistence_closeout"] is True
|
|
assert receipt["ready_for_summary_persistence_cli_run"] is False
|
|
assert receipt["ready_for_real_write"] is False
|
|
assert receipt["ready_for_api_database_write"] is False
|
|
assert receipt["ready_for_telegram_dispatch"] is False
|
|
assert receipt["summary_persistence_run_receipt_file_written"] is False
|
|
assert receipt["run_receipt_file_written"] is False
|
|
assert receipt["receipt_file_written"] is False
|
|
assert receipt["api_executes_cli"] is False
|
|
assert receipt["api_reads_approval_token"] is False
|
|
assert receipt["api_writes_file"] is False
|
|
assert receipt["api_writes_database"] is False
|
|
assert receipt["database_connection_opened"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["database_commit_executed"] is False
|
|
assert receipt["llm_call_executed"] is False
|
|
assert receipt["telegram_dispatched"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert receipt["writes_executed"] is False
|
|
assert receipt["would_write_database"] is False
|
|
assert receipt["statement_count"] == 1
|
|
assert receipt["expected_dedupe_keys"] == [expected_key]
|
|
assert receipt["writer_output_summary"]["database_write_executed"] is True
|
|
assert receipt["writer_output_summary"]["metadata_json_update_executed"] is True
|
|
assert receipt["writer_output_summary"]["dedupe_keys_match_expected"] is True
|
|
assert (
|
|
receipt["writer_output_summary"]["summary_payload_hash_matches_expected"]
|
|
is True
|
|
)
|
|
assert receipt["postwrite_smoke_summary"]["database_write_executed"] is False
|
|
assert receipt["postwrite_smoke_summary"]["dedupe_keys_match_expected"] is True
|
|
assert receipt["operator_evidence_summary"][
|
|
"writer_output_json_path_recorded"
|
|
] is True
|
|
assert receipt["blocked_reasons"] == []
|
|
assert token_leak["run_receipt_passed"] is False
|
|
assert "writer_output_no_approval_token_key" in token_leak["blocked_reasons"]
|
|
assert "run_receipt_apply_real_write_not_requested_from_api" in apply_write[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_write_metadata_json_from_summary_persistence_receipt" in receipt[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_run_closeout_promotes_telegram_gate_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_run_closeout import (
|
|
build_candidate_queue_review_ai_summary_persistence_run_closeout,
|
|
)
|
|
|
|
expected_key = "market-alert-review:sample-batch:sku-001"
|
|
expected_hash = "f" * 64
|
|
run_receipt = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_run_receipt_preview",
|
|
"target_operation": "persist_ai_summary_metadata_json",
|
|
"run_receipt_passed": True,
|
|
"summary_persistence_run_receipt_passed": True,
|
|
"ready_for_summary_persistence_closeout": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"expected_dedupe_keys": [expected_key],
|
|
"expected_summary_payload_hash": expected_hash,
|
|
"blocked_reasons": [],
|
|
"writer_output_summary": {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_writer_cli_executed",
|
|
"metadata_json_update_executed": True,
|
|
"dedupe_keys_match_expected": True,
|
|
"summary_payload_hash_matches_expected": True,
|
|
},
|
|
"postwrite_smoke_summary": {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_postwrite_smoke_read_only",
|
|
"postwrite_smoke_passed": True,
|
|
"read_only_query_executed": True,
|
|
"metadata_json_update_verified": True,
|
|
"dedupe_keys_match_expected": True,
|
|
"summary_payload_hash_matches_expected": True,
|
|
},
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"summary_persistence_record_written": False,
|
|
"metadata_patch_written": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"safe_boundaries": [
|
|
"do_not_execute_summary_persistence_writer_from_receipt_api",
|
|
"do_not_read_approval_token_from_summary_persistence_receipt_api",
|
|
"do_not_echo_operator_receipt_payload",
|
|
"do_not_create_summary_persistence_receipt_artifact_from_api",
|
|
"do_not_open_database_connection_from_summary_persistence_receipt",
|
|
"do_not_write_metadata_json_from_summary_persistence_receipt",
|
|
"do_not_update_review_state_from_summary_persistence_receipt",
|
|
"do_not_commit_summary_persistence_receipt",
|
|
"do_not_dispatch_telegram_from_summary_persistence_receipt",
|
|
"do_not_attach_scheduler_from_summary_persistence_receipt",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"ai_summary_persistence_closeout_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-persistence-closeout.json"
|
|
),
|
|
"operator_confirmed_summary_persistence_closeout": True,
|
|
"operator_confirmed_telegram_dispatch_requires_separate_gate": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_telegram_dispatch": True,
|
|
"closeout_notes": "Receipt reviewed; next gate is Telegram dispatch.",
|
|
}
|
|
closeout = build_candidate_queue_review_ai_summary_persistence_run_closeout(
|
|
run_receipt=run_receipt,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_run_closeout(
|
|
run_receipt=run_receipt,
|
|
operator_evidence={**operator_evidence, "approval_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_run_closeout(
|
|
run_receipt=run_receipt,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert closeout["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_closeout_preview"
|
|
)
|
|
assert closeout["closeout_passed"] is True
|
|
assert closeout["summary_persistence_closeout_passed"] is True
|
|
assert closeout["ready_for_summary_persistence_telegram_dispatch_gate"] is True
|
|
assert closeout["ready_for_telegram_dispatch"] is False
|
|
assert closeout["ready_for_api_database_write"] is False
|
|
assert closeout["ready_for_scheduler_attach"] is False
|
|
assert closeout["summary_persistence_closeout_file_written"] is False
|
|
assert closeout["closeout_file_written"] is False
|
|
assert closeout["api_executes_cli"] is False
|
|
assert closeout["api_executes_llm"] is False
|
|
assert closeout["api_reads_approval_token"] is False
|
|
assert closeout["api_writes_file"] is False
|
|
assert closeout["api_writes_database"] is False
|
|
assert closeout["database_connection_opened"] is False
|
|
assert closeout["database_write_executed"] is False
|
|
assert closeout["database_commit_executed"] is False
|
|
assert closeout["llm_call_executed"] is False
|
|
assert closeout["telegram_dispatched"] is False
|
|
assert closeout["scheduler_attached"] is False
|
|
assert closeout["writes_executed"] is False
|
|
assert closeout["would_write_database"] is False
|
|
assert closeout["statement_count"] == 1
|
|
assert closeout["receipt_summary"]["safe_boundaries_complete"] is True
|
|
assert closeout["operator_closeout_summary"][
|
|
"closeout_artifact_path_recorded"
|
|
] is True
|
|
assert closeout["promotion_gate"]["next_manual_phase"] == (
|
|
"summary_persistence_telegram_dispatch_gate"
|
|
)
|
|
assert closeout["promotion_gate"][
|
|
"telegram_dispatch_requires_separate_gate"
|
|
] is True
|
|
assert closeout["blocked_reasons"] == []
|
|
assert token_leak["closeout_passed"] is False
|
|
assert "closeout_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert "closeout_apply_real_write_not_requested_from_api" in apply_write[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_dispatch_telegram_from_summary_persistence_closeout" in closeout[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate_promotes_run_package_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate,
|
|
)
|
|
|
|
closeout = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_run_closeout_preview",
|
|
"target_operation": "persist_ai_summary_metadata_json",
|
|
"target_json_path": ["ai_summary_review"],
|
|
"closeout_passed": True,
|
|
"summary_persistence_closeout_passed": True,
|
|
"ready_for_summary_persistence_telegram_dispatch_gate": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "summary_persistence_telegram_dispatch_gate",
|
|
"telegram_dispatch_requires_separate_gate": True,
|
|
},
|
|
"receipt_summary": {
|
|
"expected_dedupe_key_count": 1,
|
|
"expected_summary_payload_hash": "f" * 64,
|
|
"writer_metadata_json_update_executed": True,
|
|
"postwrite_smoke_metadata_json_verified": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_execute_summary_persistence_writer_from_closeout_api",
|
|
"do_not_read_approval_token_from_summary_persistence_closeout_api",
|
|
"do_not_write_closeout_artifact_from_summary_persistence_closeout_api",
|
|
"do_not_open_database_connection_from_summary_persistence_closeout",
|
|
"do_not_write_metadata_json_from_summary_persistence_closeout",
|
|
"do_not_update_review_state_from_summary_persistence_closeout",
|
|
"do_not_dispatch_telegram_from_summary_persistence_closeout",
|
|
"do_not_attach_scheduler_from_summary_persistence_closeout",
|
|
"future_telegram_dispatch_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"ai_summary_telegram_dispatch_gate_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-gate.json"
|
|
),
|
|
"operator_confirmed_summary_persistence_telegram_dispatch_gate": True,
|
|
"operator_confirmed_telegram_message_reviewed": True,
|
|
"operator_confirmed_dispatch_requires_manual_run_package": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"dispatch_notes": "Message contract reviewed; next step is run package.",
|
|
}
|
|
gate = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate(
|
|
summary_persistence_closeout=closeout,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate(
|
|
summary_persistence_closeout=closeout,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_bot_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate(
|
|
summary_persistence_closeout=closeout,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert gate["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate_preview"
|
|
)
|
|
assert gate["telegram_dispatch_gate_passed"] is True
|
|
assert gate["summary_persistence_telegram_dispatch_gate_passed"] is True
|
|
assert gate["ready_for_summary_persistence_telegram_dispatch_run_package"] is True
|
|
assert gate["ready_for_manual_telegram_dispatch_run_package"] is True
|
|
assert gate["ready_for_telegram_dispatch"] is False
|
|
assert gate["ready_for_api_database_write"] is False
|
|
assert gate["ready_for_scheduler_attach"] is False
|
|
assert gate["api_dispatches_telegram"] is False
|
|
assert gate["api_executes_llm"] is False
|
|
assert gate["api_reads_approval_token"] is False
|
|
assert gate["api_writes_database"] is False
|
|
assert gate["telegram_dispatch_gate_file_written"] is False
|
|
assert gate["telegram_message_file_written"] is False
|
|
assert gate["telegram_dispatched"] is False
|
|
assert gate["database_connection_opened"] is False
|
|
assert gate["database_write_executed"] is False
|
|
assert gate["scheduler_attached"] is False
|
|
assert gate["statement_count"] == 1
|
|
assert gate["telegram_message_contract"]["api_dispatches_telegram"] is False
|
|
assert gate["telegram_message_contract"]["approval_tokens_allowed_in_message"] is False
|
|
assert gate["promotion_gate"]["next_manual_phase"] == (
|
|
"summary_persistence_telegram_dispatch_run_package"
|
|
)
|
|
assert gate["blocked_reasons"] == []
|
|
assert token_leak["telegram_dispatch_gate_passed"] is False
|
|
assert "telegram_dispatch_gate_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert "telegram_dispatch_gate_apply_real_write_not_requested_from_api" in apply_write[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_dispatch_telegram_from_summary_persistence_telegram_dispatch_gate_api" in gate[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package_promotes_readiness_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package,
|
|
)
|
|
|
|
dispatch_gate = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate_preview",
|
|
"target_operation": "prepare_ai_summary_telegram_dispatch_gate",
|
|
"target_json_path": ["ai_summary_review"],
|
|
"telegram_dispatch_gate_passed": True,
|
|
"summary_persistence_telegram_dispatch_gate_passed": True,
|
|
"ready_for_summary_persistence_telegram_dispatch_run_package": True,
|
|
"ready_for_manual_telegram_dispatch_run_package": True,
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "summary_persistence_telegram_dispatch_run_package",
|
|
},
|
|
"telegram_message_contract": {
|
|
"target_channel": "market-intel-alerts",
|
|
"message_format": "market_intel_ai_summary_brief",
|
|
"max_message_chars": 3500,
|
|
"requires_evidence_refs": True,
|
|
"requires_summary_payload_hash": True,
|
|
"expected_dedupe_key_count": 1,
|
|
"expected_summary_payload_hash": "f" * 64,
|
|
"api_dispatches_telegram": False,
|
|
"scheduler_dispatches_telegram": False,
|
|
"approval_tokens_allowed_in_message": False,
|
|
},
|
|
}
|
|
operator_evidence = {
|
|
"operator_confirmed_ai_summary_telegram_dispatch_run_package": True,
|
|
"operator_confirmed_message_contract_reviewed": True,
|
|
"operator_confirmed_command_bundle_reviewed": True,
|
|
"operator_confirmed_dispatch_is_manual_only": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"ai_summary_telegram_dispatch_gate_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-gate.json"
|
|
),
|
|
"ai_summary_telegram_dispatch_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-run-package.json"
|
|
),
|
|
"telegram_message_preview_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-message-preview.json"
|
|
),
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
}
|
|
package = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package(
|
|
telegram_dispatch_gate=dispatch_gate,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package(
|
|
telegram_dispatch_gate=dispatch_gate,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_bot_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package(
|
|
telegram_dispatch_gate=dispatch_gate,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert package["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package_preview"
|
|
)
|
|
assert package["telegram_dispatch_run_package_ready"] is True
|
|
assert package["summary_persistence_telegram_dispatch_run_package_ready"] is True
|
|
assert package["ready_for_summary_persistence_telegram_dispatch_run_readiness"] is True
|
|
assert package["ready_for_telegram_dispatch"] is False
|
|
assert package["ready_for_api_database_write"] is False
|
|
assert package["ready_for_scheduler_attach"] is False
|
|
assert package["api_dispatches_telegram"] is False
|
|
assert package["api_executes_llm"] is False
|
|
assert package["api_reads_approval_token"] is False
|
|
assert package["telegram_dispatch_run_package_file_written"] is False
|
|
assert package["telegram_message_file_written"] is False
|
|
assert package["telegram_dispatched"] is False
|
|
assert package["database_connection_opened"] is False
|
|
assert package["database_write_executed"] is False
|
|
assert package["scheduler_attached"] is False
|
|
assert package["statement_count"] == 1
|
|
assert len(package["command_bundle"]) == 5
|
|
assert package["command_bundle"][3]["executes_telegram"] is True
|
|
assert package["command_bundle"][3]["executed"] is False
|
|
assert package["message_package_manifest"]["api_dispatches_telegram"] is False
|
|
assert package["message_package_manifest"][
|
|
"approval_tokens_allowed_in_message"
|
|
] is False
|
|
assert package["promotion_gate"]["next_manual_phase"] == (
|
|
"summary_persistence_telegram_dispatch_run_readiness"
|
|
)
|
|
assert package["blocked_reasons"] == []
|
|
assert token_leak["telegram_dispatch_run_package_ready"] is False
|
|
assert "telegram_dispatch_run_package_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert "telegram_dispatch_run_package_apply_real_write_not_requested_from_api" in apply_write[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_run_package_api" in package[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness_promotes_receipt_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness,
|
|
)
|
|
|
|
run_package = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package_preview",
|
|
"target_operation": "prepare_ai_summary_telegram_dispatch_run_package",
|
|
"telegram_dispatch_run_package_ready": True,
|
|
"package_ready": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_summary_persistence_telegram_dispatch_run_readiness": True,
|
|
"message_package_manifest": {
|
|
"target_channel": "market-intel-alerts",
|
|
"message_format": "market_intel_ai_summary_brief",
|
|
"expected_dedupe_key_count": 1,
|
|
"expected_summary_payload_hash": "a" * 64,
|
|
"requires_evidence_refs": True,
|
|
"requires_summary_payload_hash": True,
|
|
"api_dispatches_telegram": False,
|
|
"scheduler_dispatches_telegram": False,
|
|
"approval_tokens_allowed_in_message": False,
|
|
"manifest_hash": "b" * 64,
|
|
},
|
|
"command_bundle": [
|
|
{"key": "persist_run_package_json", "executed": False},
|
|
{"key": "render_message_preview", "executed": False},
|
|
{"key": "operator_message_review", "executed": False},
|
|
{
|
|
"key": "manual_telegram_dispatch",
|
|
"executes_telegram": True,
|
|
"executed": False,
|
|
},
|
|
{"key": "dispatch_receipt", "executed": False},
|
|
],
|
|
"required_artifacts": [
|
|
{"key": "telegram_dispatch_gate_json"},
|
|
{"key": "telegram_dispatch_run_package_json"},
|
|
{"key": "telegram_message_preview_json"},
|
|
{"key": "telegram_dispatch_receipt_json"},
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"operator_confirmed_ai_summary_telegram_dispatch_run_readiness": True,
|
|
"operator_confirmed_run_package_artifact_reviewed": True,
|
|
"operator_confirmed_message_preview_reviewed": True,
|
|
"operator_confirmed_manual_dispatch_command_reviewed": True,
|
|
"operator_confirmed_telegram_token_shell_only": True,
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
"operator_confirmed_dispatch_receipt_required": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"ai_summary_telegram_dispatch_gate_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-gate.json"
|
|
),
|
|
"ai_summary_telegram_dispatch_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-run-package.json"
|
|
),
|
|
"telegram_message_preview_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-message-preview.json"
|
|
),
|
|
"telegram_dispatch_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-receipt.json"
|
|
),
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
}
|
|
readiness = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness(
|
|
telegram_dispatch_run_package=run_package,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness(
|
|
telegram_dispatch_run_package=run_package,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_bot_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness(
|
|
telegram_dispatch_run_package=run_package,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert readiness["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness_preview"
|
|
)
|
|
assert readiness["telegram_dispatch_run_readiness_ready"] is True
|
|
assert (
|
|
readiness["summary_persistence_telegram_dispatch_run_readiness_ready"]
|
|
is True
|
|
)
|
|
assert readiness["ready_for_manual_telegram_dispatch"] is True
|
|
assert (
|
|
readiness["ready_for_summary_persistence_telegram_dispatch_run_receipt"]
|
|
is True
|
|
)
|
|
assert readiness["ready_for_telegram_dispatch"] is False
|
|
assert readiness["ready_for_api_database_write"] is False
|
|
assert readiness["ready_for_scheduler_attach"] is False
|
|
assert readiness["api_dispatches_telegram"] is False
|
|
assert readiness["api_executes_llm"] is False
|
|
assert readiness["api_reads_approval_token"] is False
|
|
assert readiness["telegram_dispatch_run_readiness_file_written"] is False
|
|
assert readiness["telegram_message_file_written"] is False
|
|
assert readiness["telegram_dispatched"] is False
|
|
assert readiness["telegram_dispatch_attempted"] is False
|
|
assert readiness["database_connection_opened"] is False
|
|
assert readiness["database_write_executed"] is False
|
|
assert readiness["scheduler_attached"] is False
|
|
assert readiness["statement_count"] == 1
|
|
assert readiness["promotion_gate"]["next_manual_phase"] == (
|
|
"summary_persistence_telegram_dispatch_run_receipt"
|
|
)
|
|
assert readiness["manual_dispatch_boundary"]["api_may_dispatch_telegram"] is False
|
|
assert readiness["manual_dispatch_boundary"]["telegram_token_shell_only"] is True
|
|
assert readiness["blocked_reasons"] == []
|
|
assert token_leak["telegram_dispatch_run_readiness_ready"] is False
|
|
assert "telegram_dispatch_run_readiness_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert "telegram_dispatch_run_readiness_apply_real_write_not_requested_from_api" in apply_write[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_run_readiness_api" in readiness[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt_promotes_closeout_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt,
|
|
)
|
|
|
|
run_readiness = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness_preview",
|
|
"telegram_dispatch_run_readiness_ready": True,
|
|
"run_readiness_ready": True,
|
|
"ready_for_manual_telegram_dispatch": True,
|
|
"ready_for_summary_persistence_telegram_dispatch_run_receipt": True,
|
|
"statement_count": 1,
|
|
"telegram_dispatch_run_package_summary": {
|
|
"target_channel": "market-intel-alerts",
|
|
"message_format": "market_intel_ai_summary_brief",
|
|
"expected_dedupe_key_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"manifest_hash": "d" * 64,
|
|
"manual_dispatch_command_present": True,
|
|
"commands_executed": False,
|
|
"side_effects_clear": True,
|
|
},
|
|
}
|
|
telegram_dispatch_receipt = {
|
|
"mode": "candidate_queue_review_ai_summary_telegram_dispatch_manual_receipt",
|
|
"ok": True,
|
|
"telegram_dispatch_attempted": True,
|
|
"telegram_dispatched": True,
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "c" * 64,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"api_updates_review_state": False,
|
|
"review_state_update_executed": False,
|
|
"llm_call_executed": False,
|
|
"scheduler_attached": False,
|
|
"api_dispatches_telegram": False,
|
|
}
|
|
operator_evidence = {
|
|
"telegram_dispatch_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-receipt.json"
|
|
),
|
|
"telegram_message_preview_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-message-preview.json"
|
|
),
|
|
"operator_confirmed_ai_summary_telegram_dispatch_run_receipt": True,
|
|
"operator_confirmed_message_id_recorded": True,
|
|
"operator_confirmed_summary_hash_matched": True,
|
|
"operator_confirmed_no_token_in_receipt": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"receipt_notes": "manual Telegram dispatch receipt reviewed",
|
|
}
|
|
receipt = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt(
|
|
telegram_dispatch_run_readiness=run_readiness,
|
|
telegram_dispatch_receipt=telegram_dispatch_receipt,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt(
|
|
telegram_dispatch_run_readiness=run_readiness,
|
|
telegram_dispatch_receipt={
|
|
**telegram_dispatch_receipt,
|
|
"telegram_bot_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt(
|
|
telegram_dispatch_run_readiness=run_readiness,
|
|
telegram_dispatch_receipt=telegram_dispatch_receipt,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert receipt["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt_preview"
|
|
)
|
|
assert receipt["telegram_dispatch_run_receipt_passed"] is True
|
|
assert receipt["summary_persistence_telegram_dispatch_run_receipt_passed"] is True
|
|
assert receipt["ready_for_summary_persistence_telegram_dispatch_closeout"] is True
|
|
assert receipt["ready_for_telegram_dispatch"] is False
|
|
assert receipt["ready_for_api_database_write"] is False
|
|
assert receipt["ready_for_scheduler_attach"] is False
|
|
assert receipt["api_dispatches_telegram"] is False
|
|
assert receipt["api_executes_llm"] is False
|
|
assert receipt["api_reads_approval_token"] is False
|
|
assert receipt["telegram_dispatch_run_receipt_file_written"] is False
|
|
assert receipt["telegram_dispatch_receipt_file_written"] is False
|
|
assert receipt["telegram_dispatched"] is False
|
|
assert receipt["telegram_dispatch_attempted"] is False
|
|
assert receipt["database_connection_opened"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert receipt["statement_count"] == 1
|
|
assert receipt["telegram_dispatch_receipt_summary"]["telegram_dispatched"] is True
|
|
assert (
|
|
receipt["telegram_dispatch_receipt_summary"][
|
|
"summary_payload_hash_matches_expected"
|
|
]
|
|
is True
|
|
)
|
|
assert receipt["promotion_gate"]["next_manual_phase"] == (
|
|
"summary_persistence_telegram_dispatch_closeout"
|
|
)
|
|
assert receipt["blocked_reasons"] == []
|
|
assert token_leak["telegram_dispatch_run_receipt_passed"] is False
|
|
assert "telegram_dispatch_receipt_no_token_key" in token_leak["blocked_reasons"]
|
|
assert "telegram_dispatch_run_receipt_apply_real_write_not_requested_from_api" in apply_write[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_run_receipt_api" in receipt[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout_archives_receipt_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout,
|
|
)
|
|
|
|
run_receipt = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt_preview",
|
|
"target_operation": "review_manual_ai_summary_telegram_dispatch_receipt",
|
|
"telegram_dispatch_run_receipt_passed": True,
|
|
"summary_persistence_telegram_dispatch_run_receipt_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_summary_persistence_telegram_dispatch_closeout": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_manual_telegram_dispatch": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_run_receipt_file_written": False,
|
|
"telegram_dispatch_receipt_file_written": False,
|
|
"telegram_message_file_written": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"external_network_executed": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"telegram_dispatch_receipt_summary": {
|
|
"provided": True,
|
|
"mode": "candidate_queue_review_ai_summary_telegram_dispatch_manual_receipt",
|
|
"ok": True,
|
|
"telegram_dispatch_attempted": True,
|
|
"telegram_dispatched": True,
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "c" * 64,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"approval_or_telegram_token_key_detected": False,
|
|
},
|
|
"telegram_dispatch_run_readiness_summary": {
|
|
"expected_dedupe_key_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_telegram_dispatch_run_receipt_api",
|
|
"do_not_read_telegram_token_from_telegram_dispatch_run_receipt_api",
|
|
"do_not_call_llm_from_telegram_dispatch_run_receipt",
|
|
"do_not_dispatch_telegram_from_telegram_dispatch_run_receipt_api",
|
|
"do_not_retry_telegram_dispatch_from_receipt_api",
|
|
"do_not_echo_operator_telegram_receipt_payload",
|
|
"do_not_open_database_connection_from_telegram_dispatch_run_receipt",
|
|
"do_not_write_dispatch_receipt_artifact_from_api",
|
|
"do_not_update_review_state_from_telegram_dispatch_run_receipt",
|
|
"do_not_attach_scheduler_from_telegram_dispatch_run_receipt",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"telegram_dispatch_closeout_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-closeout.json"
|
|
),
|
|
"telegram_dispatch_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-receipt.json"
|
|
),
|
|
"operator_confirmed_telegram_dispatch_closeout": True,
|
|
"operator_confirmed_receipt_archived": True,
|
|
"operator_confirmed_message_visible": True,
|
|
"operator_confirmed_summary_hash_matched": True,
|
|
"operator_confirmed_no_duplicate_dispatch": True,
|
|
"operator_confirmed_no_retry_needed": True,
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_post_closeout_monitoring": True,
|
|
"closeout_notes": "manual Telegram dispatch closeout archived",
|
|
}
|
|
closeout = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout(
|
|
telegram_dispatch_run_receipt=run_receipt,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout(
|
|
telegram_dispatch_run_receipt=run_receipt,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_bot_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout(
|
|
telegram_dispatch_run_receipt=run_receipt,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert closeout["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout_preview"
|
|
)
|
|
assert closeout["telegram_dispatch_closeout_passed"] is True
|
|
assert (
|
|
closeout["summary_persistence_telegram_dispatch_closeout_passed"] is True
|
|
)
|
|
assert closeout["ready_for_next_manual_phase"] is True
|
|
assert closeout["ready_for_summary_persistence_telegram_dispatch_archive"] is True
|
|
assert closeout["ready_for_telegram_dispatch"] is False
|
|
assert closeout["ready_for_api_database_write"] is False
|
|
assert closeout["ready_for_scheduler_attach"] is False
|
|
assert closeout["api_dispatches_telegram"] is False
|
|
assert closeout["api_executes_llm"] is False
|
|
assert closeout["api_reads_approval_token"] is False
|
|
assert closeout["telegram_dispatch_closeout_file_written"] is False
|
|
assert closeout["telegram_dispatch_run_receipt_file_written"] is False
|
|
assert closeout["telegram_dispatch_receipt_file_written"] is False
|
|
assert closeout["telegram_dispatched"] is False
|
|
assert closeout["telegram_dispatch_attempted"] is False
|
|
assert closeout["database_connection_opened"] is False
|
|
assert closeout["database_write_executed"] is False
|
|
assert closeout["scheduler_attached"] is False
|
|
assert closeout["statement_count"] == 1
|
|
assert closeout["dispatch_audit_summary"]["manual_dispatch_proven"] is True
|
|
assert closeout["dispatch_audit_summary"]["api_dispatch_blocked"] is True
|
|
assert closeout["dispatch_audit_summary"]["message_id"] == "9988"
|
|
assert closeout["promotion_gate"]["next_manual_phase"] == (
|
|
"summary_persistence_telegram_dispatch_archive"
|
|
)
|
|
assert closeout["blocked_reasons"] == []
|
|
assert token_leak["telegram_dispatch_closeout_passed"] is False
|
|
assert "telegram_dispatch_closeout_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_closeout_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_closeout_api" in closeout[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_manifest_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive,
|
|
)
|
|
|
|
closeout = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout_preview",
|
|
"target_operation": "closeout_manual_ai_summary_telegram_dispatch",
|
|
"telegram_dispatch_closeout_passed": True,
|
|
"summary_persistence_telegram_dispatch_closeout_passed": True,
|
|
"closeout_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_summary_persistence_telegram_dispatch_archive": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_manual_telegram_dispatch": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_closeout_file_written": False,
|
|
"telegram_dispatch_receipt_file_written": False,
|
|
"telegram_dispatch_run_receipt_file_written": False,
|
|
"telegram_message_file_written": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"external_network_executed": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"telegram_dispatch_run_receipt_summary": {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt_preview",
|
|
"receipt_passed": True,
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "c" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
},
|
|
"dispatch_audit_summary": {
|
|
"manual_dispatch_proven": True,
|
|
"api_dispatch_blocked": True,
|
|
"duplicate_dispatch_ruled_out": True,
|
|
"receipt_archived": True,
|
|
"post_closeout_monitoring_confirmed": True,
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "c" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
},
|
|
"operator_telegram_dispatch_closeout": {
|
|
"telegram_dispatch_closeout_artifact_path_recorded": True,
|
|
"telegram_dispatch_receipt_artifact_path_recorded": True,
|
|
"operator_confirmed_telegram_dispatch_closeout": True,
|
|
"operator_confirmed_receipt_archived": True,
|
|
"operator_confirmed_no_duplicate_dispatch": True,
|
|
"operator_confirmed_post_closeout_monitoring": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_dispatch_telegram_from_telegram_dispatch_closeout_api",
|
|
"telegram_dispatch_closeout_preview_only",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"telegram_dispatch_archive_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-archive.json"
|
|
),
|
|
"telegram_dispatch_closeout_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-closeout.json"
|
|
),
|
|
"telegram_dispatch_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-receipt.json"
|
|
),
|
|
"telegram_message_preview_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-message-preview.json"
|
|
),
|
|
"operator_confirmed_telegram_dispatch_archive": True,
|
|
"operator_confirmed_archive_is_read_only": True,
|
|
"operator_confirmed_receipt_archived": True,
|
|
"operator_confirmed_message_id_archived": True,
|
|
"operator_confirmed_dispatch_audit_archived": True,
|
|
"operator_confirmed_post_closeout_monitoring": True,
|
|
"operator_confirmed_no_duplicate_dispatch": True,
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"archive_notes": "manual Telegram dispatch evidence archived",
|
|
}
|
|
archive = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive(
|
|
telegram_dispatch_closeout=closeout,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive(
|
|
telegram_dispatch_closeout=closeout,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_bot_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive(
|
|
telegram_dispatch_closeout=closeout,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert archive["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_preview"
|
|
)
|
|
assert archive["target_operation"] == (
|
|
"archive_manual_ai_summary_telegram_dispatch_evidence"
|
|
)
|
|
assert archive["telegram_dispatch_archive_ready"] is True
|
|
assert archive["summary_persistence_telegram_dispatch_archive_ready"] is True
|
|
assert archive["archive_manifest_ready"] is True
|
|
assert archive["ready_for_summary_persistence_telegram_dispatch_archive_summary"] is True
|
|
assert archive["ready_for_telegram_dispatch"] is False
|
|
assert archive["ready_for_api_database_write"] is False
|
|
assert archive["ready_for_scheduler_attach"] is False
|
|
assert archive["api_dispatches_telegram"] is False
|
|
assert archive["api_executes_llm"] is False
|
|
assert archive["api_reads_approval_token"] is False
|
|
assert archive["telegram_dispatch_archive_file_written"] is False
|
|
assert archive["archive_file_written"] is False
|
|
assert archive["archive_record_written"] is False
|
|
assert archive["archive_manifest_written"] is False
|
|
assert archive["telegram_dispatched"] is False
|
|
assert archive["telegram_dispatch_attempted"] is False
|
|
assert archive["database_connection_opened"] is False
|
|
assert archive["database_write_executed"] is False
|
|
assert archive["scheduler_attached"] is False
|
|
assert archive["statement_count"] == 1
|
|
assert archive["telegram_dispatch_archive_manifest"]["telegram_message"][
|
|
"message_id"
|
|
] == "9988"
|
|
assert archive["telegram_dispatch_archive_manifest"]["dispatch_audit"][
|
|
"manual_dispatch_proven"
|
|
] is True
|
|
assert archive["promotion_gate"]["next_manual_phase"] == (
|
|
"summary_persistence_telegram_dispatch_archive_summary"
|
|
)
|
|
assert archive["blocked_reasons"] == []
|
|
assert token_leak["telegram_dispatch_archive_ready"] is False
|
|
assert "telegram_dispatch_archive_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_archive_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_archive_api" in archive[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_report_input_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary,
|
|
)
|
|
|
|
archive = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_preview",
|
|
"target_operation": "archive_manual_ai_summary_telegram_dispatch_evidence",
|
|
"telegram_dispatch_archive_ready": True,
|
|
"summary_persistence_telegram_dispatch_archive_ready": True,
|
|
"archive_manifest_ready": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_summary_persistence_telegram_dispatch_archive_summary": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_manual_telegram_dispatch": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"ready_for_llm_call": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_archive_file_written": False,
|
|
"telegram_dispatch_archive_summary_file_written": False,
|
|
"telegram_dispatch_closeout_file_written": False,
|
|
"telegram_dispatch_receipt_file_written": False,
|
|
"telegram_message_file_written": False,
|
|
"archive_file_written": False,
|
|
"archive_record_written": False,
|
|
"archive_manifest_written": False,
|
|
"archive_summary_file_written": False,
|
|
"summary_file_written": False,
|
|
"summary_record_written": False,
|
|
"summary_manifest_written": False,
|
|
"ai_summary_generated": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"external_network_executed": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"telegram_dispatch_archive_manifest": {
|
|
"telegram_message": {
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "c" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
},
|
|
"dispatch_audit": {
|
|
"manual_dispatch_proven": True,
|
|
"api_dispatch_blocked": True,
|
|
"duplicate_dispatch_ruled_out": True,
|
|
"receipt_archived": True,
|
|
"post_closeout_monitoring_confirmed": True,
|
|
},
|
|
"artifact_paths": {
|
|
"telegram_dispatch_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-receipt.json"
|
|
),
|
|
"telegram_dispatch_closeout_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-closeout.json"
|
|
),
|
|
"telegram_message_preview_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-message-preview.json"
|
|
),
|
|
"telegram_dispatch_archive_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-archive.json"
|
|
),
|
|
},
|
|
},
|
|
"telegram_dispatch_closeout_summary": {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout_preview",
|
|
"closeout_passed": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_dispatch_telegram_from_telegram_dispatch_archive_api",
|
|
"telegram_dispatch_archive_preview_only",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"telegram_dispatch_archive_summary_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-archive-summary.json"
|
|
),
|
|
"operator_confirmed_telegram_dispatch_archive_summary": True,
|
|
"operator_confirmed_summary_is_read_only": True,
|
|
"operator_confirmed_message_and_artifacts_reviewed": True,
|
|
"operator_confirmed_dispatch_audit_reviewed": True,
|
|
"operator_confirmed_report_input_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"archive_summary_notes": "manual Telegram dispatch archive summary reviewed",
|
|
}
|
|
summary = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary(
|
|
telegram_dispatch_archive=archive,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary(
|
|
telegram_dispatch_archive=archive,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_bot_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary(
|
|
telegram_dispatch_archive=archive,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert summary["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_preview"
|
|
)
|
|
assert summary["target_operation"] == (
|
|
"prepare_manual_ai_summary_telegram_dispatch_archive_summary_input"
|
|
)
|
|
assert summary["telegram_dispatch_archive_summary_ready"] is True
|
|
assert (
|
|
summary["summary_persistence_telegram_dispatch_archive_summary_ready"]
|
|
is True
|
|
)
|
|
assert summary["summary_input_ready"] is True
|
|
assert summary["ready_for_summary_persistence_telegram_dispatch_report_input"] is True
|
|
assert summary["ready_for_telegram_dispatch"] is False
|
|
assert summary["ready_for_api_database_write"] is False
|
|
assert summary["ready_for_scheduler_attach"] is False
|
|
assert summary["api_dispatches_telegram"] is False
|
|
assert summary["api_executes_llm"] is False
|
|
assert summary["api_reads_approval_token"] is False
|
|
assert summary["api_writes_file"] is False
|
|
assert summary["api_writes_database"] is False
|
|
assert summary["telegram_dispatch_archive_summary_file_written"] is False
|
|
assert summary["archive_summary_file_written"] is False
|
|
assert summary["telegram_dispatch_archive_file_written"] is False
|
|
assert summary["archive_manifest_written"] is False
|
|
assert summary["summary_file_written"] is False
|
|
assert summary["summary_record_written"] is False
|
|
assert summary["summary_manifest_written"] is False
|
|
assert summary["ai_summary_generated"] is False
|
|
assert summary["llm_call_executed"] is False
|
|
assert summary["telegram_dispatched"] is False
|
|
assert summary["telegram_dispatch_attempted"] is False
|
|
assert summary["database_connection_opened"] is False
|
|
assert summary["database_write_executed"] is False
|
|
assert summary["database_commit_executed"] is False
|
|
assert summary["review_state_update_executed"] is False
|
|
assert summary["scheduler_attached"] is False
|
|
assert summary["statement_count"] == 1
|
|
assert summary["blocked_reasons"] == []
|
|
assert summary["telegram_dispatch_archive_summary"]["message"][
|
|
"message_id"
|
|
] == "9988"
|
|
assert summary["telegram_dispatch_archive_summary"]["dispatch_audit"][
|
|
"manual_dispatch_proven"
|
|
] is True
|
|
assert summary["telegram_dispatch_archive_summary_sections"]
|
|
assert summary["promotion_gate"]["next_manual_phase"] == (
|
|
"summary_persistence_telegram_dispatch_report_input"
|
|
)
|
|
assert token_leak["telegram_dispatch_archive_summary_ready"] is False
|
|
assert (
|
|
"telegram_dispatch_archive_summary_no_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"telegram_dispatch_archive_summary_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_archive_summary_api" in summary[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input,
|
|
)
|
|
|
|
archive_summary = {
|
|
"mode": (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_preview"
|
|
),
|
|
"target_operation": (
|
|
"prepare_manual_ai_summary_telegram_dispatch_archive_summary_input"
|
|
),
|
|
"telegram_dispatch_archive_summary_ready": True,
|
|
"summary_persistence_telegram_dispatch_archive_summary_ready": True,
|
|
"summary_input_ready": True,
|
|
"ready_for_summary_persistence_telegram_dispatch_report_input": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "d" * 64,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_manual_telegram_dispatch": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"ready_for_llm_call": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_archive_summary_file_written": False,
|
|
"telegram_dispatch_archive_file_written": False,
|
|
"archive_summary_file_written": False,
|
|
"archive_file_written": False,
|
|
"archive_record_written": False,
|
|
"archive_manifest_written": False,
|
|
"telegram_message_file_written": False,
|
|
"summary_file_written": False,
|
|
"summary_record_written": False,
|
|
"summary_manifest_written": False,
|
|
"ai_summary_generated": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"external_network_executed": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"blocked_reasons": [],
|
|
"telegram_dispatch_archive_summary": {
|
|
"message": {
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "d" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
},
|
|
"dispatch_audit": {
|
|
"manual_dispatch_proven": True,
|
|
"api_dispatch_blocked": True,
|
|
"duplicate_dispatch_ruled_out": True,
|
|
"receipt_archived": True,
|
|
"post_closeout_monitoring_confirmed": True,
|
|
},
|
|
"artifact_paths": {
|
|
"telegram_dispatch_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-receipt.json"
|
|
),
|
|
"telegram_dispatch_closeout_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-closeout.json"
|
|
),
|
|
"telegram_message_preview_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-message-preview.json"
|
|
),
|
|
"telegram_dispatch_archive_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-archive.json"
|
|
),
|
|
},
|
|
},
|
|
"telegram_dispatch_archive_summary_sections": [
|
|
{"key": "telegram_message_identity", "facts": ["message_id=9988"]},
|
|
{"key": "dispatch_audit", "facts": ["manual_dispatch_proven=true"]},
|
|
{"key": "artifact_manifest", "facts": ["archive_path=ok"]},
|
|
{"key": "runtime_safety", "facts": ["telegram_dispatched=false"]},
|
|
],
|
|
"safe_boundaries": [
|
|
"do_not_dispatch_telegram_from_telegram_dispatch_archive_summary_api",
|
|
"telegram_dispatch_archive_summary_preview_only",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"telegram_dispatch_report_input_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-report-input.json"
|
|
),
|
|
"operator_confirmed_telegram_dispatch_report_input": True,
|
|
"operator_confirmed_report_input_is_read_only": True,
|
|
"operator_confirmed_archive_summary_reviewed": True,
|
|
"operator_confirmed_report_sections_reviewed": True,
|
|
"operator_confirmed_report_generation_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_input": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"report_input_notes": "manual report input reviewed",
|
|
}
|
|
report = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input(
|
|
telegram_dispatch_archive_summary=archive_summary,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input(
|
|
telegram_dispatch_archive_summary=archive_summary,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_bot_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input(
|
|
telegram_dispatch_archive_summary=archive_summary,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert report["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_preview"
|
|
)
|
|
assert report["target_operation"] == (
|
|
"prepare_manual_ai_summary_telegram_dispatch_report_input"
|
|
)
|
|
assert report["telegram_dispatch_report_input_ready"] is True
|
|
assert report["summary_persistence_telegram_dispatch_report_input_ready"] is True
|
|
assert report["ready_for_market_intel_report_run_package"] is True
|
|
assert report["ready_for_report_generation"] is False
|
|
assert report["ready_for_telegram_dispatch"] is False
|
|
assert report["ready_for_api_database_write"] is False
|
|
assert report["ready_for_scheduler_attach"] is False
|
|
assert report["api_dispatches_telegram"] is False
|
|
assert report["api_executes_llm"] is False
|
|
assert report["api_reads_approval_token"] is False
|
|
assert report["api_writes_file"] is False
|
|
assert report["api_writes_database"] is False
|
|
assert report["telegram_dispatch_report_input_file_written"] is False
|
|
assert report["report_input_file_written"] is False
|
|
assert report["report_file_written"] is False
|
|
assert report["report_record_written"] is False
|
|
assert report["report_manifest_written"] is False
|
|
assert report["ai_summary_generated"] is False
|
|
assert report["llm_call_executed"] is False
|
|
assert report["telegram_dispatched"] is False
|
|
assert report["telegram_dispatch_attempted"] is False
|
|
assert report["database_connection_opened"] is False
|
|
assert report["database_write_executed"] is False
|
|
assert report["database_commit_executed"] is False
|
|
assert report["review_state_update_executed"] is False
|
|
assert report["scheduler_attached"] is False
|
|
assert report["statement_count"] == 1
|
|
assert report["blocked_reasons"] == []
|
|
assert report["telegram_dispatch_report_input_contract"][
|
|
"contract_version"
|
|
] == "market_intel_telegram_dispatch_report_input_v1"
|
|
assert report["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_run_package"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_input_ready"] is False
|
|
assert "telegram_dispatch_report_input_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_report_input_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_report_input_api" in report[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_input_ready"] is False
|
|
assert data["summary_persistence_telegram_dispatch_report_input_ready"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_input_file_written"] is False
|
|
assert data["report_input_file_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["report_record_written"] is False
|
|
assert data["report_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["telegram_dispatch_attempted"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert "telegram_dispatch_archive_summary_ready" in data["blocked_reasons"]
|
|
assert "operator_confirmed_telegram_dispatch_report_input" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_report_input_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_report_input_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_archive_summary_ready"] is False
|
|
assert (
|
|
data["summary_persistence_telegram_dispatch_archive_summary_ready"]
|
|
is False
|
|
)
|
|
assert data["summary_input_ready"] is False
|
|
assert data["ready_for_summary_persistence_telegram_dispatch_report_input"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_archive_summary_file_written"] is False
|
|
assert data["archive_summary_file_written"] is False
|
|
assert data["telegram_dispatch_archive_file_written"] is False
|
|
assert data["archive_file_written"] is False
|
|
assert data["archive_record_written"] is False
|
|
assert data["archive_manifest_written"] is False
|
|
assert data["summary_file_written"] is False
|
|
assert data["summary_record_written"] is False
|
|
assert data["summary_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["telegram_dispatch_attempted"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_archive_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_preview"
|
|
)
|
|
assert "telegram_dispatch_archive_ready" in data["blocked_reasons"]
|
|
assert "telegram_dispatch_archive_summary_artifact_path_recorded" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "operator_confirmed_telegram_dispatch_archive_summary" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_archive_summary_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_archive_summary_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input,
|
|
)
|
|
|
|
archive_summary = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_preview",
|
|
"target_operation": "prepare_manual_ai_summary_telegram_dispatch_archive_summary_input",
|
|
"telegram_dispatch_archive_summary_ready": True,
|
|
"summary_persistence_telegram_dispatch_archive_summary_ready": True,
|
|
"summary_input_ready": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_summary_persistence_telegram_dispatch_report_input": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_manual_telegram_dispatch": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"ready_for_llm_call": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_archive_summary_file_written": False,
|
|
"archive_summary_file_written": False,
|
|
"telegram_dispatch_archive_file_written": False,
|
|
"telegram_message_file_written": False,
|
|
"summary_file_written": False,
|
|
"summary_record_written": False,
|
|
"summary_manifest_written": False,
|
|
"ai_summary_generated": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"external_network_executed": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"telegram_dispatch_archive_summary": {
|
|
"message": {
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "c" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
},
|
|
"dispatch_audit": {
|
|
"manual_dispatch_proven": True,
|
|
"api_dispatch_blocked": True,
|
|
"duplicate_dispatch_ruled_out": True,
|
|
"receipt_archived": True,
|
|
"post_closeout_monitoring_confirmed": True,
|
|
},
|
|
"artifact_paths": {
|
|
"telegram_dispatch_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-receipt.json"
|
|
),
|
|
"telegram_dispatch_closeout_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-closeout.json"
|
|
),
|
|
"telegram_message_preview_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-message-preview.json"
|
|
),
|
|
"telegram_dispatch_archive_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-archive.json"
|
|
),
|
|
},
|
|
},
|
|
"telegram_dispatch_archive_summary_sections": [
|
|
{"key": "telegram_message_identity", "facts": ["message_id=9988"]},
|
|
{"key": "dispatch_audit", "facts": ["manual_dispatch_proven=True"]},
|
|
{"key": "artifact_manifest", "facts": ["artifact_path_count=4"]},
|
|
{"key": "runtime_safety", "facts": ["llm_call_executed=false"]},
|
|
],
|
|
"safe_boundaries": [
|
|
"do_not_dispatch_telegram_from_telegram_dispatch_archive_summary_api",
|
|
"telegram_dispatch_archive_summary_preview_only",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"telegram_dispatch_report_input_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-report-input.json"
|
|
),
|
|
"operator_confirmed_telegram_dispatch_report_input": True,
|
|
"operator_confirmed_report_input_is_read_only": True,
|
|
"operator_confirmed_archive_summary_reviewed": True,
|
|
"operator_confirmed_report_sections_reviewed": True,
|
|
"operator_confirmed_report_generation_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_input": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"report_input_notes": "manual Telegram dispatch report input reviewed",
|
|
}
|
|
report_input = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input(
|
|
telegram_dispatch_archive_summary=archive_summary,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input(
|
|
telegram_dispatch_archive_summary=archive_summary,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input(
|
|
telegram_dispatch_archive_summary=archive_summary,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert report_input["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_preview"
|
|
)
|
|
assert report_input["target_operation"] == (
|
|
"prepare_manual_ai_summary_telegram_dispatch_report_input"
|
|
)
|
|
assert report_input["telegram_dispatch_report_input_ready"] is True
|
|
assert report_input["summary_persistence_telegram_dispatch_report_input_ready"] is True
|
|
assert report_input["report_input_ready"] is True
|
|
assert report_input["ready_for_market_intel_report_run_package"] is True
|
|
assert report_input["ready_for_report_generation"] is False
|
|
assert report_input["ready_for_telegram_dispatch"] is False
|
|
assert report_input["ready_for_api_database_write"] is False
|
|
assert report_input["ready_for_scheduler_attach"] is False
|
|
assert report_input["api_dispatches_telegram"] is False
|
|
assert report_input["api_executes_llm"] is False
|
|
assert report_input["api_reads_approval_token"] is False
|
|
assert report_input["api_writes_file"] is False
|
|
assert report_input["api_writes_database"] is False
|
|
assert report_input["telegram_dispatch_report_input_file_written"] is False
|
|
assert report_input["report_input_file_written"] is False
|
|
assert report_input["report_file_written"] is False
|
|
assert report_input["report_record_written"] is False
|
|
assert report_input["report_manifest_written"] is False
|
|
assert report_input["ai_summary_generated"] is False
|
|
assert report_input["llm_call_executed"] is False
|
|
assert report_input["telegram_dispatched"] is False
|
|
assert report_input["telegram_dispatch_attempted"] is False
|
|
assert report_input["database_connection_opened"] is False
|
|
assert report_input["database_write_executed"] is False
|
|
assert report_input["database_commit_executed"] is False
|
|
assert report_input["review_state_update_executed"] is False
|
|
assert report_input["scheduler_attached"] is False
|
|
assert report_input["statement_count"] == 1
|
|
assert report_input["blocked_reasons"] == []
|
|
assert report_input["telegram_dispatch_archive_summary_input"]["message"][
|
|
"message_id"
|
|
] == "9988"
|
|
assert report_input["telegram_dispatch_report_input_contract"][
|
|
"contract_version"
|
|
] == "market_intel_telegram_dispatch_report_input_v1"
|
|
assert report_input["telegram_dispatch_report_input_sections"]
|
|
assert report_input["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_run_package"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_input_ready"] is False
|
|
assert (
|
|
"telegram_dispatch_report_input_no_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"telegram_dispatch_report_input_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_telegram_dispatch_report_input_api" in report_input[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_input_ready"] is False
|
|
assert data["summary_persistence_telegram_dispatch_report_input_ready"] is False
|
|
assert data["report_input_ready"] is False
|
|
assert data["ready_for_market_intel_report_run_package"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_input_file_written"] is False
|
|
assert data["report_input_file_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["report_record_written"] is False
|
|
assert data["report_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["telegram_dispatch_attempted"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_archive_summary_input"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_preview"
|
|
)
|
|
assert "telegram_dispatch_archive_summary_ready" in data["blocked_reasons"]
|
|
assert "telegram_dispatch_report_input_artifact_path_recorded" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "operator_confirmed_telegram_dispatch_report_input" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_report_input_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_telegram_dispatch_report_input_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package,
|
|
)
|
|
|
|
report_input = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_preview",
|
|
"target_operation": "prepare_manual_ai_summary_telegram_dispatch_report_input",
|
|
"telegram_dispatch_report_input_ready": True,
|
|
"summary_persistence_telegram_dispatch_report_input_ready": True,
|
|
"report_input_ready": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_run_package": True,
|
|
"ready_for_report_generation": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_manual_telegram_dispatch": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"ready_for_llm_call": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_report_input_file_written": False,
|
|
"report_input_file_written": False,
|
|
"report_file_written": False,
|
|
"report_record_written": False,
|
|
"report_manifest_written": False,
|
|
"ai_summary_generated": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"external_network_executed": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"blocked_reasons": [],
|
|
"telegram_dispatch_archive_summary_input": {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_preview",
|
|
"statement_count": 1,
|
|
"telegram_dispatch_archive_summary_ready": True,
|
|
"side_effects_clear": True,
|
|
},
|
|
"telegram_dispatch_report_input_sections": [
|
|
{"key": "executive_context", "facts": ["statement_count=1"]},
|
|
{"key": "telegram_message_evidence", "facts": ["message_id=9988"]},
|
|
{
|
|
"key": "dispatch_audit_evidence",
|
|
"facts": ["manual_dispatch_proven=True"],
|
|
},
|
|
{"key": "artifact_traceability", "facts": ["receipt_path=ok"]},
|
|
{"key": "runtime_safety", "facts": ["llm_call_executed=false"]},
|
|
],
|
|
"telegram_dispatch_report_input_contract": {
|
|
"contract_version": "market_intel_telegram_dispatch_report_input_v1",
|
|
"language": "zh-TW",
|
|
"source_mode": (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_preview"
|
|
),
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"required_sections": [
|
|
"executive_context",
|
|
"telegram_message_evidence",
|
|
"dispatch_audit_evidence",
|
|
"artifact_traceability",
|
|
"runtime_safety",
|
|
],
|
|
"evidence_refs": {
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "c" * 64,
|
|
"artifact_paths": {
|
|
"telegram_dispatch_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-receipt.json"
|
|
),
|
|
"telegram_dispatch_closeout_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-closeout.json"
|
|
),
|
|
"telegram_message_preview_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-message-preview.json"
|
|
),
|
|
"telegram_dispatch_archive_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-archive.json"
|
|
),
|
|
},
|
|
},
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_generate_report_from_telegram_dispatch_report_input_api",
|
|
"telegram_dispatch_report_input_preview_only",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"telegram_dispatch_report_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-report-run-package.json"
|
|
),
|
|
"operator_confirmed_telegram_dispatch_report_run_package": True,
|
|
"operator_confirmed_report_run_package_is_read_only": True,
|
|
"operator_confirmed_report_input_reviewed": True,
|
|
"operator_confirmed_report_package_reviewed": True,
|
|
"operator_confirmed_report_generation_requires_readiness_gate": True,
|
|
"operator_confirmed_no_token_in_report_run_package": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"report_run_package_notes": "manual report run package reviewed",
|
|
}
|
|
run_package = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package(
|
|
telegram_dispatch_report_input=report_input,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package(
|
|
telegram_dispatch_report_input=report_input,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package(
|
|
telegram_dispatch_report_input=report_input,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert run_package["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package_preview"
|
|
)
|
|
assert run_package["target_operation"] == (
|
|
"prepare_manual_market_intel_report_run_package"
|
|
)
|
|
assert run_package["telegram_dispatch_report_run_package_ready"] is True
|
|
assert (
|
|
run_package[
|
|
"summary_persistence_telegram_dispatch_report_run_package_ready"
|
|
]
|
|
is True
|
|
)
|
|
assert run_package["report_run_package_ready"] is True
|
|
assert run_package["ready_for_market_intel_report_run_readiness"] is True
|
|
assert run_package["ready_for_report_generation"] is False
|
|
assert run_package["ready_for_telegram_dispatch"] is False
|
|
assert run_package["ready_for_api_database_write"] is False
|
|
assert run_package["ready_for_scheduler_attach"] is False
|
|
assert run_package["api_dispatches_telegram"] is False
|
|
assert run_package["api_executes_llm"] is False
|
|
assert run_package["api_reads_approval_token"] is False
|
|
assert run_package["api_writes_file"] is False
|
|
assert run_package["api_writes_database"] is False
|
|
assert run_package["telegram_dispatch_report_run_package_file_written"] is False
|
|
assert run_package["report_run_package_file_written"] is False
|
|
assert run_package["telegram_dispatch_report_input_file_written"] is False
|
|
assert run_package["report_input_file_written"] is False
|
|
assert run_package["report_file_written"] is False
|
|
assert run_package["report_record_written"] is False
|
|
assert run_package["report_manifest_written"] is False
|
|
assert run_package["ai_summary_generated"] is False
|
|
assert run_package["llm_call_executed"] is False
|
|
assert run_package["telegram_dispatched"] is False
|
|
assert run_package["telegram_dispatch_attempted"] is False
|
|
assert run_package["database_connection_opened"] is False
|
|
assert run_package["database_write_executed"] is False
|
|
assert run_package["database_commit_executed"] is False
|
|
assert run_package["review_state_update_executed"] is False
|
|
assert run_package["scheduler_attached"] is False
|
|
assert run_package["statement_count"] == 1
|
|
assert run_package["blocked_reasons"] == []
|
|
assert run_package["telegram_dispatch_report_input_summary"][
|
|
"report_contract_version"
|
|
] == "market_intel_telegram_dispatch_report_input_v1"
|
|
assert run_package["telegram_dispatch_report_run_package"][
|
|
"contract_version"
|
|
] == "market_intel_telegram_dispatch_report_run_package_v1"
|
|
assert run_package["telegram_dispatch_report_run_package_sections"]
|
|
assert run_package["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_run_readiness"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_run_package_ready"] is False
|
|
assert (
|
|
"telegram_dispatch_report_run_package_no_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"telegram_dispatch_report_run_package_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_telegram_dispatch_report_run_package_api" in run_package[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_run_package_ready"] is False
|
|
assert (
|
|
data["summary_persistence_telegram_dispatch_report_run_package_ready"]
|
|
is False
|
|
)
|
|
assert data["report_run_package_ready"] is False
|
|
assert data["ready_for_market_intel_report_run_readiness"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_run_package_file_written"] is False
|
|
assert data["report_run_package_file_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["report_record_written"] is False
|
|
assert data["report_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["telegram_dispatch_attempted"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_report_input_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_preview"
|
|
)
|
|
assert "telegram_dispatch_report_input_ready" in data["blocked_reasons"]
|
|
assert "telegram_dispatch_report_run_package_artifact_path_recorded" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "operator_confirmed_telegram_dispatch_report_run_package" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_report_run_package_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_telegram_dispatch_report_run_package_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness,
|
|
)
|
|
|
|
report_run_package = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package_preview",
|
|
"target_operation": "prepare_manual_market_intel_report_run_package",
|
|
"telegram_dispatch_report_run_package_ready": True,
|
|
"summary_persistence_telegram_dispatch_report_run_package_ready": True,
|
|
"report_run_package_ready": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_run_readiness": True,
|
|
"ready_for_report_generation": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_manual_telegram_dispatch": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"ready_for_llm_call": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_report_run_package_file_written": False,
|
|
"report_run_package_file_written": False,
|
|
"telegram_dispatch_report_input_file_written": False,
|
|
"report_input_file_written": False,
|
|
"report_file_written": False,
|
|
"report_record_written": False,
|
|
"report_manifest_written": False,
|
|
"ai_summary_generated": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"external_network_executed": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"blocked_reasons": [],
|
|
"telegram_dispatch_report_run_package_sections": [
|
|
{"key": "source_report_input", "facts": ["source_mode=ok"]},
|
|
{"key": "report_contract", "facts": ["contract=ok"]},
|
|
{"key": "evidence_manifest", "facts": ["message_id=9988"]},
|
|
{"key": "execution_boundaries", "facts": ["api_generates_report=false"]},
|
|
{"key": "future_readiness_gate", "facts": ["next=readiness"]},
|
|
],
|
|
"telegram_dispatch_report_run_package": {
|
|
"contract_version": "market_intel_telegram_dispatch_report_run_package_v1",
|
|
"language": "zh-TW",
|
|
"source_mode": (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_preview"
|
|
),
|
|
"source_contract_version": (
|
|
"market_intel_telegram_dispatch_report_input_v1"
|
|
),
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"required_package_sections": [
|
|
"source_report_input",
|
|
"report_contract",
|
|
"evidence_manifest",
|
|
"execution_boundaries",
|
|
"future_readiness_gate",
|
|
],
|
|
"source_required_sections": [
|
|
"executive_context",
|
|
"telegram_message_evidence",
|
|
"dispatch_audit_evidence",
|
|
"artifact_traceability",
|
|
"runtime_safety",
|
|
],
|
|
"intended_report_artifacts": [
|
|
"telegram_dispatch_audit_report_payload",
|
|
"report_generation_readiness_packet",
|
|
],
|
|
"evidence_refs": {
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "c" * 64,
|
|
"artifact_paths": {
|
|
"telegram_dispatch_receipt_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-receipt.json"
|
|
),
|
|
"telegram_dispatch_closeout_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-closeout.json"
|
|
),
|
|
"telegram_message_preview_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-message-preview.json"
|
|
),
|
|
"telegram_dispatch_archive_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-archive.json"
|
|
),
|
|
},
|
|
},
|
|
"execution_boundaries": {
|
|
"api_generates_report": False,
|
|
"api_writes_report_file": False,
|
|
"api_calls_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_writes_database": False,
|
|
"api_attaches_scheduler": False,
|
|
},
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_generate_report_from_telegram_dispatch_report_run_package_api",
|
|
"telegram_dispatch_report_run_package_preview_only",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"telegram_dispatch_report_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-report-run-package.json"
|
|
),
|
|
"telegram_dispatch_report_run_readiness_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-report-run-readiness.json"
|
|
),
|
|
"report_output_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report.json"
|
|
),
|
|
"operator_confirmed_telegram_dispatch_report_run_readiness": True,
|
|
"operator_confirmed_report_run_package_reviewed": True,
|
|
"operator_confirmed_report_contract_reviewed": True,
|
|
"operator_confirmed_report_generation_is_manual_only": True,
|
|
"operator_confirmed_report_output_requires_receipt": True,
|
|
"operator_confirmed_no_token_in_report_readiness": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"report_run_readiness_notes": "manual report run readiness reviewed",
|
|
}
|
|
readiness = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness(
|
|
telegram_dispatch_report_run_package=report_run_package,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness(
|
|
telegram_dispatch_report_run_package=report_run_package,
|
|
operator_evidence={
|
|
**operator_evidence,
|
|
"telegram_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness(
|
|
telegram_dispatch_report_run_package=report_run_package,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert readiness["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness_preview"
|
|
)
|
|
assert readiness["target_operation"] == (
|
|
"manual_market_intel_report_run_readiness"
|
|
)
|
|
assert readiness["telegram_dispatch_report_run_readiness_ready"] is True
|
|
assert (
|
|
readiness[
|
|
"summary_persistence_telegram_dispatch_report_run_readiness_ready"
|
|
]
|
|
is True
|
|
)
|
|
assert readiness["report_run_readiness_ready"] is True
|
|
assert readiness["ready_for_market_intel_report_run_receipt"] is True
|
|
assert readiness["ready_for_manual_report_generation"] is True
|
|
assert readiness["ready_for_report_generation"] is False
|
|
assert readiness["ready_for_telegram_dispatch"] is False
|
|
assert readiness["ready_for_api_database_write"] is False
|
|
assert readiness["ready_for_scheduler_attach"] is False
|
|
assert readiness["api_dispatches_telegram"] is False
|
|
assert readiness["api_executes_llm"] is False
|
|
assert readiness["api_reads_approval_token"] is False
|
|
assert readiness["api_writes_file"] is False
|
|
assert readiness["api_writes_database"] is False
|
|
assert readiness["telegram_dispatch_report_run_readiness_file_written"] is False
|
|
assert readiness["report_run_readiness_file_written"] is False
|
|
assert readiness["report_file_written"] is False
|
|
assert readiness["report_record_written"] is False
|
|
assert readiness["report_manifest_written"] is False
|
|
assert readiness["ai_summary_generated"] is False
|
|
assert readiness["llm_call_executed"] is False
|
|
assert readiness["telegram_dispatched"] is False
|
|
assert readiness["database_connection_opened"] is False
|
|
assert readiness["database_write_executed"] is False
|
|
assert readiness["database_commit_executed"] is False
|
|
assert readiness["review_state_update_executed"] is False
|
|
assert readiness["scheduler_attached"] is False
|
|
assert readiness["statement_count"] == 1
|
|
assert readiness["blocked_reasons"] == []
|
|
assert readiness["report_generation_readiness_manifest"][
|
|
"manifest_version"
|
|
] == "market_intel_report_run_readiness_v1"
|
|
assert readiness["report_generation_readiness_manifest"][
|
|
"manual_generation_command"
|
|
]["executed_by_api"] is False
|
|
assert readiness["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_run_receipt"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_run_readiness_ready"] is False
|
|
assert (
|
|
"telegram_dispatch_report_run_readiness_no_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"telegram_dispatch_report_run_readiness_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_telegram_dispatch_report_run_readiness_api" in readiness[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_run_readiness_ready"] is False
|
|
assert (
|
|
data["summary_persistence_telegram_dispatch_report_run_readiness_ready"]
|
|
is False
|
|
)
|
|
assert data["report_run_readiness_ready"] is False
|
|
assert data["ready_for_market_intel_report_run_receipt"] is False
|
|
assert data["ready_for_manual_report_generation"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_run_readiness_file_written"] is False
|
|
assert data["report_run_readiness_file_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["report_record_written"] is False
|
|
assert data["report_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_report_run_package_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package_preview"
|
|
)
|
|
assert "telegram_dispatch_report_run_package_ready" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "report_run_readiness_artifacts_recorded" in data["blocked_reasons"]
|
|
assert "operator_confirmed_telegram_dispatch_report_run_readiness" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_report_run_readiness_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_telegram_dispatch_report_run_readiness_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt,
|
|
)
|
|
|
|
readiness = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness_preview",
|
|
"telegram_dispatch_report_run_readiness_ready": True,
|
|
"report_run_readiness_ready": True,
|
|
"ready_for_market_intel_report_run_receipt": True,
|
|
"ready_for_manual_report_generation": True,
|
|
"ready_for_report_generation": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"ready_for_llm_call": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_report_run_readiness_file_written": False,
|
|
"report_run_readiness_file_written": False,
|
|
"report_file_written": False,
|
|
"report_record_written": False,
|
|
"report_manifest_written": False,
|
|
"ai_summary_generated": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"external_network_executed": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"blocked_reasons": [],
|
|
"report_generation_readiness_manifest": {
|
|
"manifest_version": "market_intel_report_run_readiness_v1",
|
|
"source_contract_version": "market_intel_telegram_dispatch_report_input_v1",
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"intended_report_artifacts": [
|
|
"telegram_dispatch_audit_report_payload",
|
|
"report_generation_readiness_packet",
|
|
],
|
|
"required_package_sections": [
|
|
"source_report_input",
|
|
"report_contract",
|
|
"evidence_manifest",
|
|
"execution_boundaries",
|
|
"future_readiness_gate",
|
|
],
|
|
"evidence_refs": {
|
|
"message_id": "9988",
|
|
"chat_id": "-100123",
|
|
"telegram_channel_label": "market-intel-alerts",
|
|
"summary_payload_hash": "c" * 64,
|
|
},
|
|
"manual_generation_command": {
|
|
"key": "manual_market_intel_report_generation",
|
|
"executes_report_generation": True,
|
|
"executes_database": False,
|
|
"executes_telegram": False,
|
|
"executed_by_api": False,
|
|
},
|
|
"execution_boundaries": {
|
|
"api_generates_report": False,
|
|
"api_writes_report_file": False,
|
|
"api_calls_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_writes_database": False,
|
|
"api_attaches_scheduler": False,
|
|
},
|
|
},
|
|
}
|
|
report_receipt = {
|
|
"mode": "market_intel_report_generation_manual_receipt",
|
|
"report_generated": True,
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"report_output_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report.json"
|
|
),
|
|
"report_output_hash": "d" * 64,
|
|
"report_format": "json",
|
|
"summary_payload_hash": "c" * 64,
|
|
"source_readiness_manifest_version": "market_intel_report_run_readiness_v1",
|
|
"section_keys": [
|
|
"executive_context",
|
|
"telegram_message_evidence",
|
|
"dispatch_audit_evidence",
|
|
"artifact_traceability",
|
|
"runtime_safety",
|
|
],
|
|
"execution_boundaries": {
|
|
"api_generates_report": False,
|
|
"api_writes_file": False,
|
|
"api_calls_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_writes_database": False,
|
|
},
|
|
}
|
|
operator_evidence = {
|
|
"telegram_dispatch_report_run_package_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-report-run-package.json"
|
|
),
|
|
"telegram_dispatch_report_run_readiness_artifact_path": (
|
|
"artifacts/market_intel/ai-summary-telegram-dispatch-report-run-readiness.json"
|
|
),
|
|
"report_output_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report.json"
|
|
),
|
|
"report_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-receipt.json"
|
|
),
|
|
"operator_confirmed_report_run_receipt": True,
|
|
"operator_confirmed_report_output_hash_matched": True,
|
|
"operator_confirmed_report_sections_reviewed": True,
|
|
"operator_confirmed_no_token_in_report_receipt": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"report_run_receipt_notes": "manual report receipt reviewed",
|
|
}
|
|
|
|
receipt = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt(
|
|
telegram_dispatch_report_run_readiness=readiness,
|
|
report_run_receipt=report_receipt,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt(
|
|
telegram_dispatch_report_run_readiness=readiness,
|
|
report_run_receipt={**report_receipt, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt(
|
|
telegram_dispatch_report_run_readiness=readiness,
|
|
report_run_receipt=report_receipt,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert receipt["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt_preview"
|
|
)
|
|
assert receipt["target_operation"] == (
|
|
"review_manual_market_intel_report_run_receipt"
|
|
)
|
|
assert receipt["telegram_dispatch_report_run_receipt_passed"] is True
|
|
assert (
|
|
receipt[
|
|
"summary_persistence_telegram_dispatch_report_run_receipt_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert receipt["report_run_receipt_passed"] is True
|
|
assert receipt["ready_for_market_intel_report_closeout"] is True
|
|
assert receipt["ready_for_report_generation"] is False
|
|
assert receipt["ready_for_telegram_dispatch"] is False
|
|
assert receipt["ready_for_api_database_write"] is False
|
|
assert receipt["ready_for_scheduler_attach"] is False
|
|
assert receipt["api_dispatches_telegram"] is False
|
|
assert receipt["api_executes_llm"] is False
|
|
assert receipt["api_reads_approval_token"] is False
|
|
assert receipt["api_writes_file"] is False
|
|
assert receipt["api_writes_database"] is False
|
|
assert receipt["telegram_dispatch_report_run_receipt_file_written"] is False
|
|
assert receipt["report_run_receipt_file_written"] is False
|
|
assert receipt["report_receipt_file_written"] is False
|
|
assert receipt["report_output_file_written"] is False
|
|
assert receipt["report_file_written"] is False
|
|
assert receipt["report_record_written"] is False
|
|
assert receipt["report_manifest_written"] is False
|
|
assert receipt["ai_summary_generated"] is False
|
|
assert receipt["llm_call_executed"] is False
|
|
assert receipt["telegram_dispatched"] is False
|
|
assert receipt["database_connection_opened"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["database_commit_executed"] is False
|
|
assert receipt["review_state_update_executed"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert receipt["statement_count"] == 1
|
|
assert receipt["blocked_reasons"] == []
|
|
assert receipt["telegram_dispatch_report_run_receipt_summary"][
|
|
"summary_payload_hash_matches_expected"
|
|
] is True
|
|
assert receipt["telegram_dispatch_report_run_receipt_summary"][
|
|
"required_report_sections_present"
|
|
] is True
|
|
assert receipt["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_closeout"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_run_receipt_passed"] is False
|
|
assert "report_run_receipt_no_token_key" in token_leak["blocked_reasons"]
|
|
assert (
|
|
"report_run_receipt_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_run_receipt_api" in receipt[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_run_receipt_passed"] is False
|
|
assert (
|
|
data["summary_persistence_telegram_dispatch_report_run_receipt_passed"]
|
|
is False
|
|
)
|
|
assert data["report_run_receipt_passed"] is False
|
|
assert data["ready_for_market_intel_report_closeout"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_run_receipt_file_written"] is False
|
|
assert data["report_run_receipt_file_written"] is False
|
|
assert data["report_receipt_file_written"] is False
|
|
assert data["report_output_file_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["report_record_written"] is False
|
|
assert data["report_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_report_run_readiness_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness_preview"
|
|
)
|
|
assert "report_run_readiness_passed_before_manual_report_generation" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "report_run_receipt_provided" in data["blocked_reasons"]
|
|
assert "operator_confirmed_report_run_receipt" in data["blocked_reasons"]
|
|
assert (
|
|
"report_run_receipt_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_run_receipt_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout,
|
|
)
|
|
|
|
report_run_receipt = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt_preview",
|
|
"target_operation": "review_manual_market_intel_report_run_receipt",
|
|
"telegram_dispatch_report_run_receipt_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_run_receipt_passed": True,
|
|
"report_run_receipt_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_closeout": True,
|
|
"ready_for_report_generation": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_report_run_receipt_file_written": False,
|
|
"report_run_receipt_file_written": False,
|
|
"report_file_written": False,
|
|
"report_record_written": False,
|
|
"report_manifest_written": False,
|
|
"ai_summary_generated": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"blocked_reasons": [],
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"telegram_dispatch_report_run_readiness_summary": {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness_preview",
|
|
"telegram_dispatch_report_run_readiness_ready": True,
|
|
"ready_for_market_intel_report_run_receipt": True,
|
|
"manifest_version": "market_intel_report_run_readiness_v1",
|
|
},
|
|
"telegram_dispatch_report_run_receipt_summary": {
|
|
"provided": True,
|
|
"mode": "market_intel_report_generation_manual_receipt",
|
|
"report_generated": True,
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"report_output_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report.json"
|
|
),
|
|
"report_output_hash": "d" * 64,
|
|
"summary_payload_hash": "c" * 64,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"required_report_sections_present": True,
|
|
"section_keys": [
|
|
"executive_context",
|
|
"telegram_message_evidence",
|
|
"dispatch_audit_evidence",
|
|
"artifact_traceability",
|
|
"runtime_safety",
|
|
],
|
|
"approval_or_telegram_token_key_detected": False,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_run_receipt_api",
|
|
"do_not_read_telegram_token_from_report_run_receipt_api",
|
|
"do_not_call_llm_from_report_run_receipt",
|
|
"do_not_generate_report_from_report_run_receipt_api",
|
|
"do_not_write_report_artifact_from_report_run_receipt_api",
|
|
"do_not_dispatch_telegram_from_report_run_receipt_api",
|
|
"do_not_open_database_connection_from_report_run_receipt",
|
|
"do_not_update_review_state_from_report_run_receipt",
|
|
"do_not_attach_scheduler_from_report_run_receipt",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_closeout_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-closeout.json"
|
|
),
|
|
"report_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-receipt.json"
|
|
),
|
|
"report_output_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report.json"
|
|
),
|
|
"operator_confirmed_report_closeout": True,
|
|
"operator_confirmed_report_receipt_archived": True,
|
|
"operator_confirmed_report_output_hash_matched": True,
|
|
"operator_confirmed_report_sections_reviewed": True,
|
|
"operator_confirmed_report_archive_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_closeout": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"report_closeout_notes": "manual report closeout reviewed",
|
|
}
|
|
|
|
closeout = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout(
|
|
telegram_dispatch_report_run_receipt=report_run_receipt,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout(
|
|
telegram_dispatch_report_run_receipt=report_run_receipt,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout(
|
|
telegram_dispatch_report_run_receipt=report_run_receipt,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert closeout["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout_preview"
|
|
)
|
|
assert closeout["target_operation"] == "closeout_manual_market_intel_report"
|
|
assert closeout["telegram_dispatch_report_closeout_passed"] is True
|
|
assert (
|
|
closeout[
|
|
"summary_persistence_telegram_dispatch_report_closeout_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert closeout["report_closeout_passed"] is True
|
|
assert closeout["ready_for_market_intel_report_archive"] is True
|
|
assert closeout["ready_for_report_generation"] is False
|
|
assert closeout["ready_for_telegram_dispatch"] is False
|
|
assert closeout["ready_for_api_database_write"] is False
|
|
assert closeout["ready_for_scheduler_attach"] is False
|
|
assert closeout["api_dispatches_telegram"] is False
|
|
assert closeout["api_executes_llm"] is False
|
|
assert closeout["api_reads_approval_token"] is False
|
|
assert closeout["api_writes_file"] is False
|
|
assert closeout["api_writes_database"] is False
|
|
assert closeout["telegram_dispatch_report_closeout_file_written"] is False
|
|
assert closeout["report_closeout_file_written"] is False
|
|
assert closeout["report_file_written"] is False
|
|
assert closeout["telegram_dispatched"] is False
|
|
assert closeout["database_connection_opened"] is False
|
|
assert closeout["database_write_executed"] is False
|
|
assert closeout["database_commit_executed"] is False
|
|
assert closeout["review_state_update_executed"] is False
|
|
assert closeout["scheduler_attached"] is False
|
|
assert closeout["blocked_reasons"] == []
|
|
assert closeout["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_archive"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_closeout_passed"] is False
|
|
assert "report_closeout_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_closeout_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_closeout_api" in closeout[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_closeout_passed"] is False
|
|
assert (
|
|
data["summary_persistence_telegram_dispatch_report_closeout_passed"]
|
|
is False
|
|
)
|
|
assert data["report_closeout_passed"] is False
|
|
assert data["ready_for_market_intel_report_archive"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_closeout_file_written"] is False
|
|
assert data["report_closeout_file_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_run_receipt_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt_preview"
|
|
)
|
|
assert "report_run_receipt_passed" in data["blocked_reasons"]
|
|
assert "report_closeout_artifacts_recorded" in data["blocked_reasons"]
|
|
assert "operator_confirmed_report_closeout" in data["blocked_reasons"]
|
|
assert (
|
|
"report_closeout_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_closeout_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive,
|
|
)
|
|
|
|
report_closeout = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout_preview",
|
|
"target_operation": "closeout_manual_market_intel_report",
|
|
"telegram_dispatch_report_closeout_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_closeout_passed": True,
|
|
"report_closeout_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_archive": True,
|
|
"ready_for_report_generation": False,
|
|
"ready_for_api_database_write": False,
|
|
"ready_for_telegram_dispatch": False,
|
|
"ready_for_scheduler_attach": False,
|
|
"api_executes_cli": False,
|
|
"api_executes_llm": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_reads_approval_token": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_updates_review_state": False,
|
|
"telegram_dispatch_report_closeout_file_written": False,
|
|
"report_closeout_file_written": False,
|
|
"report_file_written": False,
|
|
"report_record_written": False,
|
|
"report_manifest_written": False,
|
|
"archive_file_written": False,
|
|
"archive_record_written": False,
|
|
"archive_manifest_written": False,
|
|
"ai_summary_generated": False,
|
|
"llm_call_executed": False,
|
|
"telegram_dispatched": False,
|
|
"telegram_dispatch_attempted": False,
|
|
"database_connection_opened": False,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"review_state_update_executed": False,
|
|
"scheduler_attached": False,
|
|
"blocked_reasons": [],
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"telegram_dispatch_report_run_receipt_summary": {
|
|
"provided": True,
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt_preview",
|
|
"report_receipt_mode": "market_intel_report_generation_manual_receipt",
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"report_output_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report.json"
|
|
),
|
|
"report_output_hash": "d" * 64,
|
|
"summary_payload_hash": "c" * 64,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"required_report_sections_present": True,
|
|
"section_keys": [
|
|
"executive_context",
|
|
"telegram_message_evidence",
|
|
"dispatch_audit_evidence",
|
|
"artifact_traceability",
|
|
"runtime_safety",
|
|
],
|
|
},
|
|
"operator_telegram_dispatch_report_closeout": {
|
|
"report_closeout_artifact_path_recorded": True,
|
|
"report_run_receipt_artifact_path_recorded": True,
|
|
"report_output_artifact_path_recorded": True,
|
|
"operator_confirmed_report_closeout": True,
|
|
"operator_confirmed_report_receipt_archived": True,
|
|
"operator_confirmed_report_output_hash_matched": True,
|
|
"operator_confirmed_report_sections_reviewed": True,
|
|
"operator_confirmed_report_archive_requires_separate_gate": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_archive",
|
|
"report_archive_requires_separate_gate": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_closeout_api",
|
|
"do_not_read_telegram_token_from_report_closeout_api",
|
|
"do_not_call_llm_from_report_closeout",
|
|
"do_not_generate_report_from_report_closeout_api",
|
|
"do_not_write_report_artifact_from_report_closeout_api",
|
|
"do_not_dispatch_telegram_from_report_closeout_api",
|
|
"do_not_open_database_connection_from_report_closeout",
|
|
"do_not_update_review_state_from_report_closeout",
|
|
"do_not_attach_scheduler_from_report_closeout",
|
|
"future_market_intel_report_archive_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_archive_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-archive.json"
|
|
),
|
|
"report_closeout_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-closeout.json"
|
|
),
|
|
"report_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-receipt.json"
|
|
),
|
|
"report_output_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report.json"
|
|
),
|
|
"operator_confirmed_report_archive": True,
|
|
"operator_confirmed_report_closeout_archived": True,
|
|
"operator_confirmed_report_receipt_archived": True,
|
|
"operator_confirmed_report_output_archived": True,
|
|
"operator_confirmed_report_output_hash_matched": True,
|
|
"operator_confirmed_report_sections_reviewed": True,
|
|
"operator_confirmed_archive_manifest_reviewed": True,
|
|
"operator_confirmed_archive_retention_policy_recorded": True,
|
|
"operator_confirmed_report_archive_summary_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_archive": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"report_archive_notes": "manual report archive reviewed",
|
|
}
|
|
|
|
archive = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive(
|
|
telegram_dispatch_report_closeout=report_closeout,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive(
|
|
telegram_dispatch_report_closeout=report_closeout,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive(
|
|
telegram_dispatch_report_closeout=report_closeout,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert archive["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_preview"
|
|
)
|
|
assert archive["target_operation"] == "archive_manual_market_intel_report"
|
|
assert archive["telegram_dispatch_report_archive_passed"] is True
|
|
assert (
|
|
archive[
|
|
"summary_persistence_telegram_dispatch_report_archive_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert archive["report_archive_passed"] is True
|
|
assert archive["ready_for_market_intel_report_archive_summary"] is True
|
|
assert archive["ready_for_report_generation"] is False
|
|
assert archive["ready_for_telegram_dispatch"] is False
|
|
assert archive["ready_for_api_database_write"] is False
|
|
assert archive["ready_for_scheduler_attach"] is False
|
|
assert archive["api_dispatches_telegram"] is False
|
|
assert archive["api_executes_llm"] is False
|
|
assert archive["api_reads_approval_token"] is False
|
|
assert archive["api_writes_file"] is False
|
|
assert archive["api_writes_database"] is False
|
|
assert archive["telegram_dispatch_report_archive_file_written"] is False
|
|
assert archive["report_archive_file_written"] is False
|
|
assert archive["archive_file_written"] is False
|
|
assert archive["report_file_written"] is False
|
|
assert archive["telegram_dispatched"] is False
|
|
assert archive["database_connection_opened"] is False
|
|
assert archive["database_write_executed"] is False
|
|
assert archive["database_commit_executed"] is False
|
|
assert archive["review_state_update_executed"] is False
|
|
assert archive["scheduler_attached"] is False
|
|
assert archive["blocked_reasons"] == []
|
|
assert archive["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_archive_summary"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_archive_passed"] is False
|
|
assert "report_archive_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_archive_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_archive_api" in archive[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_archive_passed"] is False
|
|
assert (
|
|
data["summary_persistence_telegram_dispatch_report_archive_passed"]
|
|
is False
|
|
)
|
|
assert data["report_archive_passed"] is False
|
|
assert data["ready_for_market_intel_report_archive_summary"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_archive_file_written"] is False
|
|
assert data["report_archive_file_written"] is False
|
|
assert data["archive_file_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_closeout_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout_preview"
|
|
)
|
|
assert "report_closeout_passed" in data["blocked_reasons"]
|
|
assert "report_archive_artifacts_recorded" in data["blocked_reasons"]
|
|
assert "operator_confirmed_report_archive" in data["blocked_reasons"]
|
|
assert (
|
|
"report_archive_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_archive_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary,
|
|
)
|
|
|
|
report_archive = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_preview",
|
|
"target_operation": "archive_manual_market_intel_report",
|
|
"telegram_dispatch_report_archive_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_archive_passed": True,
|
|
"report_archive_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_archive_summary": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "c" * 64,
|
|
"telegram_dispatch_report_closeout_summary": {
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"report_output_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report.json"
|
|
),
|
|
"report_output_hash": "d" * 64,
|
|
"summary_payload_hash": "c" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"required_report_sections_present": True,
|
|
"section_keys": [
|
|
"executive_context",
|
|
"telegram_message_evidence",
|
|
"dispatch_audit_evidence",
|
|
"artifact_traceability",
|
|
"runtime_safety",
|
|
],
|
|
},
|
|
"operator_telegram_dispatch_report_archive": {
|
|
"report_archive_artifact_path_recorded": True,
|
|
"report_closeout_artifact_path_recorded": True,
|
|
"report_run_receipt_artifact_path_recorded": True,
|
|
"report_output_artifact_path_recorded": True,
|
|
"operator_confirmed_report_archive": True,
|
|
"operator_confirmed_report_closeout_archived": True,
|
|
"operator_confirmed_report_receipt_archived": True,
|
|
"operator_confirmed_report_output_archived": True,
|
|
"operator_confirmed_report_output_hash_matched": True,
|
|
"operator_confirmed_report_sections_reviewed": True,
|
|
"operator_confirmed_archive_manifest_reviewed": True,
|
|
"operator_confirmed_archive_retention_policy_recorded": True,
|
|
"operator_confirmed_report_archive_summary_requires_separate_gate": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_archive_summary",
|
|
"report_archive_summary_requires_separate_gate": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_archive_api",
|
|
"do_not_read_telegram_token_from_report_archive_api",
|
|
"do_not_call_llm_from_report_archive",
|
|
"do_not_generate_report_from_report_archive_api",
|
|
"do_not_write_archive_artifact_from_report_archive_api",
|
|
"do_not_dispatch_telegram_from_report_archive_api",
|
|
"do_not_open_database_connection_from_report_archive",
|
|
"do_not_update_review_state_from_report_archive",
|
|
"do_not_attach_scheduler_from_report_archive",
|
|
"future_market_intel_report_archive_summary_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_archive_summary_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-archive-summary.json"
|
|
),
|
|
"report_archive_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-archive.json"
|
|
),
|
|
"report_closeout_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-closeout.json"
|
|
),
|
|
"report_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report-receipt.json"
|
|
),
|
|
"report_output_artifact_path": (
|
|
"artifacts/market_intel/telegram-dispatch-audit-report.json"
|
|
),
|
|
"operator_confirmed_report_archive_summary": True,
|
|
"operator_confirmed_report_archive_summary_read_only": True,
|
|
"operator_confirmed_report_archive_reviewed": True,
|
|
"operator_confirmed_report_traceability_reviewed": True,
|
|
"operator_confirmed_report_catalog_handoff_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_archive_summary": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"report_archive_summary_notes": "manual report archive summary reviewed",
|
|
}
|
|
|
|
summary = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary(
|
|
telegram_dispatch_report_archive=report_archive,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary(
|
|
telegram_dispatch_report_archive=report_archive,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary(
|
|
telegram_dispatch_report_archive=report_archive,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert summary["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary_preview"
|
|
)
|
|
assert summary["target_operation"] == "summarize_archived_market_intel_report"
|
|
assert summary["telegram_dispatch_report_archive_summary_passed"] is True
|
|
assert (
|
|
summary[
|
|
"summary_persistence_telegram_dispatch_report_archive_summary_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert summary["report_archive_summary_passed"] is True
|
|
assert summary["ready_for_market_intel_report_catalog_handoff"] is True
|
|
assert summary["ready_for_report_generation"] is False
|
|
assert summary["ready_for_telegram_dispatch"] is False
|
|
assert summary["ready_for_api_database_write"] is False
|
|
assert summary["ready_for_scheduler_attach"] is False
|
|
assert summary["api_dispatches_telegram"] is False
|
|
assert summary["api_executes_llm"] is False
|
|
assert summary["api_reads_approval_token"] is False
|
|
assert summary["api_writes_file"] is False
|
|
assert summary["api_writes_database"] is False
|
|
assert summary["telegram_dispatch_report_archive_summary_file_written"] is False
|
|
assert summary["report_archive_summary_file_written"] is False
|
|
assert summary["archive_summary_file_written"] is False
|
|
assert summary["report_file_written"] is False
|
|
assert summary["telegram_dispatched"] is False
|
|
assert summary["database_connection_opened"] is False
|
|
assert summary["database_write_executed"] is False
|
|
assert summary["database_commit_executed"] is False
|
|
assert summary["review_state_update_executed"] is False
|
|
assert summary["scheduler_attached"] is False
|
|
assert summary["telegram_dispatch_report_archive_summary_sections"][0][
|
|
"key"
|
|
] == "report_identity"
|
|
assert summary["blocked_reasons"] == []
|
|
assert summary["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_handoff"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_archive_summary_passed"] is False
|
|
assert "report_archive_summary_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_archive_summary_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_archive_summary_api" in summary[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_archive_summary_passed"] is False
|
|
assert (
|
|
data["summary_persistence_telegram_dispatch_report_archive_summary_passed"]
|
|
is False
|
|
)
|
|
assert data["report_archive_summary_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_handoff"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_archive_summary_file_written"] is False
|
|
assert data["report_archive_summary_file_written"] is False
|
|
assert data["archive_summary_file_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_archive_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_preview"
|
|
)
|
|
assert "report_archive_passed" in data["blocked_reasons"]
|
|
assert "report_archive_summary_artifacts_recorded" in data["blocked_reasons"]
|
|
assert "operator_confirmed_report_archive_summary" in data["blocked_reasons"]
|
|
assert (
|
|
"report_archive_summary_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_archive_summary_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff,
|
|
)
|
|
|
|
archive_summary = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary_preview",
|
|
"target_operation": "summarize_archived_market_intel_report",
|
|
"telegram_dispatch_report_archive_summary_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_archive_summary_passed": True,
|
|
"report_archive_summary_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_handoff": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"telegram_dispatch_report_archive_summary": {
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"report_output_hash": "f" * 64,
|
|
"summary_payload_hash": "e" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"required_report_sections_present": True,
|
|
},
|
|
"telegram_dispatch_report_archive_summary_sections": [
|
|
{"key": "report_identity"},
|
|
{"key": "archive_traceability"},
|
|
{"key": "integrity_review"},
|
|
{"key": "runtime_safety"},
|
|
],
|
|
"operator_telegram_dispatch_report_archive_summary": {
|
|
"report_archive_summary_artifact_path": "artifacts/market_intel/archive-summary.json",
|
|
"report_archive_artifact_path_recorded": True,
|
|
"report_closeout_artifact_path_recorded": True,
|
|
"report_run_receipt_artifact_path_recorded": True,
|
|
"report_output_artifact_path_recorded": True,
|
|
"operator_confirmed_report_archive_summary": True,
|
|
"operator_confirmed_summary_is_read_only": True,
|
|
"operator_confirmed_report_archive_reviewed": True,
|
|
"operator_confirmed_report_traceability_reviewed": True,
|
|
"operator_confirmed_report_catalog_handoff_requires_separate_gate": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_handoff",
|
|
"report_catalog_handoff_requires_separate_gate": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_archive_summary_api",
|
|
"do_not_read_telegram_token_from_report_archive_summary_api",
|
|
"do_not_call_llm_from_report_archive_summary",
|
|
"do_not_generate_report_from_report_archive_summary_api",
|
|
"do_not_write_report_archive_summary_artifact_from_api",
|
|
"do_not_dispatch_telegram_from_report_archive_summary_api",
|
|
"do_not_open_database_connection_from_report_archive_summary",
|
|
"do_not_update_review_state_from_report_archive_summary",
|
|
"do_not_attach_scheduler_from_report_archive_summary",
|
|
"future_market_intel_report_catalog_handoff_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_handoff_artifact_path": "artifacts/market_intel/catalog-handoff.json",
|
|
"report_archive_summary_artifact_path": "artifacts/market_intel/archive-summary.json",
|
|
"report_archive_artifact_path": "artifacts/market_intel/archive.json",
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"catalog_record_key": "market_intel_telegram_dispatch_audit_report:2026-05-20",
|
|
"catalog_family": "market_intel_telegram_dispatch_audit_report",
|
|
"operator_confirmed_report_catalog_handoff": True,
|
|
"operator_confirmed_catalog_handoff_is_read_only": True,
|
|
"operator_confirmed_report_archive_summary_reviewed": True,
|
|
"operator_confirmed_catalog_identity_reviewed": True,
|
|
"operator_confirmed_report_catalog_index_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_catalog_handoff": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_handoff_notes": "manual report catalog handoff reviewed",
|
|
}
|
|
|
|
handoff = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff(
|
|
telegram_dispatch_report_archive_summary=archive_summary,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff(
|
|
telegram_dispatch_report_archive_summary=archive_summary,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff(
|
|
telegram_dispatch_report_archive_summary=archive_summary,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert handoff["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff_preview"
|
|
)
|
|
assert handoff["target_operation"] == "handoff_archived_market_intel_report_to_catalog"
|
|
assert handoff["telegram_dispatch_report_catalog_handoff_passed"] is True
|
|
assert handoff["summary_persistence_telegram_dispatch_report_catalog_handoff_passed"] is True
|
|
assert handoff["report_catalog_handoff_passed"] is True
|
|
assert handoff["ready_for_market_intel_report_catalog_index"] is True
|
|
assert handoff["ready_for_market_intel_report_catalog_write_preflight"] is False
|
|
assert handoff["ready_for_report_generation"] is False
|
|
assert handoff["ready_for_telegram_dispatch"] is False
|
|
assert handoff["ready_for_api_database_write"] is False
|
|
assert handoff["api_dispatches_telegram"] is False
|
|
assert handoff["api_executes_llm"] is False
|
|
assert handoff["api_reads_approval_token"] is False
|
|
assert handoff["api_writes_file"] is False
|
|
assert handoff["api_writes_database"] is False
|
|
assert handoff["telegram_dispatch_report_catalog_handoff_file_written"] is False
|
|
assert handoff["report_catalog_handoff_file_written"] is False
|
|
assert handoff["catalog_record_written"] is False
|
|
assert handoff["catalog_index_written"] is False
|
|
assert handoff["report_file_written"] is False
|
|
assert handoff["telegram_dispatched"] is False
|
|
assert handoff["database_connection_opened"] is False
|
|
assert handoff["database_write_executed"] is False
|
|
assert handoff["database_commit_executed"] is False
|
|
assert handoff["review_state_update_executed"] is False
|
|
assert handoff["scheduler_attached"] is False
|
|
assert handoff["telegram_dispatch_report_catalog_handoff_sections"][0][
|
|
"key"
|
|
] == "catalog_identity"
|
|
assert handoff["blocked_reasons"] == []
|
|
assert handoff["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_index"
|
|
)
|
|
assert handoff["promotion_gate"]["report_catalog_index_requires_separate_gate"] is True
|
|
assert token_leak["telegram_dispatch_report_catalog_handoff_passed"] is False
|
|
assert "report_catalog_handoff_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_handoff_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_catalog_handoff_api" in handoff[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_handoff_passed"] is False
|
|
assert data["summary_persistence_telegram_dispatch_report_catalog_handoff_passed"] is False
|
|
assert data["report_catalog_handoff_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_index"] is False
|
|
assert data["ready_for_market_intel_report_catalog_write_preflight"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_catalog_handoff_file_written"] is False
|
|
assert data["report_catalog_handoff_file_written"] is False
|
|
assert data["catalog_handoff_file_written"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_index_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_archive_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary_preview"
|
|
)
|
|
assert "report_archive_summary_passed" in data["blocked_reasons"]
|
|
assert "operator_confirmed_report_catalog_handoff" in data["blocked_reasons"]
|
|
assert (
|
|
"report_catalog_handoff_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_catalog_handoff_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index,
|
|
)
|
|
|
|
catalog_handoff = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff_preview",
|
|
"target_operation": "handoff_archived_market_intel_report_to_catalog",
|
|
"telegram_dispatch_report_catalog_handoff_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_handoff_passed": True,
|
|
"report_catalog_handoff_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_index": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"telegram_dispatch_report_archive_summary": {
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"report_output_hash": "f" * 64,
|
|
"summary_payload_hash": "e" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"required_report_sections_present": True,
|
|
},
|
|
"telegram_dispatch_report_catalog_handoff_sections": [
|
|
{"key": "catalog_identity"},
|
|
{"key": "archive_summary_trace"},
|
|
{"key": "artifact_manifest"},
|
|
{"key": "runtime_safety"},
|
|
],
|
|
"operator_telegram_dispatch_report_catalog_handoff": {
|
|
"report_catalog_handoff_artifact_path": "artifacts/market_intel/catalog-handoff.json",
|
|
"report_archive_summary_artifact_path_recorded": True,
|
|
"report_archive_artifact_path_recorded": True,
|
|
"report_output_artifact_path_recorded": True,
|
|
"catalog_record_key_recorded": True,
|
|
"catalog_family_recorded": True,
|
|
"operator_confirmed_report_catalog_handoff": True,
|
|
"operator_confirmed_catalog_handoff_is_read_only": True,
|
|
"operator_confirmed_report_archive_summary_reviewed": True,
|
|
"operator_confirmed_catalog_identity_reviewed": True,
|
|
"operator_confirmed_report_catalog_index_requires_separate_gate": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_index",
|
|
"report_catalog_index_requires_separate_gate": True,
|
|
"report_catalog_write_preflight_requires_separate_gate": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_handoff_api",
|
|
"do_not_read_telegram_token_from_report_catalog_handoff_api",
|
|
"do_not_call_llm_from_report_catalog_handoff",
|
|
"do_not_generate_report_from_report_catalog_handoff_api",
|
|
"do_not_write_report_catalog_handoff_artifact_from_api",
|
|
"do_not_write_report_catalog_record_from_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_handoff_api",
|
|
"do_not_open_database_connection_from_report_catalog_handoff",
|
|
"do_not_update_review_state_from_report_catalog_handoff",
|
|
"do_not_attach_scheduler_from_report_catalog_handoff",
|
|
"future_market_intel_report_catalog_index_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_index_artifact_path": "artifacts/market_intel/catalog-index.json",
|
|
"report_catalog_handoff_artifact_path": "artifacts/market_intel/catalog-handoff.json",
|
|
"report_archive_summary_artifact_path": "artifacts/market_intel/archive-summary.json",
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"catalog_record_key": "market_intel_telegram_dispatch_audit_report:2026-05-20",
|
|
"catalog_family": "market_intel_telegram_dispatch_audit_report",
|
|
"catalog_index_key": "market_intel_telegram_dispatch_audit_report:index:2026-05-20",
|
|
"operator_confirmed_report_catalog_index": True,
|
|
"operator_confirmed_catalog_index_is_read_only": True,
|
|
"operator_confirmed_report_catalog_handoff_reviewed": True,
|
|
"operator_confirmed_catalog_manifest_reviewed": True,
|
|
"operator_confirmed_report_catalog_write_preflight_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_catalog_index": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_index_notes": "manual report catalog index reviewed",
|
|
}
|
|
|
|
index = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index(
|
|
telegram_dispatch_report_catalog_handoff=catalog_handoff,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index(
|
|
telegram_dispatch_report_catalog_handoff=catalog_handoff,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index(
|
|
telegram_dispatch_report_catalog_handoff=catalog_handoff,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert index["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index_preview"
|
|
)
|
|
assert index["target_operation"] == "index_archived_market_intel_report_catalog_handoff"
|
|
assert index["telegram_dispatch_report_catalog_index_passed"] is True
|
|
assert index["summary_persistence_telegram_dispatch_report_catalog_index_passed"] is True
|
|
assert index["report_catalog_index_passed"] is True
|
|
assert index["ready_for_market_intel_report_catalog_write_preflight"] is True
|
|
assert index["ready_for_market_intel_report_catalog_record_write"] is False
|
|
assert index["ready_for_report_generation"] is False
|
|
assert index["ready_for_telegram_dispatch"] is False
|
|
assert index["ready_for_api_database_write"] is False
|
|
assert index["api_dispatches_telegram"] is False
|
|
assert index["api_executes_llm"] is False
|
|
assert index["api_reads_approval_token"] is False
|
|
assert index["api_writes_file"] is False
|
|
assert index["api_writes_database"] is False
|
|
assert index["telegram_dispatch_report_catalog_index_file_written"] is False
|
|
assert index["report_catalog_index_file_written"] is False
|
|
assert index["catalog_index_file_written"] is False
|
|
assert index["catalog_record_written"] is False
|
|
assert index["catalog_index_written"] is False
|
|
assert index["report_file_written"] is False
|
|
assert index["telegram_dispatched"] is False
|
|
assert index["database_connection_opened"] is False
|
|
assert index["database_write_executed"] is False
|
|
assert index["database_commit_executed"] is False
|
|
assert index["review_state_update_executed"] is False
|
|
assert index["scheduler_attached"] is False
|
|
assert index["telegram_dispatch_report_catalog_index_sections"][0][
|
|
"key"
|
|
] == "catalog_index_identity"
|
|
assert index["blocked_reasons"] == []
|
|
assert index["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_write_preflight"
|
|
)
|
|
assert (
|
|
index["promotion_gate"]["report_catalog_write_preflight_requires_separate_gate"]
|
|
is True
|
|
)
|
|
assert token_leak["telegram_dispatch_report_catalog_index_passed"] is False
|
|
assert "report_catalog_index_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_index_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_catalog_index_api" in index[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_index_passed"] is False
|
|
assert data["summary_persistence_telegram_dispatch_report_catalog_index_passed"] is False
|
|
assert data["report_catalog_index_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_write_preflight"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_write"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_catalog_index_file_written"] is False
|
|
assert data["report_catalog_index_file_written"] is False
|
|
assert data["catalog_index_file_written"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_index_written"] is False
|
|
assert data["report_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_handoff"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff_preview"
|
|
)
|
|
assert "report_catalog_handoff_passed" in data["blocked_reasons"]
|
|
assert "operator_confirmed_report_catalog_index" in data["blocked_reasons"]
|
|
assert (
|
|
"report_catalog_index_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_catalog_index_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight,
|
|
)
|
|
|
|
catalog_index = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index_preview",
|
|
"target_operation": "index_archived_market_intel_report_catalog_handoff",
|
|
"telegram_dispatch_report_catalog_index_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_index_passed": True,
|
|
"report_catalog_index_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_write_preflight": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"telegram_dispatch_report_catalog_handoff": {
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"report_output_hash": "f" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"required_report_sections_present": True,
|
|
},
|
|
"telegram_dispatch_report_catalog_index_sections": [
|
|
{"key": "catalog_index_identity"},
|
|
{"key": "catalog_source_trace"},
|
|
{"key": "index_manifest"},
|
|
{"key": "runtime_safety"},
|
|
],
|
|
"operator_telegram_dispatch_report_catalog_index": {
|
|
"report_catalog_index_artifact_path": "artifacts/market_intel/catalog-index.json",
|
|
"report_catalog_handoff_artifact_path_recorded": True,
|
|
"report_archive_summary_artifact_path_recorded": True,
|
|
"report_output_artifact_path_recorded": True,
|
|
"catalog_record_key_recorded": True,
|
|
"catalog_family_recorded": True,
|
|
"catalog_index_key_recorded": True,
|
|
"operator_confirmed_report_catalog_index": True,
|
|
"operator_confirmed_catalog_index_is_read_only": True,
|
|
"operator_confirmed_report_catalog_handoff_reviewed": True,
|
|
"operator_confirmed_catalog_manifest_reviewed": True,
|
|
"operator_confirmed_report_catalog_write_preflight_requires_separate_gate": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_write_preflight",
|
|
"report_catalog_write_preflight_requires_separate_gate": True,
|
|
"report_catalog_record_write_requires_separate_gate": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_index_api",
|
|
"do_not_read_telegram_token_from_report_catalog_index_api",
|
|
"do_not_call_llm_from_report_catalog_index",
|
|
"do_not_generate_report_from_report_catalog_index_api",
|
|
"do_not_write_report_catalog_index_artifact_from_api",
|
|
"do_not_write_report_catalog_record_from_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_index_api",
|
|
"do_not_open_database_connection_from_report_catalog_index",
|
|
"do_not_update_review_state_from_report_catalog_index",
|
|
"do_not_attach_scheduler_from_report_catalog_index",
|
|
"future_market_intel_report_catalog_write_preflight_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_write_preflight_artifact_path": (
|
|
"artifacts/market_intel/catalog-write-preflight.json"
|
|
),
|
|
"report_catalog_index_artifact_path": "artifacts/market_intel/catalog-index.json",
|
|
"report_catalog_handoff_artifact_path": "artifacts/market_intel/catalog-handoff.json",
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"catalog_record_key": "market_intel_telegram_dispatch_audit_report:2026-05-20",
|
|
"catalog_family": "market_intel_telegram_dispatch_audit_report",
|
|
"catalog_index_key": "market_intel_telegram_dispatch_audit_report:index:2026-05-20",
|
|
"catalog_record_schema": "market_intel_report_catalog_v1",
|
|
"operator_confirmed_report_catalog_write_preflight": True,
|
|
"operator_confirmed_catalog_write_preflight_is_read_only": True,
|
|
"operator_confirmed_report_catalog_index_reviewed": True,
|
|
"operator_confirmed_catalog_record_schema_reviewed": True,
|
|
"operator_confirmed_report_catalog_record_write_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_catalog_write_preflight": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_write_preflight_notes": "manual report catalog write preflight reviewed",
|
|
}
|
|
|
|
preflight = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight(
|
|
telegram_dispatch_report_catalog_index=catalog_index,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight(
|
|
telegram_dispatch_report_catalog_index=catalog_index,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight(
|
|
telegram_dispatch_report_catalog_index=catalog_index,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert preflight["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight_preview"
|
|
)
|
|
assert preflight["target_operation"] == (
|
|
"preflight_market_intel_report_catalog_record_write"
|
|
)
|
|
assert preflight["telegram_dispatch_report_catalog_write_preflight_passed"] is True
|
|
assert (
|
|
preflight[
|
|
"summary_persistence_telegram_dispatch_report_catalog_write_preflight_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert preflight["report_catalog_write_preflight_passed"] is True
|
|
assert preflight["ready_for_market_intel_report_catalog_record_write"] is True
|
|
assert preflight["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert preflight["ready_for_report_generation"] is False
|
|
assert preflight["ready_for_telegram_dispatch"] is False
|
|
assert preflight["ready_for_api_database_write"] is False
|
|
assert preflight["api_dispatches_telegram"] is False
|
|
assert preflight["api_executes_llm"] is False
|
|
assert preflight["api_reads_approval_token"] is False
|
|
assert preflight["api_writes_file"] is False
|
|
assert preflight["api_writes_database"] is False
|
|
assert preflight["telegram_dispatch_report_catalog_write_preflight_file_written"] is False
|
|
assert preflight["report_catalog_write_preflight_file_written"] is False
|
|
assert preflight["catalog_write_preflight_file_written"] is False
|
|
assert preflight["catalog_record_written"] is False
|
|
assert preflight["catalog_record_write_executed"] is False
|
|
assert preflight["database_connection_opened"] is False
|
|
assert preflight["database_write_executed"] is False
|
|
assert preflight["database_commit_executed"] is False
|
|
assert preflight["review_state_update_executed"] is False
|
|
assert preflight["scheduler_attached"] is False
|
|
assert preflight["telegram_dispatch_report_catalog_write_preflight_sections"][0][
|
|
"key"
|
|
] == "catalog_record_identity"
|
|
assert preflight["blocked_reasons"] == []
|
|
assert preflight["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_write"
|
|
)
|
|
assert preflight["promotion_gate"]["requires_real_db_write"] is True
|
|
assert token_leak["telegram_dispatch_report_catalog_write_preflight_passed"] is False
|
|
assert "report_catalog_write_preflight_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_write_preflight_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_catalog_write_preflight_api" in preflight[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_write_preflight_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_write_preflight_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_write_preflight_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_write"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_report_catalog_write_preflight_file_written"] is False
|
|
assert data["report_catalog_write_preflight_file_written"] is False
|
|
assert data["catalog_write_preflight_file_written"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_record_write_executed"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_index"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index_preview"
|
|
)
|
|
assert "report_catalog_index_passed" in data["blocked_reasons"]
|
|
assert (
|
|
"operator_confirmed_report_catalog_write_preflight"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"report_catalog_write_preflight_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_generate_report_from_report_catalog_write_preflight_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write,
|
|
)
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight,
|
|
)
|
|
|
|
catalog_index = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index_preview",
|
|
"target_operation": "index_archived_market_intel_report_catalog_handoff",
|
|
"telegram_dispatch_report_catalog_index_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_index_passed": True,
|
|
"report_catalog_index_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_write_preflight": True,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"telegram_dispatch_report_catalog_handoff": {
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"report_output_hash": "f" * 64,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"required_report_sections_present": True,
|
|
},
|
|
"telegram_dispatch_report_catalog_index_sections": [
|
|
{"key": "catalog_index_identity"},
|
|
{"key": "catalog_source_trace"},
|
|
{"key": "index_manifest"},
|
|
{"key": "runtime_safety"},
|
|
],
|
|
"operator_telegram_dispatch_report_catalog_index": {
|
|
"report_catalog_index_artifact_path": "artifacts/market_intel/catalog-index.json",
|
|
"report_catalog_handoff_artifact_path_recorded": True,
|
|
"report_archive_summary_artifact_path_recorded": True,
|
|
"report_output_artifact_path_recorded": True,
|
|
"catalog_record_key_recorded": True,
|
|
"catalog_family_recorded": True,
|
|
"catalog_index_key_recorded": True,
|
|
"operator_confirmed_report_catalog_index": True,
|
|
"operator_confirmed_catalog_index_is_read_only": True,
|
|
"operator_confirmed_report_catalog_handoff_reviewed": True,
|
|
"operator_confirmed_catalog_manifest_reviewed": True,
|
|
"operator_confirmed_report_catalog_write_preflight_requires_separate_gate": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_write_preflight",
|
|
"report_catalog_write_preflight_requires_separate_gate": True,
|
|
"report_catalog_record_write_requires_separate_gate": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_index_api",
|
|
"do_not_read_telegram_token_from_report_catalog_index_api",
|
|
"do_not_call_llm_from_report_catalog_index",
|
|
"do_not_generate_report_from_report_catalog_index_api",
|
|
"do_not_write_report_catalog_index_artifact_from_api",
|
|
"do_not_write_report_catalog_record_from_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_index_api",
|
|
"do_not_open_database_connection_from_report_catalog_index",
|
|
"do_not_update_review_state_from_report_catalog_index",
|
|
"do_not_attach_scheduler_from_report_catalog_index",
|
|
"future_market_intel_report_catalog_write_preflight_must_use_separate_gate",
|
|
],
|
|
}
|
|
write_preflight_operator = {
|
|
"report_catalog_write_preflight_artifact_path": (
|
|
"artifacts/market_intel/catalog-write-preflight.json"
|
|
),
|
|
"report_catalog_index_artifact_path": "artifacts/market_intel/catalog-index.json",
|
|
"report_catalog_handoff_artifact_path": "artifacts/market_intel/catalog-handoff.json",
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"catalog_record_key": "market_intel_telegram_dispatch_audit_report:2026-05-20",
|
|
"catalog_family": "market_intel_telegram_dispatch_audit_report",
|
|
"catalog_index_key": "market_intel_telegram_dispatch_audit_report:index:2026-05-20",
|
|
"catalog_record_schema": "market_intel_report_catalog_v1",
|
|
"operator_confirmed_report_catalog_write_preflight": True,
|
|
"operator_confirmed_catalog_write_preflight_is_read_only": True,
|
|
"operator_confirmed_report_catalog_index_reviewed": True,
|
|
"operator_confirmed_catalog_record_schema_reviewed": True,
|
|
"operator_confirmed_report_catalog_record_write_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_catalog_write_preflight": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
}
|
|
write_preflight = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight(
|
|
telegram_dispatch_report_catalog_index=catalog_index,
|
|
operator_evidence=write_preflight_operator,
|
|
)
|
|
operator_evidence = {
|
|
**write_preflight_operator,
|
|
"report_catalog_record_write_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-write.json"
|
|
),
|
|
"catalog_record_backup_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-backup.json"
|
|
),
|
|
"catalog_record_write_dry_run_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-dry-run.json"
|
|
),
|
|
"operator_confirmed_report_catalog_record_write": True,
|
|
"operator_confirmed_catalog_record_write_is_cli_only": True,
|
|
"operator_confirmed_catalog_record_write_dry_run_reviewed": True,
|
|
"operator_confirmed_catalog_record_backup_required": True,
|
|
"operator_confirmed_report_catalog_record_commit_requires_separate_gate": True,
|
|
"operator_confirmed_postwrite_smoke_required": True,
|
|
"operator_confirmed_no_token_in_report_catalog_record_write": True,
|
|
"catalog_record_write_notes": "manual report catalog record write gate reviewed",
|
|
}
|
|
|
|
record_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write(
|
|
telegram_dispatch_report_catalog_write_preflight=write_preflight,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write(
|
|
telegram_dispatch_report_catalog_write_preflight=write_preflight,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write(
|
|
telegram_dispatch_report_catalog_write_preflight=write_preflight,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert record_write["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write_preview"
|
|
)
|
|
assert record_write["target_operation"] == (
|
|
"gate_market_intel_report_catalog_record_write"
|
|
)
|
|
assert record_write["telegram_dispatch_report_catalog_record_write_passed"] is True
|
|
assert (
|
|
record_write[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_write_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert record_write["report_catalog_record_write_passed"] is True
|
|
assert record_write["ready_for_market_intel_report_catalog_record_write"] is True
|
|
assert record_write["ready_for_market_intel_report_catalog_record_cli_run"] is True
|
|
assert record_write["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert record_write["ready_for_report_generation"] is False
|
|
assert record_write["ready_for_telegram_dispatch"] is False
|
|
assert record_write["ready_for_api_database_write"] is False
|
|
assert record_write["api_dispatches_telegram"] is False
|
|
assert record_write["api_executes_llm"] is False
|
|
assert record_write["api_reads_approval_token"] is False
|
|
assert record_write["api_writes_file"] is False
|
|
assert record_write["api_writes_database"] is False
|
|
assert record_write["catalog_record_write_gate_file_written"] is False
|
|
assert record_write["catalog_record_written"] is False
|
|
assert record_write["catalog_record_write_executed"] is False
|
|
assert record_write["catalog_record_commit_executed"] is False
|
|
assert record_write["database_connection_opened"] is False
|
|
assert record_write["database_write_executed"] is False
|
|
assert record_write["database_commit_executed"] is False
|
|
assert record_write["review_state_update_executed"] is False
|
|
assert record_write["scheduler_attached"] is False
|
|
assert record_write["telegram_dispatch_report_catalog_record_write_sections"][0][
|
|
"key"
|
|
] == "catalog_record_write_identity"
|
|
assert record_write["blocked_reasons"] == []
|
|
assert record_write["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_run_package"
|
|
)
|
|
assert record_write["promotion_gate"]["requires_cli_run"] is True
|
|
assert record_write["promotion_gate"]["requires_real_db_write"] is True
|
|
assert token_leak["telegram_dispatch_report_catalog_record_write_passed"] is False
|
|
assert "report_catalog_record_write_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_write_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_write_report_catalog_record_from_api" in record_write[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_record_write_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_write_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_record_write_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_write"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["catalog_record_write_gate_file_written"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_record_write_executed"] is False
|
|
assert data["catalog_record_commit_executed"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_write_preflight"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight_preview"
|
|
)
|
|
assert "report_catalog_write_preflight_passed" in data["blocked_reasons"]
|
|
assert (
|
|
"operator_confirmed_report_catalog_record_write"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"report_catalog_record_write_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_write_report_catalog_record_from_api" in data["safe_boundaries"]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package,
|
|
)
|
|
|
|
record_write = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write_preview",
|
|
"target_operation": "gate_market_intel_report_catalog_record_write",
|
|
"telegram_dispatch_report_catalog_record_write_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_write_passed": True,
|
|
"report_catalog_record_write_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_record_write": True,
|
|
"ready_for_market_intel_report_catalog_record_cli_run": True,
|
|
"ready_for_market_intel_report_catalog_record_commit": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"telegram_dispatch_report_catalog_write_preflight": {
|
|
"target_report_family": "market_intel_telegram_dispatch_audit_report",
|
|
"language": "zh-TW",
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"report_output_hash": "f" * 64,
|
|
"report_catalog_index_artifact_path": "artifacts/market_intel/catalog-index.json",
|
|
"report_catalog_write_preflight_artifact_path": (
|
|
"artifacts/market_intel/catalog-write-preflight.json"
|
|
),
|
|
"catalog_record_key_recorded": True,
|
|
"catalog_family_recorded": True,
|
|
"catalog_index_key_recorded": True,
|
|
"catalog_record_schema_recorded": True,
|
|
},
|
|
"telegram_dispatch_report_catalog_record_write_sections": [
|
|
{"key": "catalog_record_write_identity"},
|
|
{"key": "catalog_record_write_trace"},
|
|
{"key": "catalog_record_write_runtime_plan"},
|
|
{"key": "catalog_record_write_safety"},
|
|
],
|
|
"operator_telegram_dispatch_report_catalog_record_write": {
|
|
"report_catalog_record_write_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-write.json"
|
|
),
|
|
"report_catalog_write_preflight_artifact_path_recorded": True,
|
|
"report_catalog_index_artifact_path_recorded": True,
|
|
"report_output_artifact_path_recorded": True,
|
|
"catalog_record_key_recorded": True,
|
|
"catalog_family_recorded": True,
|
|
"catalog_index_key_recorded": True,
|
|
"catalog_record_schema_recorded": True,
|
|
"catalog_record_backup_artifact_path_recorded": True,
|
|
"catalog_record_write_dry_run_artifact_path_recorded": True,
|
|
"operator_confirmed_report_catalog_record_write": True,
|
|
"operator_confirmed_catalog_record_write_is_cli_only": True,
|
|
"operator_confirmed_catalog_record_write_dry_run_reviewed": True,
|
|
"operator_confirmed_catalog_record_backup_required": True,
|
|
"operator_confirmed_report_catalog_record_commit_requires_separate_gate": True,
|
|
"operator_confirmed_postwrite_smoke_required": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_record_run_package",
|
|
"requires_real_db_write": True,
|
|
"requires_cli_run": True,
|
|
"requires_postwrite_smoke": True,
|
|
"report_catalog_record_run_package_requires_separate_gate": True,
|
|
"report_catalog_record_commit_requires_separate_gate": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_record_write_api",
|
|
"do_not_read_telegram_token_from_report_catalog_record_write_api",
|
|
"do_not_call_llm_from_report_catalog_record_write",
|
|
"do_not_generate_report_from_report_catalog_record_write_api",
|
|
"do_not_write_report_catalog_record_write_artifact_from_api",
|
|
"do_not_write_report_catalog_record_from_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_record_write_api",
|
|
"do_not_open_database_connection_from_report_catalog_record_write",
|
|
"do_not_update_review_state_from_report_catalog_record_write",
|
|
"do_not_attach_scheduler_from_report_catalog_record_write",
|
|
"future_market_intel_report_catalog_record_run_package_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_record_run_package_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-package.json"
|
|
),
|
|
"report_catalog_record_write_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-write.json"
|
|
),
|
|
"report_catalog_write_preflight_artifact_path": (
|
|
"artifacts/market_intel/catalog-write-preflight.json"
|
|
),
|
|
"report_output_artifact_path": "artifacts/market_intel/report.json",
|
|
"catalog_record_key": "market_intel_telegram_dispatch_audit_report:2026-05-20",
|
|
"catalog_record_schema": "market_intel_report_catalog_v1",
|
|
"catalog_record_payload_manifest_path": (
|
|
"artifacts/market_intel/catalog-record-payload.json"
|
|
),
|
|
"catalog_record_backup_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-backup.json"
|
|
),
|
|
"catalog_record_write_dry_run_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-dry-run.json"
|
|
),
|
|
"catalog_record_cli_command": (
|
|
"python scripts/market_intel/write_report_catalog_record.py --input payload --dry-run"
|
|
),
|
|
"operator_confirmed_report_catalog_record_run_package": True,
|
|
"operator_confirmed_catalog_record_payload_manifest_reviewed": True,
|
|
"operator_confirmed_catalog_record_cli_command_reviewed": True,
|
|
"operator_confirmed_catalog_record_run_is_cli_only": True,
|
|
"operator_confirmed_catalog_record_backup_available": True,
|
|
"operator_confirmed_report_catalog_record_run_readiness_requires_separate_gate": True,
|
|
"operator_confirmed_report_catalog_record_commit_requires_separate_gate": True,
|
|
"operator_confirmed_postwrite_smoke_required": True,
|
|
"operator_confirmed_no_token_in_report_catalog_record_run_package": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_record_run_package_notes": "manual report catalog record run package reviewed",
|
|
}
|
|
|
|
run_package = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package(
|
|
telegram_dispatch_report_catalog_record_write=record_write,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package(
|
|
telegram_dispatch_report_catalog_record_write=record_write,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package(
|
|
telegram_dispatch_report_catalog_record_write=record_write,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert run_package["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_preview"
|
|
)
|
|
assert run_package["target_operation"] == (
|
|
"package_market_intel_report_catalog_record_run"
|
|
)
|
|
assert run_package["telegram_dispatch_report_catalog_record_run_package_passed"] is True
|
|
assert (
|
|
run_package[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_run_package_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert run_package["report_catalog_record_run_package_passed"] is True
|
|
assert run_package["ready_for_market_intel_report_catalog_record_run_package"] is True
|
|
assert run_package["ready_for_market_intel_report_catalog_record_run_readiness"] is True
|
|
assert run_package["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert run_package["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert run_package["ready_for_report_generation"] is False
|
|
assert run_package["ready_for_telegram_dispatch"] is False
|
|
assert run_package["ready_for_api_database_write"] is False
|
|
assert run_package["api_dispatches_telegram"] is False
|
|
assert run_package["api_executes_llm"] is False
|
|
assert run_package["api_writes_file"] is False
|
|
assert run_package["api_writes_database"] is False
|
|
assert run_package["catalog_record_run_package_file_written"] is False
|
|
assert run_package["catalog_record_cli_executed"] is False
|
|
assert run_package["catalog_record_written"] is False
|
|
assert run_package["catalog_record_write_executed"] is False
|
|
assert run_package["database_connection_opened"] is False
|
|
assert run_package["database_write_executed"] is False
|
|
assert run_package["database_commit_executed"] is False
|
|
assert run_package["scheduler_attached"] is False
|
|
assert run_package["command_bundle"]["api_must_not_execute_command"] is True
|
|
assert run_package["payload_manifest"]["execute_in_api"] is False
|
|
assert run_package["blocked_reasons"] == []
|
|
assert run_package["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_run_readiness"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_catalog_record_run_package_passed"] is False
|
|
assert "report_catalog_record_run_package_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_run_package_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert "do_not_execute_catalog_record_cli_from_api" in run_package[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_record_run_package_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_run_package_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_record_run_package_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_run_package"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_run_readiness"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["catalog_record_run_package_file_written"] is False
|
|
assert data["catalog_record_cli_executed"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_record_write_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_record_write"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write_preview"
|
|
)
|
|
assert "report_catalog_record_write_passed" in data["blocked_reasons"]
|
|
assert (
|
|
"operator_confirmed_report_catalog_record_run_package"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"report_catalog_record_run_package_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_execute_catalog_record_cli_from_api" in data["safe_boundaries"]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness,
|
|
)
|
|
|
|
run_package = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_preview",
|
|
"target_operation": "package_market_intel_report_catalog_record_run",
|
|
"telegram_dispatch_report_catalog_record_run_package_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_run_package_passed": True,
|
|
"report_catalog_record_run_package_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_record_run_package": True,
|
|
"ready_for_market_intel_report_catalog_record_run_readiness": True,
|
|
"ready_for_market_intel_report_catalog_record_cli_run": False,
|
|
"ready_for_market_intel_report_catalog_record_commit": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"payload_manifest": {
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"record_key_recorded": True,
|
|
"record_schema_recorded": True,
|
|
"report_output_hash": "f" * 64,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"statement_count": 1,
|
|
"source_artifacts": {
|
|
"record_write_gate": True,
|
|
"write_preflight": True,
|
|
"report_output": True,
|
|
"backup": True,
|
|
"dry_run": True,
|
|
},
|
|
"execute_in_api": False,
|
|
},
|
|
"command_bundle": {
|
|
"script_path": "scripts/market_intel/write_report_catalog_record.py",
|
|
"approval_env_var": "MARKET_INTEL_QUEUE_WRITE_APPROVAL",
|
|
"dry_run_command": (
|
|
"python scripts/market_intel/write_report_catalog_record.py --input payload --dry-run"
|
|
),
|
|
"real_run_command_requires_separate_gate": True,
|
|
"api_must_not_execute_command": True,
|
|
"cli_command_recorded_by_operator": True,
|
|
"expected_statement_count": 1,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_record_run_readiness",
|
|
"requires_real_db_write": True,
|
|
"requires_cli_run": True,
|
|
"requires_postwrite_smoke": True,
|
|
"report_catalog_record_run_readiness_requires_separate_gate": True,
|
|
"report_catalog_record_commit_requires_separate_gate": True,
|
|
},
|
|
"telegram_dispatch_report_catalog_record_run_package_sections": [
|
|
{"key": "catalog_record_run_package_identity"},
|
|
{"key": "catalog_record_payload_manifest"},
|
|
{"key": "catalog_record_command_bundle"},
|
|
{"key": "catalog_record_run_package_safety"},
|
|
],
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_record_run_package_api",
|
|
"do_not_read_telegram_token_from_report_catalog_record_run_package_api",
|
|
"do_not_call_llm_from_report_catalog_record_run_package",
|
|
"do_not_generate_report_from_report_catalog_record_run_package_api",
|
|
"do_not_write_report_catalog_record_run_package_artifact_from_api",
|
|
"do_not_execute_catalog_record_cli_from_api",
|
|
"do_not_write_report_catalog_record_from_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_record_run_package_api",
|
|
"do_not_open_database_connection_from_report_catalog_record_run_package",
|
|
"do_not_update_review_state_from_report_catalog_record_run_package",
|
|
"do_not_attach_scheduler_from_report_catalog_record_run_package",
|
|
"future_market_intel_report_catalog_record_run_readiness_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_record_run_readiness_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-readiness.json"
|
|
),
|
|
"report_catalog_record_run_package_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-package.json"
|
|
),
|
|
"catalog_record_payload_manifest_path": (
|
|
"artifacts/market_intel/catalog-record-payload.json"
|
|
),
|
|
"catalog_record_backup_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-backup.json"
|
|
),
|
|
"catalog_record_write_dry_run_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-dry-run.json"
|
|
),
|
|
"catalog_record_cli_command": (
|
|
"python scripts/market_intel/write_report_catalog_record.py --input payload"
|
|
),
|
|
"catalog_record_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-receipt.json"
|
|
),
|
|
"catalog_record_postwrite_smoke_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-postwrite-smoke.json"
|
|
),
|
|
"operator_confirmed_report_catalog_record_run_readiness": True,
|
|
"operator_confirmed_report_catalog_record_run_package_reviewed": True,
|
|
"operator_confirmed_catalog_record_payload_manifest_reviewed": True,
|
|
"operator_confirmed_catalog_record_cli_command_reviewed": True,
|
|
"operator_confirmed_catalog_record_dry_run_reviewed": True,
|
|
"operator_confirmed_catalog_record_backup_available": True,
|
|
"operator_confirmed_catalog_record_run_is_cli_only": True,
|
|
"operator_confirmed_one_time_token_shell_only": True,
|
|
"operator_confirmed_report_catalog_record_run_receipt_required": True,
|
|
"operator_confirmed_report_catalog_record_commit_requires_separate_gate": True,
|
|
"operator_confirmed_postwrite_smoke_required": True,
|
|
"operator_confirmed_no_token_in_report_catalog_record_run_readiness": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_record_run_readiness_notes": "manual run readiness reviewed",
|
|
}
|
|
|
|
readiness = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness(
|
|
telegram_dispatch_report_catalog_record_run_package=run_package,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness(
|
|
telegram_dispatch_report_catalog_record_run_package=run_package,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness(
|
|
telegram_dispatch_report_catalog_record_run_package=run_package,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert readiness["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_preview"
|
|
)
|
|
assert readiness["target_operation"] == (
|
|
"manual_market_intel_report_catalog_record_run_readiness"
|
|
)
|
|
assert readiness["telegram_dispatch_report_catalog_record_run_readiness_passed"] is True
|
|
assert (
|
|
readiness[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert readiness["report_catalog_record_run_readiness_passed"] is True
|
|
assert readiness["ready_for_cli_operator_run"] is True
|
|
assert readiness["ready_for_market_intel_report_catalog_record_cli_operator_run"] is True
|
|
assert readiness["ready_for_market_intel_report_catalog_record_run_receipt"] is True
|
|
assert readiness["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert readiness["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert readiness["ready_for_real_write"] is False
|
|
assert readiness["ready_for_api_database_write"] is False
|
|
assert readiness["api_executes_cli"] is False
|
|
assert readiness["api_reads_approval_token"] is False
|
|
assert readiness["api_writes_file"] is False
|
|
assert readiness["api_writes_database"] is False
|
|
assert readiness["catalog_record_run_readiness_gate_file_written"] is False
|
|
assert readiness["catalog_record_run_readiness_executed"] is False
|
|
assert readiness["catalog_record_run_readiness_file_written"] is False
|
|
assert readiness["catalog_record_cli_executed"] is False
|
|
assert readiness["catalog_record_written"] is False
|
|
assert readiness["database_connection_opened"] is False
|
|
assert readiness["database_write_executed"] is False
|
|
assert readiness["scheduler_attached"] is False
|
|
assert readiness["blocked_reasons"] == []
|
|
assert readiness["catalog_record_run_readiness_manifest"]["manifest_version"] == (
|
|
"market_intel_report_catalog_record_run_readiness_v1"
|
|
)
|
|
assert (
|
|
readiness["catalog_record_run_readiness_manifest"]["manual_cli_run_command"][
|
|
"executed_by_api"
|
|
]
|
|
is False
|
|
)
|
|
assert readiness["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_run_receipt"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_catalog_record_run_readiness_passed"] is False
|
|
assert "report_catalog_record_run_readiness_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_run_readiness_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_run_readiness_api"
|
|
in readiness["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_record_run_readiness_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_record_run_readiness_passed"] is False
|
|
assert data["ready_for_cli_operator_run"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_cli_operator_run"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_run_receipt"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["catalog_record_run_readiness_gate_file_written"] is False
|
|
assert data["catalog_record_run_readiness_executed"] is False
|
|
assert data["catalog_record_run_readiness_file_written"] is False
|
|
assert data["catalog_record_cli_executed"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_record_run_package"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_preview"
|
|
)
|
|
assert "report_catalog_record_run_package_passed" in data["blocked_reasons"]
|
|
assert (
|
|
"operator_confirmed_report_catalog_record_run_readiness"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"report_catalog_record_run_readiness_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_run_readiness_api"
|
|
in data["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt,
|
|
)
|
|
|
|
readiness = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_preview",
|
|
"target_operation": "manual_market_intel_report_catalog_record_run_readiness",
|
|
"telegram_dispatch_report_catalog_record_run_readiness_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_passed": True,
|
|
"report_catalog_record_run_readiness_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_cli_operator_run": True,
|
|
"ready_for_market_intel_report_catalog_record_cli_operator_run": True,
|
|
"ready_for_market_intel_report_catalog_record_run_receipt": True,
|
|
"ready_for_market_intel_report_catalog_record_cli_run": False,
|
|
"ready_for_market_intel_report_catalog_record_commit": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"catalog_record_run_readiness_manifest": {
|
|
"manifest_version": "market_intel_report_catalog_record_run_readiness_v1",
|
|
"source_mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_preview",
|
|
"source_operation": "package_market_intel_report_catalog_record_run",
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"report_output_hash": "f" * 64,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"statement_count": 1,
|
|
"source_artifacts": {
|
|
"record_write_gate": True,
|
|
"write_preflight": True,
|
|
"report_output": True,
|
|
"backup": True,
|
|
"dry_run": True,
|
|
},
|
|
"manual_cli_run_command": {
|
|
"script_path": "scripts/market_intel/write_report_catalog_record.py",
|
|
"dry_run_command": (
|
|
"python scripts/market_intel/write_report_catalog_record.py --input payload --dry-run"
|
|
),
|
|
"executed_by_api": False,
|
|
"writes_catalog_record": True,
|
|
"requires_approval_env_var": "MARKET_INTEL_QUEUE_WRITE_APPROVAL",
|
|
},
|
|
"execution_boundaries": {
|
|
"api_writes_file": False,
|
|
"api_executes_cli": False,
|
|
"api_writes_catalog_record": False,
|
|
"api_writes_database": False,
|
|
"api_dispatches_telegram": False,
|
|
"api_calls_llm": False,
|
|
"api_attaches_scheduler": False,
|
|
},
|
|
},
|
|
"telegram_dispatch_report_catalog_record_run_package": {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_preview",
|
|
"catalog_record_run_package_passed": True,
|
|
"record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"report_output_hash": "f" * 64,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_record_run_receipt",
|
|
"requires_real_db_write": True,
|
|
"requires_cli_run": True,
|
|
"requires_postwrite_smoke": True,
|
|
"report_catalog_record_run_receipt_requires_separate_gate": True,
|
|
"report_catalog_record_commit_requires_separate_gate": True,
|
|
},
|
|
"telegram_dispatch_report_catalog_record_run_readiness_sections": [
|
|
{"key": "catalog_record_run_readiness_identity"},
|
|
{"key": "catalog_record_run_readiness_artifacts"},
|
|
{"key": "catalog_record_run_readiness_command"},
|
|
{"key": "catalog_record_run_readiness_safety"},
|
|
],
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_record_run_readiness_api",
|
|
"do_not_read_telegram_token_from_report_catalog_record_run_readiness_api",
|
|
"do_not_call_llm_from_report_catalog_record_run_readiness",
|
|
"do_not_generate_report_from_report_catalog_record_run_readiness_api",
|
|
"do_not_write_report_catalog_record_run_readiness_artifact_from_api",
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_run_readiness_api",
|
|
"do_not_write_report_catalog_record_from_report_catalog_record_run_readiness_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_record_run_readiness_api",
|
|
"do_not_open_database_connection_from_report_catalog_record_run_readiness",
|
|
"do_not_update_review_state_from_report_catalog_record_run_readiness",
|
|
"do_not_attach_scheduler_from_report_catalog_record_run_readiness",
|
|
"future_market_intel_report_catalog_record_run_receipt_must_use_separate_gate",
|
|
],
|
|
}
|
|
receipt_payload = {
|
|
"mode": "manual_market_intel_report_catalog_record_run_receipt",
|
|
"writer_output": {
|
|
"mode": "market_intel_report_catalog_record_run_receipt",
|
|
"catalog_record_cli_executed": True,
|
|
"catalog_record_written": True,
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"catalog_record_key": "market-intel-report-20260520",
|
|
"statement_count": 1,
|
|
"affected_count": 1,
|
|
"database_connection_opened": True,
|
|
"explicit_transaction_opened": True,
|
|
"database_write_executed": True,
|
|
"database_commit_executed": True,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"report_output_hash": "f" * 64,
|
|
},
|
|
"postwrite_smoke_result": {
|
|
"mode": "market_intel_report_catalog_record_postwrite_smoke_read_only",
|
|
"postwrite_smoke_passed": True,
|
|
"read_only_query_executed": True,
|
|
"catalog_record_found": True,
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"catalog_record_key": "market-intel-report-20260520",
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
},
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_record_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-receipt.json"
|
|
),
|
|
"report_catalog_record_run_readiness_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-readiness.json"
|
|
),
|
|
"report_catalog_record_run_package_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-package.json"
|
|
),
|
|
"catalog_record_payload_manifest_path": (
|
|
"artifacts/market_intel/catalog-record-payload.json"
|
|
),
|
|
"catalog_record_backup_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-backup.json"
|
|
),
|
|
"catalog_record_write_dry_run_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-dry-run.json"
|
|
),
|
|
"catalog_record_writer_output_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-writer-output.json"
|
|
),
|
|
"catalog_record_postwrite_smoke_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-postwrite-smoke.json"
|
|
),
|
|
"catalog_record_cli_command": (
|
|
"python scripts/market_intel/write_report_catalog_record.py --input payload"
|
|
),
|
|
"operator_confirmed_report_catalog_record_run_receipt": True,
|
|
"operator_confirmed_catalog_record_run_readiness_reviewed": True,
|
|
"operator_confirmed_catalog_record_cli_output_reviewed": True,
|
|
"operator_confirmed_catalog_record_postwrite_smoke_passed": True,
|
|
"operator_confirmed_catalog_record_backup_available": True,
|
|
"operator_confirmed_catalog_record_commit_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_catalog_record_run_receipt": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_cli_execution": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_record_run_receipt_notes": "manual run receipt reviewed",
|
|
}
|
|
|
|
receipt = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt(
|
|
telegram_dispatch_report_catalog_record_run_readiness=readiness,
|
|
catalog_record_run_receipt=receipt_payload,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt(
|
|
telegram_dispatch_report_catalog_record_run_readiness=readiness,
|
|
catalog_record_run_receipt=receipt_payload,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt(
|
|
telegram_dispatch_report_catalog_record_run_readiness=readiness,
|
|
catalog_record_run_receipt=receipt_payload,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert receipt["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_preview"
|
|
)
|
|
assert receipt["target_operation"] == (
|
|
"review_manual_market_intel_report_catalog_record_run_receipt"
|
|
)
|
|
assert receipt["telegram_dispatch_report_catalog_record_run_receipt_passed"] is True
|
|
assert (
|
|
receipt[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert receipt["report_catalog_record_run_receipt_passed"] is True
|
|
assert receipt["ready_for_market_intel_report_catalog_record_commit"] is True
|
|
assert receipt["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert receipt["ready_for_real_write"] is False
|
|
assert receipt["ready_for_api_database_write"] is False
|
|
assert receipt["api_executes_cli"] is False
|
|
assert receipt["api_writes_file"] is False
|
|
assert receipt["api_writes_database"] is False
|
|
assert receipt["catalog_record_written"] is False
|
|
assert receipt["catalog_record_run_receipt_gate_file_written"] is False
|
|
assert receipt["catalog_record_run_receipt_executed"] is False
|
|
assert receipt["catalog_record_commit_executed"] is False
|
|
assert receipt["database_connection_opened"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert receipt["blocked_reasons"] == []
|
|
assert (
|
|
receipt["telegram_dispatch_report_catalog_record_run_receipt_writer"][
|
|
"catalog_record_written"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
receipt["telegram_dispatch_report_catalog_record_run_receipt_postwrite_smoke"][
|
|
"postwrite_smoke_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert receipt["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_commit"
|
|
)
|
|
assert token_leak["telegram_dispatch_report_catalog_record_run_receipt_passed"] is False
|
|
assert "report_catalog_record_run_receipt_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_run_receipt_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_run_receipt_api"
|
|
in receipt["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_record_run_receipt_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_record_run_receipt_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_record_run_receipt_gate_file_written"] is False
|
|
assert data["catalog_record_run_receipt_executed"] is False
|
|
assert data["catalog_record_commit_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_record_run_readiness"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_preview"
|
|
)
|
|
assert "report_catalog_record_run_readiness_passed" in data["blocked_reasons"]
|
|
assert (
|
|
"catalog_record_run_receipt_writer_output_provided"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"report_catalog_record_run_receipt_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_run_receipt_api"
|
|
in data["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit,
|
|
)
|
|
|
|
run_receipt = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_preview",
|
|
"target_operation": "review_manual_market_intel_report_catalog_record_run_receipt",
|
|
"telegram_dispatch_report_catalog_record_run_receipt_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_passed": True,
|
|
"report_catalog_record_run_receipt_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_record_commit": True,
|
|
"ready_for_market_intel_report_catalog_record_commit_gate": True,
|
|
"ready_for_market_intel_report_catalog_record_cli_run": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"api_executes_cli": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"catalog_record_written": False,
|
|
"catalog_record_commit_executed": False,
|
|
"database_write_executed": False,
|
|
"scheduler_attached": False,
|
|
"telegram_dispatch_report_catalog_record_run_receipt_writer": {
|
|
"mode": "market_intel_report_catalog_record_run_receipt",
|
|
"catalog_record_written": True,
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"catalog_record_key": "market-intel-report-20260520",
|
|
"statement_count": 1,
|
|
"database_write_executed": True,
|
|
"database_commit_executed": True,
|
|
"database_rollback_executed": False,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"approval_or_telegram_token_key_detected": False,
|
|
},
|
|
"telegram_dispatch_report_catalog_record_run_receipt_postwrite_smoke": {
|
|
"mode": "market_intel_report_catalog_record_postwrite_smoke_read_only",
|
|
"postwrite_smoke_passed": True,
|
|
"read_only_query_executed": True,
|
|
"catalog_record_found": True,
|
|
"target_table": "market_alert_review_queue",
|
|
"target_column": "metadata_json",
|
|
"record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"catalog_record_key": "market-intel-report-20260520",
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"summary_payload_hash_matches_expected": True,
|
|
"approval_or_telegram_token_key_detected": False,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_record_commit",
|
|
"report_catalog_record_commit_requires_separate_gate": True,
|
|
"api_must_not_write_database": True,
|
|
"api_must_not_execute_cli": True,
|
|
"api_must_not_write_catalog_record": True,
|
|
},
|
|
"telegram_dispatch_report_catalog_record_run_receipt_sections": [
|
|
{"key": "catalog_record_run_receipt_identity"},
|
|
{"key": "catalog_record_run_receipt_cli_result"},
|
|
{"key": "catalog_record_run_receipt_postwrite_smoke"},
|
|
{"key": "catalog_record_run_receipt_safety"},
|
|
],
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_record_run_receipt_api",
|
|
"do_not_read_telegram_token_from_report_catalog_record_run_receipt_api",
|
|
"do_not_call_llm_from_report_catalog_record_run_receipt",
|
|
"do_not_generate_report_from_report_catalog_record_run_receipt_api",
|
|
"do_not_write_report_catalog_record_run_receipt_artifact_from_api",
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_run_receipt_api",
|
|
"do_not_write_report_catalog_record_from_report_catalog_record_run_receipt_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_record_run_receipt_api",
|
|
"do_not_open_database_connection_from_report_catalog_record_run_receipt",
|
|
"do_not_update_review_state_from_report_catalog_record_run_receipt",
|
|
"do_not_attach_scheduler_from_report_catalog_record_run_receipt",
|
|
"future_market_intel_report_catalog_record_commit_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_record_commit_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-commit-gate.json"
|
|
),
|
|
"report_catalog_record_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-receipt.json"
|
|
),
|
|
"catalog_record_writer_output_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-writer-output.json"
|
|
),
|
|
"catalog_record_postwrite_smoke_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-postwrite-smoke.json"
|
|
),
|
|
"catalog_record_backup_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-backup.json"
|
|
),
|
|
"operator_confirmed_report_catalog_record_commit_gate": True,
|
|
"operator_confirmed_catalog_record_run_receipt_reviewed": True,
|
|
"operator_confirmed_catalog_record_db_commit_observed": True,
|
|
"operator_confirmed_catalog_record_postwrite_smoke_passed": True,
|
|
"operator_confirmed_catalog_record_no_followup_db_write_required": True,
|
|
"operator_confirmed_catalog_record_closeout_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_catalog_record_commit": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_cli_execution": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_record_commit_notes": "manual commit gate reviewed",
|
|
}
|
|
|
|
commit = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit(
|
|
telegram_dispatch_report_catalog_record_run_receipt=run_receipt,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit(
|
|
telegram_dispatch_report_catalog_record_run_receipt=run_receipt,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit(
|
|
telegram_dispatch_report_catalog_record_run_receipt=run_receipt,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert commit["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit_preview"
|
|
)
|
|
assert commit["target_operation"] == (
|
|
"review_manual_market_intel_report_catalog_record_commit"
|
|
)
|
|
assert commit["telegram_dispatch_report_catalog_record_commit_passed"] is True
|
|
assert (
|
|
commit[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_commit_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert commit["report_catalog_record_commit_passed"] is True
|
|
assert commit["ready_for_market_intel_report_catalog_record_closeout"] is True
|
|
assert commit["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert commit["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert commit["ready_for_real_write"] is False
|
|
assert commit["ready_for_api_database_write"] is False
|
|
assert commit["api_executes_cli"] is False
|
|
assert commit["api_writes_file"] is False
|
|
assert commit["api_writes_database"] is False
|
|
assert commit["catalog_record_written"] is False
|
|
assert commit["catalog_record_commit_gate_file_written"] is False
|
|
assert commit["catalog_record_commit_executed"] is False
|
|
assert commit["catalog_record_closeout_gate_file_written"] is False
|
|
assert commit["database_connection_opened"] is False
|
|
assert commit["database_write_executed"] is False
|
|
assert commit["scheduler_attached"] is False
|
|
assert commit["blocked_reasons"] == []
|
|
assert commit["telegram_dispatch_report_catalog_record_run_receipt"][
|
|
"writer_database_commit_executed"
|
|
] is True
|
|
assert commit["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_closeout"
|
|
)
|
|
assert (
|
|
commit["promotion_gate"]["report_catalog_record_closeout_requires_separate_gate"]
|
|
is True
|
|
)
|
|
assert token_leak["telegram_dispatch_report_catalog_record_commit_passed"] is False
|
|
assert "report_catalog_record_commit_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_commit_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_commit_api"
|
|
in commit["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_record_commit_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_commit_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_record_commit_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_closeout"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_record_commit_gate_file_written"] is False
|
|
assert data["catalog_record_commit_executed"] is False
|
|
assert data["catalog_record_closeout_gate_file_written"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_record_run_receipt"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_preview"
|
|
)
|
|
assert "report_catalog_record_run_receipt_passed" in data["blocked_reasons"]
|
|
assert "report_catalog_record_commit_operator_confirmed" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_commit_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_commit_api"
|
|
in data["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout,
|
|
)
|
|
|
|
commit = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit_preview",
|
|
"target_operation": "review_manual_market_intel_report_catalog_record_commit",
|
|
"telegram_dispatch_report_catalog_record_commit_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_commit_passed": True,
|
|
"report_catalog_record_commit_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_record_closeout": True,
|
|
"ready_for_market_intel_report_catalog_record_commit": False,
|
|
"ready_for_market_intel_report_catalog_record_cli_run": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"api_executes_cli": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_dispatches_telegram": False,
|
|
"catalog_record_written": False,
|
|
"catalog_record_commit_executed": False,
|
|
"database_write_executed": False,
|
|
"scheduler_attached": False,
|
|
"telegram_dispatch_report_catalog_record_run_receipt": {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_preview",
|
|
"run_receipt_passed": True,
|
|
"writer_catalog_record_key": "market-intel-report-20260520",
|
|
"writer_target_table": "market_alert_review_queue",
|
|
"writer_target_column": "metadata_json",
|
|
"writer_record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"writer_statement_count": 1,
|
|
"writer_database_commit_executed": True,
|
|
"writer_hash_match": True,
|
|
"smoke_read_only_query_executed": True,
|
|
"smoke_postwrite_smoke_passed": True,
|
|
"smoke_hash_match": True,
|
|
},
|
|
"operator_telegram_dispatch_report_catalog_record_commit": {
|
|
"operator_confirmed_report_catalog_record_commit_gate": True,
|
|
"operator_confirmed_catalog_record_run_receipt_reviewed": True,
|
|
"operator_confirmed_catalog_record_db_commit_observed": True,
|
|
"operator_confirmed_catalog_record_postwrite_smoke_passed": True,
|
|
"operator_confirmed_catalog_record_no_followup_db_write_required": True,
|
|
"operator_confirmed_catalog_record_closeout_requires_separate_gate": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_record_closeout",
|
|
"report_catalog_record_closeout_requires_separate_gate": True,
|
|
"api_must_not_write_database": True,
|
|
"api_must_not_execute_cli": True,
|
|
"api_must_not_write_catalog_record": True,
|
|
"api_must_not_commit_catalog_record": True,
|
|
"api_must_not_dispatch_telegram": True,
|
|
},
|
|
"telegram_dispatch_report_catalog_record_commit_sections": [
|
|
{"key": "catalog_record_commit_identity"},
|
|
{"key": "catalog_record_commit_receipt"},
|
|
{"key": "catalog_record_commit_operator"},
|
|
{"key": "catalog_record_commit_safety"},
|
|
],
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_record_commit_api",
|
|
"do_not_read_telegram_token_from_report_catalog_record_commit_api",
|
|
"do_not_call_llm_from_report_catalog_record_commit",
|
|
"do_not_generate_report_from_report_catalog_record_commit_api",
|
|
"do_not_write_report_catalog_record_commit_artifact_from_api",
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_commit_api",
|
|
"do_not_write_report_catalog_record_from_report_catalog_record_commit_api",
|
|
"do_not_commit_catalog_record_from_report_catalog_record_commit_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_record_commit_api",
|
|
"do_not_open_database_connection_from_report_catalog_record_commit",
|
|
"do_not_update_review_state_from_report_catalog_record_commit",
|
|
"do_not_attach_scheduler_from_report_catalog_record_commit",
|
|
"future_market_intel_report_catalog_record_closeout_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_record_closeout_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-closeout-gate.json"
|
|
),
|
|
"report_catalog_record_commit_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-commit-gate.json"
|
|
),
|
|
"report_catalog_record_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-receipt.json"
|
|
),
|
|
"catalog_record_writer_output_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-writer-output.json"
|
|
),
|
|
"catalog_record_postwrite_smoke_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-postwrite-smoke.json"
|
|
),
|
|
"catalog_record_backup_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-backup.json"
|
|
),
|
|
"operator_confirmed_report_catalog_record_closeout_gate": True,
|
|
"operator_confirmed_report_catalog_record_commit_reviewed": True,
|
|
"operator_confirmed_catalog_record_db_commit_observed": True,
|
|
"operator_confirmed_catalog_record_no_followup_db_write_required": True,
|
|
"operator_confirmed_catalog_record_closeout_summary_ready": True,
|
|
"operator_confirmed_catalog_record_archive_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_catalog_record_closeout": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_cli_execution": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_record_closeout_notes": "manual closeout gate reviewed",
|
|
}
|
|
|
|
closeout = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout(
|
|
telegram_dispatch_report_catalog_record_commit=commit,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout(
|
|
telegram_dispatch_report_catalog_record_commit=commit,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout(
|
|
telegram_dispatch_report_catalog_record_commit=commit,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert closeout["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout_preview"
|
|
)
|
|
assert closeout["target_operation"] == (
|
|
"review_manual_market_intel_report_catalog_record_closeout"
|
|
)
|
|
assert closeout["telegram_dispatch_report_catalog_record_closeout_passed"] is True
|
|
assert (
|
|
closeout[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_closeout_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert closeout["report_catalog_record_closeout_passed"] is True
|
|
assert closeout["ready_for_market_intel_report_catalog_record_archive"] is True
|
|
assert closeout["ready_for_market_intel_report_catalog_record_closeout"] is False
|
|
assert closeout["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert closeout["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert closeout["ready_for_real_write"] is False
|
|
assert closeout["ready_for_api_database_write"] is False
|
|
assert closeout["api_executes_cli"] is False
|
|
assert closeout["api_writes_file"] is False
|
|
assert closeout["api_writes_database"] is False
|
|
assert closeout["catalog_record_written"] is False
|
|
assert closeout["catalog_record_closeout_gate_file_written"] is False
|
|
assert closeout["catalog_record_closeout_executed"] is False
|
|
assert closeout["catalog_record_archive_gate_file_written"] is False
|
|
assert closeout["database_connection_opened"] is False
|
|
assert closeout["database_write_executed"] is False
|
|
assert closeout["scheduler_attached"] is False
|
|
assert closeout["blocked_reasons"] == []
|
|
assert closeout["telegram_dispatch_report_catalog_record_commit"][
|
|
"writer_database_commit_executed"
|
|
] is True
|
|
assert closeout["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_archive"
|
|
)
|
|
assert (
|
|
closeout["promotion_gate"]["report_catalog_record_archive_requires_separate_gate"]
|
|
is True
|
|
)
|
|
assert token_leak["telegram_dispatch_report_catalog_record_closeout_passed"] is False
|
|
assert "report_catalog_record_closeout_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_closeout_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_closeout_api"
|
|
in closeout["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_record_closeout_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_closeout_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_record_closeout_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_archive"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_closeout"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_commit"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_cli_run"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_record_closeout_gate_file_written"] is False
|
|
assert data["catalog_record_closeout_executed"] is False
|
|
assert data["catalog_record_archive_gate_file_written"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_record_commit"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit_preview"
|
|
)
|
|
assert "report_catalog_record_commit_passed" in data["blocked_reasons"]
|
|
assert "report_catalog_record_closeout_operator_confirmed" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_closeout_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_closeout_api"
|
|
in data["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive,
|
|
)
|
|
|
|
closeout = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout_preview",
|
|
"target_operation": "review_manual_market_intel_report_catalog_record_closeout",
|
|
"telegram_dispatch_report_catalog_record_closeout_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_closeout_passed": True,
|
|
"report_catalog_record_closeout_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_record_archive": True,
|
|
"ready_for_market_intel_report_catalog_record_closeout": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "e" * 64,
|
|
"api_executes_cli": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_dispatches_telegram": False,
|
|
"database_write_executed": False,
|
|
"catalog_record_closeout_executed": False,
|
|
"scheduler_attached": False,
|
|
"telegram_dispatch_report_catalog_record_commit": {
|
|
"writer_catalog_record_key": "market-intel-report-20260520",
|
|
"writer_target_table": "market_alert_review_queue",
|
|
"writer_target_column": "metadata_json",
|
|
"writer_record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"writer_statement_count": 1,
|
|
"writer_database_commit_executed": True,
|
|
"writer_hash_match": True,
|
|
"smoke_read_only_query_executed": True,
|
|
"smoke_postwrite_smoke_passed": True,
|
|
"smoke_hash_match": True,
|
|
},
|
|
"operator_telegram_dispatch_report_catalog_record_closeout": {
|
|
"report_catalog_record_closeout_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-closeout-gate.json"
|
|
),
|
|
"report_catalog_record_commit_artifact_path_recorded": True,
|
|
"report_catalog_record_run_receipt_artifact_path_recorded": True,
|
|
"catalog_record_writer_output_artifact_path_recorded": True,
|
|
"catalog_record_postwrite_smoke_artifact_path_recorded": True,
|
|
"catalog_record_backup_artifact_path_recorded": True,
|
|
"operator_confirmed_report_catalog_record_closeout_gate": True,
|
|
"operator_confirmed_report_catalog_record_commit_reviewed": True,
|
|
"operator_confirmed_catalog_record_db_commit_observed": True,
|
|
"operator_confirmed_catalog_record_no_followup_db_write_required": True,
|
|
"operator_confirmed_catalog_record_closeout_summary_ready": True,
|
|
"operator_confirmed_catalog_record_archive_requires_separate_gate": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_record_archive",
|
|
"report_catalog_record_archive_requires_separate_gate": True,
|
|
"api_must_not_generate_report": True,
|
|
"api_must_not_write_file": True,
|
|
"api_must_not_execute_cli": True,
|
|
"api_must_not_write_catalog_record": True,
|
|
"api_must_not_write_database": True,
|
|
"api_must_not_commit_catalog_record": True,
|
|
"api_must_not_dispatch_telegram": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_record_closeout_api",
|
|
"do_not_read_telegram_token_from_report_catalog_record_closeout_api",
|
|
"do_not_call_llm_from_report_catalog_record_closeout",
|
|
"do_not_generate_report_from_report_catalog_record_closeout_api",
|
|
"do_not_write_report_catalog_record_closeout_artifact_from_api",
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_closeout_api",
|
|
"do_not_write_report_catalog_record_from_report_catalog_record_closeout_api",
|
|
"do_not_commit_catalog_record_from_report_catalog_record_closeout_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_record_closeout_api",
|
|
"do_not_open_database_connection_from_report_catalog_record_closeout",
|
|
"do_not_update_review_state_from_report_catalog_record_closeout",
|
|
"do_not_attach_scheduler_from_report_catalog_record_closeout",
|
|
"future_market_intel_report_catalog_record_archive_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_record_archive_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-archive-gate.json"
|
|
),
|
|
"report_catalog_record_closeout_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-closeout-gate.json"
|
|
),
|
|
"report_catalog_record_commit_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-commit-gate.json"
|
|
),
|
|
"report_catalog_record_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-receipt.json"
|
|
),
|
|
"catalog_record_writer_output_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-writer-output.json"
|
|
),
|
|
"catalog_record_postwrite_smoke_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-postwrite-smoke.json"
|
|
),
|
|
"catalog_record_backup_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-backup.json"
|
|
),
|
|
"operator_confirmed_report_catalog_record_archive_gate": True,
|
|
"operator_confirmed_report_catalog_record_closeout_reviewed": True,
|
|
"operator_confirmed_catalog_record_db_commit_observed": True,
|
|
"operator_confirmed_catalog_record_no_followup_db_write_required": True,
|
|
"operator_confirmed_catalog_record_archive_manifest_reviewed": True,
|
|
"operator_confirmed_catalog_record_archive_retention_policy_recorded": True,
|
|
"operator_confirmed_catalog_record_archive_summary_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_catalog_record_archive": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_cli_execution": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_record_archive_notes": "manual archive gate reviewed",
|
|
}
|
|
|
|
archive = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive(
|
|
telegram_dispatch_report_catalog_record_closeout=closeout,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive(
|
|
telegram_dispatch_report_catalog_record_closeout=closeout,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive(
|
|
telegram_dispatch_report_catalog_record_closeout=closeout,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert archive["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_preview"
|
|
)
|
|
assert archive["target_operation"] == (
|
|
"review_manual_market_intel_report_catalog_record_archive"
|
|
)
|
|
assert archive["telegram_dispatch_report_catalog_record_archive_passed"] is True
|
|
assert (
|
|
archive[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_archive_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert archive["report_catalog_record_archive_passed"] is True
|
|
assert archive["ready_for_market_intel_report_catalog_record_archive_summary"] is True
|
|
assert archive["ready_for_market_intel_report_catalog_record_archive"] is False
|
|
assert archive["ready_for_real_write"] is False
|
|
assert archive["ready_for_report_generation"] is False
|
|
assert archive["ready_for_api_database_write"] is False
|
|
assert archive["api_executes_cli"] is False
|
|
assert archive["api_writes_file"] is False
|
|
assert archive["api_writes_database"] is False
|
|
assert archive["catalog_record_written"] is False
|
|
assert archive["catalog_record_archive_gate_file_written"] is False
|
|
assert archive["catalog_record_archive_executed"] is False
|
|
assert archive["database_connection_opened"] is False
|
|
assert archive["database_write_executed"] is False
|
|
assert archive["scheduler_attached"] is False
|
|
assert archive["blocked_reasons"] == []
|
|
assert archive["telegram_dispatch_report_catalog_record_closeout"][
|
|
"writer_database_commit_executed"
|
|
] is True
|
|
assert archive["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_archive_summary"
|
|
)
|
|
assert (
|
|
archive["promotion_gate"][
|
|
"report_catalog_record_archive_summary_requires_separate_gate"
|
|
]
|
|
is True
|
|
)
|
|
assert token_leak["telegram_dispatch_report_catalog_record_archive_passed"] is False
|
|
assert "report_catalog_record_archive_no_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_archive_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_archive_api"
|
|
in archive["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_record_archive_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_archive_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_record_archive_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_archive_summary"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_archive"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_record_archive_gate_file_written"] is False
|
|
assert data["catalog_record_archive_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_record_closeout"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout_preview"
|
|
)
|
|
assert "report_catalog_record_closeout_passed" in data["blocked_reasons"]
|
|
assert "report_catalog_record_archive_operator_confirmed" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_archive_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_archive_api"
|
|
in data["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary,
|
|
)
|
|
|
|
archive = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_preview",
|
|
"target_operation": "review_manual_market_intel_report_catalog_record_archive",
|
|
"telegram_dispatch_report_catalog_record_archive_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_archive_passed": True,
|
|
"report_catalog_record_archive_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_record_archive_summary": True,
|
|
"ready_for_market_intel_report_catalog_record_archive": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "f" * 64,
|
|
"api_executes_cli": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_dispatches_telegram": False,
|
|
"database_write_executed": False,
|
|
"catalog_record_archive_executed": False,
|
|
"scheduler_attached": False,
|
|
"telegram_dispatch_report_catalog_record_closeout": {
|
|
"writer_record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"writer_catalog_record_key": "market-intel-report-20260520",
|
|
"writer_target_table": "market_alert_review_queue",
|
|
"writer_target_column": "metadata_json",
|
|
"writer_statement_count": 1,
|
|
"writer_database_commit_executed": True,
|
|
"writer_hash_match": True,
|
|
"smoke_read_only_query_executed": True,
|
|
"smoke_postwrite_smoke_passed": True,
|
|
"smoke_hash_match": True,
|
|
"closeout_passed": True,
|
|
"operator_closeout_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-closeout-gate.json"
|
|
),
|
|
"operator_commit_artifact_path_recorded": True,
|
|
"operator_run_receipt_artifact_path_recorded": True,
|
|
"operator_writer_output_artifact_path_recorded": True,
|
|
"operator_postwrite_smoke_artifact_path_recorded": True,
|
|
"operator_backup_artifact_path_recorded": True,
|
|
},
|
|
"operator_telegram_dispatch_report_catalog_record_archive": {
|
|
"report_catalog_record_archive_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-archive-gate.json"
|
|
),
|
|
"report_catalog_record_closeout_artifact_path_recorded": True,
|
|
"report_catalog_record_commit_artifact_path_recorded": True,
|
|
"report_catalog_record_run_receipt_artifact_path_recorded": True,
|
|
"catalog_record_writer_output_artifact_path_recorded": True,
|
|
"catalog_record_postwrite_smoke_artifact_path_recorded": True,
|
|
"catalog_record_backup_artifact_path_recorded": True,
|
|
"operator_confirmed_report_catalog_record_archive_gate": True,
|
|
"operator_confirmed_report_catalog_record_closeout_reviewed": True,
|
|
"operator_confirmed_catalog_record_db_commit_observed": True,
|
|
"operator_confirmed_catalog_record_no_followup_db_write_required": True,
|
|
"operator_confirmed_catalog_record_archive_manifest_reviewed": True,
|
|
"operator_confirmed_catalog_record_archive_retention_policy_recorded": True,
|
|
"operator_confirmed_catalog_record_archive_summary_requires_separate_gate": True,
|
|
},
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_record_archive_summary",
|
|
"report_catalog_record_archive_summary_requires_separate_gate": True,
|
|
"api_must_not_generate_report": True,
|
|
"api_must_not_write_file": True,
|
|
"api_must_not_execute_cli": True,
|
|
"api_must_not_write_catalog_record": True,
|
|
"api_must_not_write_database": True,
|
|
"api_must_not_commit_catalog_record": True,
|
|
"api_must_not_dispatch_telegram": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_record_archive_api",
|
|
"do_not_read_telegram_token_from_report_catalog_record_archive_api",
|
|
"do_not_call_llm_from_report_catalog_record_archive",
|
|
"do_not_generate_report_from_report_catalog_record_archive_api",
|
|
"do_not_write_report_catalog_record_archive_artifact_from_api",
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_archive_api",
|
|
"do_not_write_report_catalog_record_from_report_catalog_record_archive_api",
|
|
"do_not_commit_catalog_record_from_report_catalog_record_archive_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_record_archive_api",
|
|
"do_not_open_database_connection_from_report_catalog_record_archive",
|
|
"do_not_update_review_state_from_report_catalog_record_archive",
|
|
"do_not_attach_scheduler_from_report_catalog_record_archive",
|
|
"future_market_intel_report_catalog_record_archive_summary_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_record_archive_summary_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-archive-summary-gate.json"
|
|
),
|
|
"report_catalog_record_archive_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-archive-gate.json"
|
|
),
|
|
"report_catalog_record_closeout_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-closeout-gate.json"
|
|
),
|
|
"report_catalog_record_commit_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-commit-gate.json"
|
|
),
|
|
"report_catalog_record_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-receipt.json"
|
|
),
|
|
"catalog_record_writer_output_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-writer-output.json"
|
|
),
|
|
"catalog_record_postwrite_smoke_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-postwrite-smoke.json"
|
|
),
|
|
"catalog_record_backup_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-backup.json"
|
|
),
|
|
"operator_confirmed_report_catalog_record_archive_summary_gate": True,
|
|
"operator_confirmed_report_catalog_record_archive_reviewed": True,
|
|
"operator_confirmed_catalog_record_traceability_reviewed": True,
|
|
"operator_confirmed_catalog_record_archive_summary_read_only": True,
|
|
"operator_confirmed_catalog_record_final_closeout_requires_separate_gate": True,
|
|
"operator_confirmed_no_token_in_report_catalog_record_archive_summary": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_cli_execution": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_record_archive_summary_notes": "manual archive summary reviewed",
|
|
}
|
|
|
|
summary = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary(
|
|
telegram_dispatch_report_catalog_record_archive=archive,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary(
|
|
telegram_dispatch_report_catalog_record_archive=archive,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary(
|
|
telegram_dispatch_report_catalog_record_archive=archive,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert summary["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_preview"
|
|
)
|
|
assert summary["target_operation"] == (
|
|
"summarize_manual_market_intel_report_catalog_record_archive"
|
|
)
|
|
assert summary["telegram_dispatch_report_catalog_record_archive_summary_passed"] is True
|
|
assert (
|
|
summary[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert summary["report_catalog_record_archive_summary_passed"] is True
|
|
assert summary["ready_for_market_intel_report_catalog_record_final_closeout"] is True
|
|
assert summary["ready_for_market_intel_report_catalog_record_archive_summary"] is False
|
|
assert summary["ready_for_market_intel_report_catalog_record_archive"] is False
|
|
assert summary["ready_for_real_write"] is False
|
|
assert summary["ready_for_report_generation"] is False
|
|
assert summary["ready_for_api_database_write"] is False
|
|
assert summary["api_executes_cli"] is False
|
|
assert summary["api_writes_file"] is False
|
|
assert summary["api_writes_database"] is False
|
|
assert summary["catalog_record_written"] is False
|
|
assert summary["catalog_record_archive_summary_gate_file_written"] is False
|
|
assert summary["catalog_record_archive_summary_executed"] is False
|
|
assert summary["catalog_record_final_closeout_gate_file_written"] is False
|
|
assert summary["database_connection_opened"] is False
|
|
assert summary["database_write_executed"] is False
|
|
assert summary["scheduler_attached"] is False
|
|
assert summary["blocked_reasons"] == []
|
|
assert summary["telegram_dispatch_report_catalog_record_archive"][
|
|
"writer_database_commit_executed"
|
|
] is True
|
|
assert summary["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_final_closeout"
|
|
)
|
|
assert (
|
|
summary["promotion_gate"][
|
|
"report_catalog_record_final_closeout_requires_separate_gate"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
token_leak[
|
|
"telegram_dispatch_report_catalog_record_archive_summary_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
"report_catalog_record_archive_summary_no_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"report_catalog_record_archive_summary_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_archive_summary_api"
|
|
in summary["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_record_archive_summary_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_record_archive_summary_passed"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_final_closeout"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_archive_summary"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_record_archive_summary_gate_file_written"] is False
|
|
assert data["catalog_record_archive_summary_executed"] is False
|
|
assert data["catalog_record_final_closeout_gate_file_written"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_record_archive"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_preview"
|
|
)
|
|
assert "report_catalog_record_archive_passed" in data["blocked_reasons"]
|
|
assert "report_catalog_record_archive_summary_operator_confirmed" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_archive_summary_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_archive_summary_api"
|
|
in data["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout_contract_only():
|
|
from services.market_intel.candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout import (
|
|
build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout,
|
|
)
|
|
|
|
archive_summary = {
|
|
"mode": "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_preview",
|
|
"target_operation": "summarize_manual_market_intel_report_catalog_record_archive",
|
|
"telegram_dispatch_report_catalog_record_archive_summary_passed": True,
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_passed": True,
|
|
"report_catalog_record_archive_summary_passed": True,
|
|
"ready_for_next_manual_phase": True,
|
|
"ready_for_market_intel_report_catalog_record_final_closeout": True,
|
|
"ready_for_market_intel_report_catalog_record_archive_summary": False,
|
|
"statement_count": 1,
|
|
"expected_summary_payload_hash": "a" * 64,
|
|
"api_executes_cli": False,
|
|
"api_writes_file": False,
|
|
"api_writes_database": False,
|
|
"api_dispatches_telegram": False,
|
|
"database_write_executed": False,
|
|
"catalog_record_archive_summary_executed": False,
|
|
"scheduler_attached": False,
|
|
"telegram_dispatch_report_catalog_record_archive": {
|
|
"writer_record_family": "market_intel_telegram_dispatch_audit_report",
|
|
"writer_catalog_record_key": "market-intel-report-20260520",
|
|
"writer_target_table": "market_alert_review_queue",
|
|
"writer_target_column": "metadata_json",
|
|
"writer_statement_count": 1,
|
|
"writer_database_commit_executed": True,
|
|
"writer_hash_match": True,
|
|
"smoke_read_only_query_executed": True,
|
|
"smoke_postwrite_smoke_passed": True,
|
|
"smoke_hash_match": True,
|
|
"archive_passed": True,
|
|
"archive_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-archive-gate.json"
|
|
),
|
|
"archive_closeout_artifact_path_recorded": True,
|
|
"archive_commit_artifact_path_recorded": True,
|
|
"archive_run_receipt_artifact_path_recorded": True,
|
|
"archive_writer_output_artifact_path_recorded": True,
|
|
"archive_postwrite_smoke_artifact_path_recorded": True,
|
|
"archive_backup_artifact_path_recorded": True,
|
|
},
|
|
"operator_telegram_dispatch_report_catalog_record_archive_summary": {
|
|
"report_catalog_record_archive_summary_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-archive-summary-gate.json"
|
|
),
|
|
"report_catalog_record_archive_artifact_path_recorded": True,
|
|
"operator_confirmed_report_catalog_record_archive_summary_gate": True,
|
|
"operator_confirmed_report_catalog_record_archive_reviewed": True,
|
|
"operator_confirmed_catalog_record_traceability_reviewed": True,
|
|
"operator_confirmed_catalog_record_archive_summary_read_only": True,
|
|
"operator_confirmed_catalog_record_final_closeout_requires_separate_gate": True,
|
|
},
|
|
"telegram_dispatch_report_catalog_record_archive_summary_sections": [
|
|
{"key": "catalog_record_archive_summary_identity", "facts": []},
|
|
{"key": "catalog_record_archive_summary_traceability", "facts": []},
|
|
{"key": "catalog_record_archive_summary_integrity", "facts": []},
|
|
{"key": "catalog_record_archive_summary_safety", "facts": []},
|
|
],
|
|
"promotion_gate": {
|
|
"allowed": True,
|
|
"next_manual_phase": "market_intel_report_catalog_record_final_closeout",
|
|
"report_catalog_record_final_closeout_requires_separate_gate": True,
|
|
"api_must_not_generate_report": True,
|
|
"api_must_not_write_file": True,
|
|
"api_must_not_execute_cli": True,
|
|
"api_must_not_write_catalog_record": True,
|
|
"api_must_not_write_database": True,
|
|
"api_must_not_commit_catalog_record": True,
|
|
"api_must_not_dispatch_telegram": True,
|
|
},
|
|
"safe_boundaries": [
|
|
"do_not_read_approval_token_from_report_catalog_record_archive_summary_api",
|
|
"do_not_read_telegram_token_from_report_catalog_record_archive_summary_api",
|
|
"do_not_call_llm_from_report_catalog_record_archive_summary",
|
|
"do_not_generate_report_from_report_catalog_record_archive_summary_api",
|
|
"do_not_write_report_catalog_record_archive_summary_artifact_from_api",
|
|
"do_not_execute_catalog_record_cli_from_report_catalog_record_archive_summary_api",
|
|
"do_not_write_report_catalog_record_from_report_catalog_record_archive_summary_api",
|
|
"do_not_commit_catalog_record_from_report_catalog_record_archive_summary_api",
|
|
"do_not_dispatch_telegram_from_report_catalog_record_archive_summary_api",
|
|
"do_not_open_database_connection_from_report_catalog_record_archive_summary",
|
|
"do_not_update_review_state_from_report_catalog_record_archive_summary",
|
|
"do_not_attach_scheduler_from_report_catalog_record_archive_summary",
|
|
"future_market_intel_report_catalog_record_final_closeout_must_use_separate_gate",
|
|
],
|
|
}
|
|
operator_evidence = {
|
|
"report_catalog_record_final_closeout_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-final-closeout-gate.json"
|
|
),
|
|
"report_catalog_record_archive_summary_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-archive-summary-gate.json"
|
|
),
|
|
"report_catalog_record_archive_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-archive-gate.json"
|
|
),
|
|
"report_catalog_record_closeout_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-closeout-gate.json"
|
|
),
|
|
"report_catalog_record_commit_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-commit-gate.json"
|
|
),
|
|
"report_catalog_record_run_receipt_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-run-receipt.json"
|
|
),
|
|
"catalog_record_writer_output_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-writer-output.json"
|
|
),
|
|
"catalog_record_postwrite_smoke_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-postwrite-smoke.json"
|
|
),
|
|
"catalog_record_backup_artifact_path": (
|
|
"artifacts/market_intel/catalog-record-backup.json"
|
|
),
|
|
"operator_confirmed_report_catalog_record_final_closeout_gate": True,
|
|
"operator_confirmed_report_catalog_record_archive_summary_reviewed": True,
|
|
"operator_confirmed_catalog_record_traceability_reviewed": True,
|
|
"operator_confirmed_catalog_record_pipeline_complete": True,
|
|
"operator_confirmed_no_pending_catalog_record_followup": True,
|
|
"operator_confirmed_catalog_record_final_closeout_read_only": True,
|
|
"operator_confirmed_no_token_in_report_catalog_record_final_closeout": True,
|
|
"operator_confirmed_no_api_report_generation": True,
|
|
"operator_confirmed_no_api_file_write": True,
|
|
"operator_confirmed_no_api_cli_execution": True,
|
|
"operator_confirmed_no_api_catalog_record_write": True,
|
|
"operator_confirmed_no_api_telegram_dispatch": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_no_llm_call": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"catalog_record_final_closeout_notes": "manual final closeout reviewed",
|
|
}
|
|
|
|
closeout = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout(
|
|
telegram_dispatch_report_catalog_record_archive_summary=archive_summary,
|
|
operator_evidence=operator_evidence,
|
|
execute_requested=True,
|
|
)
|
|
token_leak = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout(
|
|
telegram_dispatch_report_catalog_record_archive_summary=archive_summary,
|
|
operator_evidence={**operator_evidence, "telegram_token": TEST_APPROVAL_TOKEN},
|
|
)
|
|
apply_write = build_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout(
|
|
telegram_dispatch_report_catalog_record_archive_summary=archive_summary,
|
|
operator_evidence=operator_evidence,
|
|
apply_real_write=True,
|
|
)
|
|
|
|
assert closeout["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout_preview"
|
|
)
|
|
assert closeout["target_operation"] == (
|
|
"close_manual_market_intel_report_catalog_record_pipeline"
|
|
)
|
|
assert closeout["telegram_dispatch_report_catalog_record_final_closeout_passed"] is True
|
|
assert (
|
|
closeout[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_final_closeout_passed"
|
|
]
|
|
is True
|
|
)
|
|
assert closeout["report_catalog_record_final_closeout_passed"] is True
|
|
assert closeout["market_intel_report_catalog_record_pipeline_complete"] is True
|
|
assert closeout["ready_for_next_manual_phase"] is False
|
|
assert closeout["ready_for_market_intel_report_catalog_record_final_closeout"] is False
|
|
assert closeout["ready_for_real_write"] is False
|
|
assert closeout["ready_for_report_generation"] is False
|
|
assert closeout["ready_for_api_database_write"] is False
|
|
assert closeout["api_executes_cli"] is False
|
|
assert closeout["api_writes_file"] is False
|
|
assert closeout["api_writes_database"] is False
|
|
assert closeout["catalog_record_written"] is False
|
|
assert closeout["catalog_record_final_closeout_gate_file_written"] is False
|
|
assert closeout["catalog_record_final_closeout_executed"] is False
|
|
assert closeout["catalog_record_pipeline_completion_record_written"] is False
|
|
assert closeout["market_intel_catalog_record_pipeline_completed_by_api"] is False
|
|
assert closeout["database_connection_opened"] is False
|
|
assert closeout["database_write_executed"] is False
|
|
assert closeout["scheduler_attached"] is False
|
|
assert closeout["blocked_reasons"] == []
|
|
assert closeout["telegram_dispatch_report_catalog_record_archive_summary"][
|
|
"writer_database_commit_executed"
|
|
] is True
|
|
assert closeout["promotion_gate"]["next_manual_phase"] == (
|
|
"market_intel_report_catalog_record_pipeline_complete"
|
|
)
|
|
assert closeout["promotion_gate"]["terminal_gate"] is True
|
|
assert (
|
|
token_leak["telegram_dispatch_report_catalog_record_final_closeout_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
"report_catalog_record_final_closeout_no_token_submitted_to_api"
|
|
in token_leak["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"report_catalog_record_final_closeout_apply_real_write_not_requested_from_api"
|
|
in apply_write["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_final_closeout_api"
|
|
in closeout["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_report_catalog_record_final_closeout_passed"] is False
|
|
assert (
|
|
data[
|
|
"summary_persistence_telegram_dispatch_report_catalog_record_final_closeout_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert data["report_catalog_record_final_closeout_passed"] is False
|
|
assert data["market_intel_report_catalog_record_pipeline_complete"] is False
|
|
assert data["ready_for_market_intel_report_catalog_record_final_closeout"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_report_generation"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["catalog_record_written"] is False
|
|
assert data["catalog_record_final_closeout_gate_file_written"] is False
|
|
assert data["catalog_record_final_closeout_executed"] is False
|
|
assert data["catalog_record_pipeline_completion_record_written"] is False
|
|
assert data["market_intel_catalog_record_pipeline_completed_by_api"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["telegram_dispatch_report_catalog_record_archive_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_preview"
|
|
)
|
|
assert "report_catalog_record_archive_summary_passed" in data["blocked_reasons"]
|
|
assert "report_catalog_record_final_closeout_operator_confirmed" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"report_catalog_record_final_closeout_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_commit_catalog_record_from_report_catalog_record_final_closeout_api"
|
|
in data["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_writer_preflight_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/candidate_queue_writer_preflight",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-18",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "f" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_writer_preflight_planned"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 1
|
|
assert data["payload_column_map"]["metadata_json_preview"] == "metadata_json"
|
|
|
|
|
|
def test_candidate_queue_writer_status_route_never_leaks_approval_token(monkeypatch):
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
monkeypatch.setenv("MARKET_INTEL_QUEUE_WRITE_APPROVAL", TEST_APPROVAL_TOKEN)
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/candidate_queue_writer_status"
|
|
"?execute=true&apply_real_write=true",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-14",
|
|
"platform_code": "pchome",
|
|
"source_key": "homepage",
|
|
"source_url": "https://24h.pchome.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1800,
|
|
"page_hash": "b" * 64,
|
|
"title": "PChome 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "medium",
|
|
"score": 74,
|
|
"url": "https://24h.pchome.com.tw/activity/sample",
|
|
"text": "活動頁",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_writer_cli_blocked"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is True
|
|
assert data["apply_real_write_requested"] is True
|
|
assert data["approval_token_present"] is False
|
|
assert data["approval_token_valid"] is False
|
|
assert data["approval_token_secret_configured"] is True
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["writes_executed"] is False
|
|
assert data["would_write_database"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["transaction_preview_summary"]["statement_count"] == 1
|
|
assert "approval_token_present" in data["blocked_reasons"]
|
|
assert "approval_token_valid" in data["blocked_reasons"]
|
|
assert "approval_token_hint" not in payload
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
assert "APPROVED_MARKET_INTEL_QUEUE_WRITE" not in payload
|
|
|
|
|
|
def test_candidate_queue_writer_status_blocks_invalid_payload():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/candidate_queue_writer_status",
|
|
data="not-json",
|
|
content_type="application/json",
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 400
|
|
assert data["mode"] == "candidate_queue_writer_cli_blocked"
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["writes_executed"] is False
|
|
assert data["transaction_preview_summary"]["statement_count"] == 0
|
|
assert "transaction_preview_created" in data["blocked_reasons"]
|
|
|
|
|
|
def test_candidate_queue_writer_postwrite_smoke_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_writer_postwrite_smoke",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-22",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "4" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_writer_postwrite_smoke_planned"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_key_count"] == 1
|
|
assert data["postwrite_smoke_passed"] is False
|
|
|
|
|
|
def test_candidate_queue_writer_operator_drill_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_writer_operator_drill",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-24",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "6" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_writer_operator_drill_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["operator_drill_ready"] is True
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_summary"]["statement_count"] == 1
|
|
assert "backup_verified_by_operator" in data["blocked_reasons"]
|
|
|
|
|
|
def test_candidate_queue_writer_run_package_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_writer_run_package",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-26",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "8" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_writer_run_package_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["package_ready"] is True
|
|
assert data["package_artifact_created"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["payload_manifest"]["payload_count"] == 1
|
|
assert len(data["command_bundle"]) == 5
|
|
assert "real_sample_payload_saved_by_operator" in data["blocked_reasons"]
|
|
|
|
|
|
def test_candidate_queue_writer_run_readiness_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_writer_run_readiness",
|
|
json={
|
|
"sample_result": {
|
|
"batch_id": "sample-batch-28",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "a" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
"operator_evidence": {
|
|
"reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": "artifacts/market_intel/preflight.json",
|
|
"migration_live_smoke_passed": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
},
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_writer_run_readiness_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["ready_for_cli_operator_run"] is True
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["run_package_summary"]["payload_count"] == 1
|
|
assert data["operator_evidence_summary"]["artifact_path_count"] == 3
|
|
assert data["blocked_reasons"] == []
|
|
|
|
|
|
def test_candidate_queue_writer_run_receipt_preview_reviews_operator_artifacts():
|
|
from services.market_intel.candidate_queue_writer_cli import (
|
|
build_candidate_queue_writer_cli_plan,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_operator_drill import (
|
|
build_candidate_queue_writer_operator_drill,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_postwrite_smoke import (
|
|
build_candidate_queue_writer_postwrite_smoke,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_preflight import (
|
|
build_candidate_queue_writer_preflight,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_package import (
|
|
build_candidate_queue_writer_run_package,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_readiness import (
|
|
build_candidate_queue_writer_run_readiness,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_receipt import (
|
|
build_candidate_queue_writer_run_receipt,
|
|
)
|
|
|
|
sample_result = _market_intel_sample_result("sample-batch-29")
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
expected_key = transaction["statements"][0]["lookup"]["dedupe_key"]
|
|
preflight = build_candidate_queue_writer_preflight(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
writer_status = build_candidate_queue_writer_cli_plan(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
)
|
|
postwrite_smoke = build_candidate_queue_writer_postwrite_smoke(
|
|
transaction_preview=transaction,
|
|
execute_requested=False,
|
|
)
|
|
operator_drill = build_candidate_queue_writer_operator_drill(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
)
|
|
run_package = build_candidate_queue_writer_run_package(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
operator_drill=operator_drill,
|
|
)
|
|
operator_evidence = {
|
|
"reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": "artifacts/market_intel/preflight.json",
|
|
"migration_live_smoke_passed": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
"writer_output_json_path": "artifacts/market_intel/writer-output.json",
|
|
"postwrite_smoke_json_path": "artifacts/market_intel/postwrite-smoke.json",
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
}
|
|
run_readiness = build_candidate_queue_writer_run_readiness(
|
|
transaction_preview=transaction,
|
|
writer_preflight=preflight,
|
|
writer_status=writer_status,
|
|
postwrite_smoke=postwrite_smoke,
|
|
operator_drill=operator_drill,
|
|
run_package=run_package,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
writer_output = {
|
|
"mode": "candidate_queue_writer_cli_executed",
|
|
"exit_code": 0,
|
|
"writes_executed": True,
|
|
"would_write_database": True,
|
|
"database_connection_opened": True,
|
|
"explicit_transaction_opened": True,
|
|
"database_write_executed": True,
|
|
"database_commit_executed": True,
|
|
"database_rollback_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"inserted_count": 1,
|
|
"skipped_count": 0,
|
|
"affected_dedupe_keys": [expected_key],
|
|
"skipped_dedupe_keys": [],
|
|
}
|
|
postwrite_smoke_result = {
|
|
"mode": "candidate_queue_writer_postwrite_smoke_read_only",
|
|
"postwrite_smoke_passed": True,
|
|
"ready_for_operator_review": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"expected_dedupe_key_count": 1,
|
|
"found_count": 1,
|
|
"missing_count": 0,
|
|
"found_dedupe_keys": [expected_key],
|
|
"missing_dedupe_keys": [],
|
|
}
|
|
|
|
receipt = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=transaction,
|
|
run_readiness=run_readiness,
|
|
writer_output=writer_output,
|
|
postwrite_smoke_result=postwrite_smoke_result,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
token_leak = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=transaction,
|
|
run_readiness=run_readiness,
|
|
writer_output={**writer_output, "approval_token": TEST_APPROVAL_TOKEN},
|
|
postwrite_smoke_result=postwrite_smoke_result,
|
|
operator_evidence=operator_evidence,
|
|
)
|
|
|
|
assert receipt["mode"] == "candidate_queue_writer_run_receipt_preview"
|
|
assert receipt["receipt_passed"] is True
|
|
assert receipt["ready_for_next_manual_review"] is True
|
|
assert receipt["ready_for_api_database_write"] is False
|
|
assert receipt["ready_for_scheduler_attach"] is False
|
|
assert receipt["api_executes_cli"] is False
|
|
assert receipt["api_reads_approval_token"] is False
|
|
assert receipt["api_writes_file"] is False
|
|
assert receipt["database_connection_opened"] is False
|
|
assert receipt["database_write_executed"] is False
|
|
assert receipt["database_commit_executed"] is False
|
|
assert receipt["scheduler_attached"] is False
|
|
assert receipt["writer_output_summary"]["dedupe_keys_match_expected"] is True
|
|
assert receipt["postwrite_smoke_summary"]["dedupe_keys_match_expected"] is True
|
|
assert receipt["operator_evidence_summary"]["writer_output_json_path_recorded"] is True
|
|
assert receipt["blocked_reasons"] == []
|
|
assert token_leak["receipt_passed"] is False
|
|
assert token_leak["writer_output_summary"]["approval_token_key_detected"] is True
|
|
assert "writer_output_no_approval_token_key" in token_leak["blocked_reasons"]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
assert "do_not_echo_operator_receipt_payload" in receipt["safe_boundaries"]
|
|
|
|
|
|
def test_candidate_queue_writer_run_closeout_preview_blocks_api_write_and_tokens():
|
|
from services.market_intel.candidate_queue_writer_run_closeout import (
|
|
build_candidate_queue_writer_run_closeout,
|
|
)
|
|
from services.market_intel.candidate_queue_writer_run_receipt import (
|
|
build_candidate_queue_writer_run_receipt,
|
|
)
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-closeout"
|
|
)
|
|
closeout_evidence = {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"closeout_notes": "manual closeout reviewed",
|
|
}
|
|
receipt = build_candidate_queue_writer_run_receipt(
|
|
transaction_preview=fixture["transaction"],
|
|
run_readiness=fixture["run_readiness"],
|
|
writer_output=fixture["writer_output"],
|
|
postwrite_smoke_result=fixture["postwrite_smoke_result"],
|
|
operator_evidence=fixture["operator_evidence"],
|
|
)
|
|
closeout = build_candidate_queue_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=receipt,
|
|
operator_evidence=closeout_evidence,
|
|
)
|
|
token_leak = build_candidate_queue_writer_run_closeout(
|
|
transaction_preview=fixture["transaction"],
|
|
run_receipt=receipt,
|
|
operator_evidence={
|
|
**closeout_evidence,
|
|
"approval_token": TEST_APPROVAL_TOKEN,
|
|
},
|
|
)
|
|
|
|
assert closeout["mode"] == "candidate_queue_writer_run_closeout_preview"
|
|
assert closeout["closeout_passed"] is True
|
|
assert closeout["ready_for_next_manual_phase"] is True
|
|
assert closeout["ready_for_api_database_write"] is False
|
|
assert closeout["ready_for_scheduler_attach"] is False
|
|
assert closeout["api_executes_cli"] is False
|
|
assert closeout["api_reads_approval_token"] is False
|
|
assert closeout["api_writes_file"] is False
|
|
assert closeout["api_writes_database"] is False
|
|
assert closeout["database_connection_opened"] is False
|
|
assert closeout["database_write_executed"] is False
|
|
assert closeout["database_commit_executed"] is False
|
|
assert closeout["scheduler_attached"] is False
|
|
assert closeout["blocked_reasons"] == []
|
|
assert closeout["promotion_gate"]["requires_operator_approval"] is True
|
|
assert "no_momo_db_lifecycle_change" in closeout["safe_boundaries"]
|
|
assert token_leak["closeout_passed"] is False
|
|
assert token_leak["operator_closeout_summary"][
|
|
"approval_token_submitted_to_api"
|
|
] is True
|
|
assert "closeout_no_approval_token_submitted_to_api" in token_leak[
|
|
"blocked_reasons"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in json.dumps(
|
|
token_leak,
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
)
|
|
|
|
|
|
def test_candidate_queue_writer_run_receipt_route_accepts_inline_payload_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
sample_result = _market_intel_sample_result("sample-batch-30")
|
|
transaction = MarketIntelService().build_manual_sample_candidate_queue_transaction(
|
|
sample_result=sample_result
|
|
)
|
|
expected_key = transaction["statements"][0]["lookup"]["dedupe_key"]
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_writer_run_receipt",
|
|
json={
|
|
"sample_result": sample_result,
|
|
"operator_evidence": {
|
|
"reviewed_sample_json_path": "artifacts/market_intel/reviewed.json",
|
|
"backup_artifact_path": "scripts/tools/backups/backup.zip",
|
|
"preflight_artifact_path": "artifacts/market_intel/preflight.json",
|
|
"migration_live_smoke_passed": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
"writer_output_json_path": "artifacts/market_intel/writer-output.json",
|
|
"postwrite_smoke_json_path": "artifacts/market_intel/smoke.json",
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
},
|
|
"writer_output": {
|
|
"mode": "candidate_queue_writer_cli_executed",
|
|
"exit_code": 0,
|
|
"writes_executed": True,
|
|
"would_write_database": True,
|
|
"database_connection_opened": True,
|
|
"explicit_transaction_opened": True,
|
|
"database_write_executed": True,
|
|
"database_commit_executed": True,
|
|
"database_rollback_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"inserted_count": 1,
|
|
"skipped_count": 0,
|
|
"affected_dedupe_keys": [expected_key],
|
|
},
|
|
"postwrite_smoke_result": {
|
|
"mode": "candidate_queue_writer_postwrite_smoke_read_only",
|
|
"postwrite_smoke_passed": True,
|
|
"ready_for_operator_review": True,
|
|
"read_only_query_executed": True,
|
|
"database_connection_opened": True,
|
|
"database_write_executed": False,
|
|
"database_commit_executed": False,
|
|
"external_network_executed": False,
|
|
"scheduler_attached": False,
|
|
"expected_dedupe_key_count": 1,
|
|
"found_count": 1,
|
|
"missing_count": 0,
|
|
"found_dedupe_keys": [expected_key],
|
|
"missing_dedupe_keys": [],
|
|
},
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_writer_run_receipt_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["receipt_passed"] is True
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["blocked_reasons"] == []
|
|
|
|
|
|
def test_candidate_queue_writer_run_closeout_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-closeout-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_writer_run_closeout",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"closeout_notes": "manual closeout reviewed",
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_writer_run_closeout_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["closeout_passed"] is True
|
|
assert data["ready_for_next_manual_phase"] is True
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["blocked_reasons"] == []
|
|
|
|
|
|
def test_candidate_queue_review_handoff_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-handoff-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_handoff",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_handoff_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["handoff_ready"] is True
|
|
assert data["ready_for_manual_queue_review"] is True
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["review_contract"]["expected_review_state"] == "needs_review"
|
|
assert data["blocked_reasons"] == []
|
|
|
|
|
|
def test_candidate_queue_review_inventory_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-inventory-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_inventory"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_inventory?execute=false",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_inventory_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["review_inventory_ready"] is False
|
|
assert data["ready_for_human_decision_review"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == fixture["expected_keys"]
|
|
assert "read_only_inventory_executed" in data["blocked_reasons"]
|
|
assert "do_not_insert_missing_queue_row_from_api" in data["safe_boundaries"]
|
|
|
|
|
|
def test_candidate_queue_review_decision_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision?execute=false",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_decision_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["decision_ready"] is False
|
|
assert data["ready_for_human_decision_record"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["decision_record_written"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == fixture["expected_keys"]
|
|
assert "review_inventory_ready" in data["blocked_reasons"]
|
|
assert "do_not_update_review_state_from_api" in data["safe_boundaries"]
|
|
|
|
|
|
def test_candidate_queue_review_decision_approval_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-approval-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_approval"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_approval?execute=false",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"decision_approval_notes": "cli-only approval gate",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_decision_approval_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["approval_ready"] is False
|
|
assert data["ready_for_review_state_transaction_preview"] is False
|
|
assert data["ready_for_cli_decision_writer"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["approval_record_written"] is False
|
|
assert data["decision_record_written"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["decision_update_preview"] == []
|
|
assert "decision_preview_ready" in data["blocked_reasons"]
|
|
assert "do_not_update_review_state_from_approval_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
|
|
|
|
def test_candidate_queue_review_decision_transaction_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-transaction-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_transaction"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_transaction?execute=false",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"decision_approval_notes": "cli-only approval gate",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
"decision_transaction_notes": "shell-only transaction preview",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_decision_transaction_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["transaction_preview_created"] is False
|
|
assert data["transaction_ready"] is False
|
|
assert data["ready_for_manual_shell_update_window"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["approval_record_written"] is False
|
|
assert data["decision_record_written"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["explicit_transaction_opened"] is False
|
|
assert data["transaction_opened"] is False
|
|
assert data["transaction_committed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statements"] == []
|
|
assert "decision_approval_ready" in data["blocked_reasons"]
|
|
assert "transaction_statements_present" in data["blocked_reasons"]
|
|
assert "do_not_update_review_state_from_transaction_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_status_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-writer-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_status"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_status?execute=true"
|
|
"&apply_real_write=true",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"decision_approval_notes": "cli-only approval gate",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
"decision_transaction_notes": "shell-only transaction preview",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_decision_writer_cli_blocked"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is True
|
|
assert data["apply_real_write_requested"] is True
|
|
assert data["approval_token_present"] is False
|
|
assert data["approval_token_valid"] is False
|
|
assert data["writer_implementation_enabled"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_session_created"] is False
|
|
assert data["transaction_opened"] is False
|
|
assert data["transaction_committed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["writes_executed"] is False
|
|
assert data["would_write_database"] is False
|
|
assert "approval_token_present" in data["blocked_reasons"]
|
|
assert "review_decision_writer_implementation_enabled" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_execute_review_decision_writer_from_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_preflight_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-preflight-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_preflight"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_preflight?execute=true"
|
|
"&apply_real_write=true",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"decision_approval_notes": "cli-only approval gate",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
"decision_transaction_notes": "shell-only transaction preview",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_decision_writer_preflight_preview"
|
|
)
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is True
|
|
assert data["apply_real_write_requested"] is True
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_session_created"] is False
|
|
assert data["explicit_transaction_opened"] is False
|
|
assert data["transaction_opened"] is False
|
|
assert data["transaction_committed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["writes_executed"] is False
|
|
assert data["would_write_database"] is False
|
|
assert data["preflight_payload_ready"] is False
|
|
assert data["statement_summary"]["statement_count"] == 0
|
|
assert "statement_payloads_present" in data["blocked_reasons"]
|
|
assert "preflight_execute_not_requested_from_api" in data["blocked_reasons"]
|
|
assert "preflight_apply_real_write_not_requested_from_api" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "review_decision_writer_implementation_enabled" in data["blocked_reasons"]
|
|
assert "do_not_update_review_state_from_review_state_preflight" in data[
|
|
"safe_boundaries"
|
|
]
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_postwrite_smoke_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-postwrite-smoke-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_postwrite_smoke"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_postwrite_smoke",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"decision_approval_notes": "cli-only approval gate",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
"decision_transaction_notes": "shell-only transaction preview",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_decision_writer_postwrite_smoke_planned"
|
|
)
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_session_created"] is False
|
|
assert data["explicit_transaction_opened"] is False
|
|
assert data["transaction_opened"] is False
|
|
assert data["transaction_committed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["writes_executed"] is False
|
|
assert data["would_write_database"] is False
|
|
assert data["postwrite_smoke_passed"] is False
|
|
assert data["review_state_update_verified"] is False
|
|
assert "review_decision_writer_postwrite_smoke_not_loaded" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_update_review_state_from_postwrite_smoke" in data[
|
|
"safe_boundaries"
|
|
]
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_operator_drill_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-operator-drill-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_operator_drill"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_operator_drill",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"decision_approval_notes": "cli-only approval gate",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
"decision_transaction_notes": "shell-only transaction preview",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
"operator_confirmed_manual_shell_window": True,
|
|
"operator_confirmed_post_update_inventory_planned": True,
|
|
"operator_drill_notes": "manual shell drill reviewed",
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_decision_writer_operator_drill_preview"
|
|
)
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["operator_drill_ready"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_summary"]["statement_count"] == 0
|
|
assert data["input_summaries"]["writer_status_mode"] == (
|
|
"candidate_queue_review_decision_writer_cli_blocked"
|
|
)
|
|
assert "transaction_preview_created" in data["blocked_reasons"]
|
|
assert "transaction_has_update_statements" in data["blocked_reasons"]
|
|
assert "backup_verified_by_operator" in data["blocked_reasons"]
|
|
assert "do_not_execute_review_state_writer_from_operator_drill_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_run_package_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-run-package-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_package"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_package",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"decision_approval_notes": "cli-only approval gate",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
"decision_transaction_notes": "shell-only transaction preview",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
"operator_confirmed_manual_shell_window": True,
|
|
"operator_confirmed_post_update_inventory_planned": True,
|
|
"operator_drill_notes": "manual shell drill reviewed",
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_decision_writer_run_package_preview"
|
|
)
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["package_ready"] is False
|
|
assert data["package_artifact_created"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["payload_manifest"]["payload_count"] == 0
|
|
assert "transaction_preview_created" in data["blocked_reasons"]
|
|
assert "transaction_has_update_statements" in data["blocked_reasons"]
|
|
assert "backup_artifact_path_recorded" in data["blocked_reasons"]
|
|
assert "do_not_execute_review_state_writer_from_run_package_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_run_readiness_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-run-readiness-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_readiness"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_readiness"
|
|
"?execute=true&apply_real_write=true",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"review_state_transaction_json_path": (
|
|
"artifacts/market_intel/review-state-transaction.json"
|
|
),
|
|
"operator_confirmed_review_state_preflight_only": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"decision_approval_notes": "cli-only approval gate",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
"decision_transaction_notes": "shell-only transaction preview",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
"operator_confirmed_manual_shell_window": True,
|
|
"operator_confirmed_post_update_inventory_planned": True,
|
|
"operator_drill_notes": "manual shell drill reviewed",
|
|
},
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_decision_writer_run_readiness_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["ready_for_cli_operator_run"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["run_package_summary"]["payload_count"] == 0
|
|
assert "payload_count_within_small_batch_limit" in data["blocked_reasons"]
|
|
assert "do_not_execute_review_state_writer_from_run_readiness_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_run_receipt_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-run-receipt-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_receipt"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_receipt"
|
|
"?execute=true&apply_real_write=true",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"review_state_transaction_json_path": (
|
|
"artifacts/market_intel/review-state-transaction.json"
|
|
),
|
|
"operator_confirmed_review_state_preflight_only": True,
|
|
"operator_acknowledged_shell_only_token": True,
|
|
"review_state_writer_output_json_path": (
|
|
"artifacts/market_intel/review-state-writer-output.json"
|
|
),
|
|
"review_state_postwrite_smoke_json_path": (
|
|
"artifacts/market_intel/review-state-postwrite-smoke.json"
|
|
),
|
|
"operator_confirmed_no_token_in_artifacts": True,
|
|
"receipt_notes": "review_state receipt reviewed",
|
|
"closeout_artifact_path": "artifacts/market_intel/closeout.json",
|
|
"operator_confirmed_queue_review_next": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"operator_confirmed_inventory_read_only": True,
|
|
"reviewer_id": "operator-a",
|
|
"proposed_review_decision": "confirmed",
|
|
"decision_notes": "manual review only",
|
|
"operator_confirmed_manual_decision_only": True,
|
|
"decision_approval_notes": "cli-only approval gate",
|
|
"operator_confirmed_decision_payload_reviewed": True,
|
|
"operator_confirmed_decision_apply_requires_cli": True,
|
|
"operator_confirmed_review_state_update_is_not_api": True,
|
|
"decision_transaction_notes": "shell-only transaction preview",
|
|
"operator_confirmed_transaction_payload_reviewed": True,
|
|
"operator_confirmed_cli_only_transaction": True,
|
|
"operator_confirmed_manual_shell_window": True,
|
|
"operator_confirmed_post_update_inventory_planned": True,
|
|
"operator_drill_notes": "manual shell drill reviewed",
|
|
},
|
|
"writer_output": {
|
|
**fixture["writer_output"],
|
|
"mode": "candidate_queue_review_decision_writer_cli_executed",
|
|
"review_state_update_executed": True,
|
|
"api_updates_review_state": False,
|
|
},
|
|
"postwrite_smoke_result": {
|
|
**fixture["postwrite_smoke_result"],
|
|
"mode": (
|
|
"candidate_queue_review_decision_writer_postwrite_smoke_read_only"
|
|
),
|
|
"review_state_update_verified": True,
|
|
"state_mismatch_count": 0,
|
|
"state_mismatches": [],
|
|
},
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_decision_writer_run_receipt_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["receipt_passed"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == []
|
|
assert "expected_dedupe_keys_present" in data["blocked_reasons"]
|
|
assert "do_not_execute_review_state_writer_from_receipt_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_writer_run_closeout_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
"sample-batch-review-decision-run-closeout-route"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_closeout"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_closeout"
|
|
"?execute=true&apply_real_write=true",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": {
|
|
**fixture["operator_evidence"],
|
|
"review_state_closeout_artifact_path": (
|
|
"artifacts/market_intel/review-state-closeout.json"
|
|
),
|
|
"operator_confirmed_review_state_closeout_next": True,
|
|
"operator_confirmed_post_closeout_inventory_read_only": True,
|
|
"operator_confirmed_no_scheduler_attach": True,
|
|
"operator_confirmed_no_api_db_write": True,
|
|
"closeout_notes": "review_state closeout reviewed",
|
|
},
|
|
"writer_output": {
|
|
**fixture["writer_output"],
|
|
"mode": "candidate_queue_review_decision_writer_cli_executed",
|
|
"review_state_update_executed": True,
|
|
"api_updates_review_state": False,
|
|
},
|
|
"postwrite_smoke_result": {
|
|
**fixture["postwrite_smoke_result"],
|
|
"mode": (
|
|
"candidate_queue_review_decision_writer_postwrite_smoke_read_only"
|
|
),
|
|
"review_state_update_verified": True,
|
|
"state_mismatch_count": 0,
|
|
"state_mismatches": [],
|
|
},
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_decision_writer_run_closeout_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["closeout_passed"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["receipt_summary"]["expected_dedupe_key_count"] == 0
|
|
assert "receipt_expected_review_state_updates_present" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_update_review_state_from_review_state_closeout" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_decision_post_closeout_inventory_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_post_closeout_inventory"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_post_closeout_inventory"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_decision_post_closeout_inventory_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["post_closeout_inventory_ready"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == []
|
|
assert "expected_review_state_updates_present" in data["blocked_reasons"]
|
|
assert "do_not_update_review_state_from_post_closeout_inventory" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_completion_archive_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_completion_archive"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_completion_archive"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_completion_archive_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["review_completion_archive_ready"] is False
|
|
assert data["archive_manifest_ready"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["archive_file_written"] is False
|
|
assert data["archive_record_written"] is False
|
|
assert data["archive_manifest_written"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == []
|
|
assert "post_closeout_inventory_ready" in data["blocked_reasons"]
|
|
assert "do_not_write_archive_file_from_api" in data["safe_boundaries"]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_archive_summary_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_archive_summary"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_archive_summary"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_archive_summary_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["archive_summary_ready"] is False
|
|
assert data["summary_input_ready"] is False
|
|
assert data["ready_for_ai_summary_generation"] is False
|
|
assert data["ready_for_llm_call"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_file_written"] is False
|
|
assert data["summary_record_written"] is False
|
|
assert data["summary_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["ollama_call_executed"] is False
|
|
assert data["gemini_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == []
|
|
assert "review_completion_archive_ready" in data["blocked_reasons"]
|
|
assert "do_not_call_llm_from_archive_summary_gate" in data["safe_boundaries"]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_preflight_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_preflight"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_preflight"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_ai_summary_preflight_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["ai_summary_preflight_ready"] is False
|
|
assert data["ready_for_manual_ollama_summary_run"] is False
|
|
assert data["ready_for_ai_summary_generation"] is False
|
|
assert data["ready_for_llm_call"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_file_written"] is False
|
|
assert data["summary_record_written"] is False
|
|
assert data["summary_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["ollama_call_executed"] is False
|
|
assert data["gemini_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == []
|
|
assert "archive_summary_ready" in data["blocked_reasons"]
|
|
assert "do_not_call_llm_from_ai_summary_preflight" in data["safe_boundaries"]
|
|
assert (
|
|
data["model_route_policy"]["primary_policy"]
|
|
== "ollama_first"
|
|
)
|
|
assert (
|
|
data["model_route_policy"]["fallback_policy"]
|
|
== "gemini_backup_only_after_ollama_cascade_failure"
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_run_package_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_run_package"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_run_package"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_ai_summary_run_package_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["ai_summary_run_package_ready"] is False
|
|
assert data["ready_for_manual_ollama_summary_run"] is False
|
|
assert data["ready_for_ai_summary_generation"] is False
|
|
assert data["ready_for_llm_call"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["run_package_file_written"] is False
|
|
assert data["summary_file_written"] is False
|
|
assert data["summary_record_written"] is False
|
|
assert data["summary_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["ollama_call_executed"] is False
|
|
assert data["gemini_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == []
|
|
assert "archive_summary_ready" in data["blocked_reasons"]
|
|
assert "ai_summary_preflight_ready" in data["blocked_reasons"]
|
|
assert "do_not_call_llm_from_ai_summary_run_package" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert data["prompt_contract"]["contract_version"] == (
|
|
"market_intel_ai_summary_prompt_v1"
|
|
)
|
|
assert data["summary_output_schema"]["schema_version"] == (
|
|
"market_intel_ai_summary_v1"
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_output_receipt_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_output_receipt"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_output_receipt"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_review_ai_summary_output_receipt_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["ai_summary_output_receipt_ready"] is False
|
|
assert data["ready_for_summary_persistence_review"] is False
|
|
assert data["manual_ai_summary_output_provided"] is False
|
|
assert data["summary_output_schema_valid"] is False
|
|
assert data["summary_output_evidence_refs_grounded"] is False
|
|
assert data["summary_output_model_route_accepted"] is False
|
|
assert data["ready_for_ai_summary_generation"] is False
|
|
assert data["ready_for_llm_call"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_receipt_file_written"] is False
|
|
assert data["summary_file_written"] is False
|
|
assert data["summary_record_written"] is False
|
|
assert data["summary_manifest_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["ollama_call_executed"] is False
|
|
assert data["gemini_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == []
|
|
assert "ai_summary_run_package_ready" in data["blocked_reasons"]
|
|
assert "manual_ai_summary_output_provided" in data["blocked_reasons"]
|
|
assert "do_not_call_llm_from_ai_summary_output_receipt" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_preflight_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_preflight"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_preflight"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_preflight_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["summary_persistence_preflight_ready"] is False
|
|
assert data["ready_for_summary_transaction_preview"] is False
|
|
assert data["ready_for_summary_persistence_cli_run"] is False
|
|
assert data["ready_for_ai_summary_generation"] is False
|
|
assert data["ready_for_llm_call"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_review_state_update"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_persistence_preflight_file_written"] is False
|
|
assert data["summary_record_written"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["ollama_call_executed"] is False
|
|
assert data["gemini_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["expected_dedupe_keys"] == []
|
|
assert "ai_summary_output_receipt_ready" in data["blocked_reasons"]
|
|
assert "manual_ai_summary_output_still_provided" in data["blocked_reasons"]
|
|
assert "do_not_call_llm_from_ai_summary_persistence_preflight" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_transaction_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_transaction"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_transaction"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_transaction_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["summary_persistence_transaction_ready"] is False
|
|
assert data["ready_for_summary_persistence_writer_gate"] is False
|
|
assert data["ready_for_summary_persistence_cli_run"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_persistence_transaction_file_written"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["transaction_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert "summary_persistence_preflight_ready" in data["blocked_reasons"]
|
|
assert "summary_persistence_update_statements_planned" in data["blocked_reasons"]
|
|
assert "do_not_open_database_from_ai_summary_persistence_transaction" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_writer_preflight_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_writer_preflight"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_writer_preflight"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_writer_preflight_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["summary_persistence_writer_preflight_ready"] is False
|
|
assert data["ready_for_summary_persistence_run_package"] is False
|
|
assert data["ready_for_summary_persistence_cli_run"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_persistence_writer_preflight_file_written"] is False
|
|
assert data["writer_preflight_file_written"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["transaction_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert "summary_persistence_transaction_ready" in data["blocked_reasons"]
|
|
assert "summary_persistence_update_statements_valid" in data["blocked_reasons"]
|
|
assert (
|
|
"summary_persistence_writer_preflight_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_open_database_from_ai_summary_persistence_writer_preflight" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_run_package_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_package"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_package"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_package_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["package_ready"] is False
|
|
assert data["ready_for_summary_persistence_run_readiness"] is False
|
|
assert data["ready_for_summary_persistence_cli_run"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["package_artifact_created"] is False
|
|
assert data["summary_persistence_run_package_file_written"] is False
|
|
assert data["run_package_file_written"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["transaction_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["payload_manifest"]["payload_count"] == 0
|
|
assert "summary_persistence_writer_preflight_ready" in data["blocked_reasons"]
|
|
assert "summary_persistence_payload_manifest_ready" in data["blocked_reasons"]
|
|
assert (
|
|
"summary_persistence_run_package_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_open_database_connection_from_summary_persistence_run_package" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_run_readiness_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_readiness"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_readiness"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_readiness_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["run_readiness_ready"] is False
|
|
assert data["summary_persistence_run_readiness_ready"] is False
|
|
assert data["ready_for_cli_operator_run"] is False
|
|
assert data["ready_for_summary_persistence_cli_run"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["package_artifact_created"] is False
|
|
assert data["summary_persistence_run_readiness_file_written"] is False
|
|
assert data["run_readiness_file_written"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["transaction_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["run_package_summary"]["payload_count"] == 0
|
|
assert "summary_persistence_run_package_ready" in data["blocked_reasons"]
|
|
assert "summary_persistence_payload_manifest_small_batch" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"summary_persistence_run_readiness_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert (
|
|
"do_not_open_database_connection_from_summary_persistence_run_readiness"
|
|
in data["safe_boundaries"]
|
|
)
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_run_receipt_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_receipt"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_receipt"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_receipt_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["run_receipt_passed"] is False
|
|
assert data["summary_persistence_run_receipt_passed"] is False
|
|
assert data["ready_for_summary_persistence_closeout"] is False
|
|
assert data["ready_for_summary_persistence_cli_run"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["summary_persistence_run_receipt_file_written"] is False
|
|
assert data["run_receipt_file_written"] is False
|
|
assert data["receipt_file_written"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["transaction_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["expected_dedupe_keys"] == []
|
|
assert data["writer_output_summary"]["provided"] is False
|
|
assert data["postwrite_smoke_summary"]["provided"] is False
|
|
assert "run_readiness_passed_before_cli" in data["blocked_reasons"]
|
|
assert "expected_dedupe_keys_present" in data["blocked_reasons"]
|
|
assert "writer_output_provided" in data["blocked_reasons"]
|
|
assert "postwrite_smoke_result_provided" in data["blocked_reasons"]
|
|
assert "run_receipt_apply_real_write_not_requested_from_api" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_open_database_connection_from_summary_persistence_receipt" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_run_closeout_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_closeout"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_closeout"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_closeout_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["closeout_passed"] is False
|
|
assert data["summary_persistence_closeout_passed"] is False
|
|
assert data["ready_for_summary_persistence_telegram_dispatch_gate"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["summary_persistence_closeout_file_written"] is False
|
|
assert data["closeout_file_written"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["transaction_file_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["receipt_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_receipt_preview"
|
|
)
|
|
assert "receipt_passed" in data["blocked_reasons"]
|
|
assert "receipt_expected_dedupe_keys_present" in data["blocked_reasons"]
|
|
assert "closeout_artifact_path_recorded" in data["blocked_reasons"]
|
|
assert "operator_confirmed_telegram_dispatch_requires_separate_gate" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "closeout_apply_real_write_not_requested_from_api" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_open_database_connection_from_summary_persistence_closeout" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_gate_passed"] is False
|
|
assert data["summary_persistence_telegram_dispatch_gate_passed"] is False
|
|
assert data["ready_for_summary_persistence_telegram_dispatch_run_package"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_gate_file_written"] is False
|
|
assert data["telegram_message_file_written"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["closeout_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_run_closeout_preview"
|
|
)
|
|
assert "summary_persistence_closeout_passed" in data["blocked_reasons"]
|
|
assert "operator_confirmed_telegram_dispatch_gate" in data["blocked_reasons"]
|
|
assert "telegram_dispatch_gate_artifact_path_recorded" in data["blocked_reasons"]
|
|
assert "telegram_dispatch_gate_apply_real_write_not_requested_from_api" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "do_not_dispatch_telegram_from_summary_persistence_telegram_dispatch_gate_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_run_package_ready"] is False
|
|
assert data["summary_persistence_telegram_dispatch_run_package_ready"] is False
|
|
assert data["ready_for_summary_persistence_telegram_dispatch_run_readiness"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_run_package_file_written"] is False
|
|
assert data["telegram_message_file_written"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_gate_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate_preview"
|
|
)
|
|
assert "telegram_dispatch_gate_ready" in data["blocked_reasons"]
|
|
assert "operator_confirmed_telegram_dispatch_run_package" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "telegram_dispatch_run_package_artifacts_recorded" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_run_package_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_run_package_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_run_readiness_ready"] is False
|
|
assert (
|
|
data["summary_persistence_telegram_dispatch_run_readiness_ready"] is False
|
|
)
|
|
assert data["ready_for_manual_telegram_dispatch"] is False
|
|
assert (
|
|
data["ready_for_summary_persistence_telegram_dispatch_run_receipt"]
|
|
is False
|
|
)
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_run_readiness_file_written"] is False
|
|
assert data["telegram_dispatch_run_package_file_written"] is False
|
|
assert data["telegram_message_file_written"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["telegram_dispatch_attempted"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_run_package_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package_preview"
|
|
)
|
|
assert "telegram_dispatch_run_package_ready" in data["blocked_reasons"]
|
|
assert "telegram_dispatch_readiness_artifacts_recorded" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "operator_confirmed_telegram_dispatch_run_readiness" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_run_readiness_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_run_readiness_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_run_receipt_passed"] is False
|
|
assert data["summary_persistence_telegram_dispatch_run_receipt_passed"] is False
|
|
assert data["ready_for_summary_persistence_telegram_dispatch_closeout"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_run_receipt_file_written"] is False
|
|
assert data["telegram_dispatch_receipt_file_written"] is False
|
|
assert data["telegram_message_file_written"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["telegram_dispatch_attempted"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_run_readiness_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness_preview"
|
|
)
|
|
assert "telegram_dispatch_run_readiness_passed_before_manual_dispatch" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "telegram_dispatch_receipt_provided" in data["blocked_reasons"]
|
|
assert "operator_confirmed_telegram_dispatch_receipt" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_run_receipt_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_run_receipt_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_closeout_passed"] is False
|
|
assert data["summary_persistence_telegram_dispatch_closeout_passed"] is False
|
|
assert data["ready_for_summary_persistence_telegram_dispatch_archive"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_closeout_file_written"] is False
|
|
assert data["telegram_dispatch_run_receipt_file_written"] is False
|
|
assert data["telegram_dispatch_receipt_file_written"] is False
|
|
assert data["telegram_message_file_written"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["telegram_dispatch_attempted"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_run_receipt_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt_preview"
|
|
)
|
|
assert "telegram_dispatch_run_receipt_passed" in data["blocked_reasons"]
|
|
assert "telegram_dispatch_closeout_artifact_path_recorded" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "operator_confirmed_telegram_dispatch_closeout" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_closeout_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_closeout_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
from routes.market_intel_review_routes import market_intel_review_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
app.register_blueprint(market_intel_review_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
get_response = client.get(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
)
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
"?execute=true&apply_real_write=true",
|
|
json={"sample_result": {}},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert get_response.status_code == 405
|
|
assert response.status_code == 200
|
|
assert data["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_preview"
|
|
)
|
|
assert data["phase"] == (
|
|
"phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
)
|
|
assert data["telegram_dispatch_archive_ready"] is False
|
|
assert data["summary_persistence_telegram_dispatch_archive_ready"] is False
|
|
assert data["archive_manifest_ready"] is False
|
|
assert data["ready_for_summary_persistence_telegram_dispatch_archive_summary"] is False
|
|
assert data["ready_for_telegram_dispatch"] is False
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_dispatches_telegram"] is False
|
|
assert data["api_executes_llm"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["api_updates_review_state"] is False
|
|
assert data["telegram_dispatch_archive_file_written"] is False
|
|
assert data["telegram_dispatch_closeout_file_written"] is False
|
|
assert data["telegram_dispatch_receipt_file_written"] is False
|
|
assert data["telegram_message_file_written"] is False
|
|
assert data["archive_file_written"] is False
|
|
assert data["archive_record_written"] is False
|
|
assert data["archive_manifest_written"] is False
|
|
assert data["summary_persistence_record_written"] is False
|
|
assert data["metadata_patch_written"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["telegram_dispatch_attempted"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["review_state_update_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["statement_count"] == 0
|
|
assert data["telegram_dispatch_closeout_summary"]["mode"] == (
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout_preview"
|
|
)
|
|
assert "telegram_dispatch_closeout_passed" in data["blocked_reasons"]
|
|
assert "telegram_dispatch_archive_artifact_paths_recorded" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert "operator_confirmed_telegram_dispatch_archive" in data[
|
|
"blocked_reasons"
|
|
]
|
|
assert (
|
|
"telegram_dispatch_archive_apply_real_write_not_requested_from_api"
|
|
in data["blocked_reasons"]
|
|
)
|
|
assert "do_not_dispatch_telegram_from_telegram_dispatch_archive_api" in data[
|
|
"safe_boundaries"
|
|
]
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_candidate_queue_writer_run_receipt_route_is_post_only_and_no_write():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
fixture = _build_candidate_queue_writer_receipt_fixture(
|
|
batch_id="sample-batch-route-receipt"
|
|
)
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.post(
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_writer_run_receipt",
|
|
json={
|
|
"sample_result": fixture["sample_result"],
|
|
"operator_evidence": fixture["operator_evidence"],
|
|
"writer_output": fixture["writer_output"],
|
|
"postwrite_smoke_result": fixture["postwrite_smoke_result"],
|
|
},
|
|
)
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "candidate_queue_writer_run_receipt_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["receipt_passed"] is True
|
|
assert data["ready_for_next_manual_review"] is True
|
|
assert data["ready_for_api_database_write"] is False
|
|
assert data["ready_for_scheduler_attach"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_writes_file"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["writer_output_summary"]["database_commit_executed"] is True
|
|
assert data["writer_output_summary"]["dedupe_keys_match_expected"] is True
|
|
assert data["postwrite_smoke_summary"]["postwrite_smoke_passed"] is True
|
|
assert data["postwrite_smoke_summary"]["dedupe_keys_match_expected"] is True
|
|
assert data["blocked_reasons"] == []
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
|
|
|
|
def test_scheduler_plan_preview_blocks_job_attachment():
|
|
plan = MarketIntelService().build_scheduler_plan()
|
|
|
|
assert plan["mode"] == "scheduler_attach_plan_preview"
|
|
assert plan["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert plan["ready_to_attach_scheduler"] is False
|
|
assert plan["scheduler_attached"] is False
|
|
assert plan["scheduler_registration_executed"] is False
|
|
assert plan["crawler_job_started"] is False
|
|
assert plan["external_network_executed"] is False
|
|
assert plan["database_session_created"] is False
|
|
assert plan["database_write_executed"] is False
|
|
assert plan["database_commit_executed"] is False
|
|
assert plan["writes_executed"] is False
|
|
assert plan["would_write_database"] is False
|
|
assert plan["job_count"] == 3
|
|
assert {item["key"] for item in plan["jobs"]} == {
|
|
"campaign_discovery_daily",
|
|
"campaign_product_probe",
|
|
"product_match_review_seed",
|
|
}
|
|
assert "market_intel_enabled" in plan["blocked_reasons"]
|
|
assert "mcp_fetch_gate_open" in plan["blocked_reasons"]
|
|
assert "manual_operator_approval" in plan["blocked_reasons"]
|
|
assert "do_not_attach_scheduler_from_api" in plan["safe_boundaries"]
|
|
|
|
|
|
def test_scheduler_plan_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/scheduler_plan")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "scheduler_attach_plan_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["scheduler_registration_executed"] is False
|
|
assert data["crawler_job_started"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
|
|
|
|
def test_match_review_plan_preview_blocks_auto_confirm():
|
|
plan = MarketIntelService().build_match_review_plan()
|
|
|
|
assert plan["mode"] == "match_review_plan_preview"
|
|
assert plan["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert plan["ready_for_review_queue"] is False
|
|
assert plan["review_queue_created"] is False
|
|
assert plan["auto_match_executed"] is False
|
|
assert plan["auto_confirm_executed"] is False
|
|
assert plan["database_session_created"] is False
|
|
assert plan["database_write_executed"] is False
|
|
assert plan["database_commit_executed"] is False
|
|
assert plan["external_network_executed"] is False
|
|
assert plan["scheduler_attached"] is False
|
|
assert plan["writes_executed"] is False
|
|
assert plan["would_write_database"] is False
|
|
assert plan["thresholds"]["auto_confirm_enabled"] is False
|
|
assert len(plan["scoring_signals"]) >= 5
|
|
assert "needs_review" in plan["planned_status_flow"]
|
|
assert "confirmed" in plan["planned_status_flow"]
|
|
assert "manual_operator_approval" in plan["blocked_reasons"]
|
|
assert "do_not_auto_confirm_matches" in plan["safe_boundaries"]
|
|
assert all(item["requires_operator"] for item in plan["review_actions"])
|
|
|
|
|
|
def test_match_review_plan_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/match_review_plan")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "match_review_plan_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["review_queue_created"] is False
|
|
assert data["auto_confirm_executed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
|
|
|
|
def test_opportunity_plan_preview_blocks_alerts_and_ai_summary():
|
|
plan = MarketIntelService().build_opportunity_plan()
|
|
|
|
assert plan["mode"] == "opportunity_plan_preview"
|
|
assert plan["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert plan["ready_for_opportunity_queue"] is False
|
|
assert plan["opportunity_queue_created"] is False
|
|
assert plan["threat_alert_dispatched"] is False
|
|
assert plan["telegram_dispatched"] is False
|
|
assert plan["ai_summary_generated"] is False
|
|
assert plan["database_session_created"] is False
|
|
assert plan["database_write_executed"] is False
|
|
assert plan["database_commit_executed"] is False
|
|
assert plan["external_network_executed"] is False
|
|
assert plan["scheduler_attached"] is False
|
|
assert plan["writes_executed"] is False
|
|
assert plan["would_write_database"] is False
|
|
assert plan["rule_count"] == 4
|
|
assert {item["key"] for item in plan["rules"]} == {
|
|
"competitor_price_threat",
|
|
"promotion_gap",
|
|
"deep_discount_overlap",
|
|
"campaign_ending_watch",
|
|
}
|
|
assert "match_review_candidates_available" in plan["blocked_reasons"]
|
|
assert "manual_operator_approval" in plan["blocked_reasons"]
|
|
assert "do_not_dispatch_alerts_from_preview" in plan["safe_boundaries"]
|
|
assert "do_not_auto_adjust_price" in plan["safe_boundaries"]
|
|
|
|
|
|
def test_opportunity_plan_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/opportunity_plan")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "opportunity_plan_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["opportunity_queue_created"] is False
|
|
assert data["threat_alert_dispatched"] is False
|
|
assert data["ai_summary_generated"] is False
|
|
assert data["database_write_executed"] is False
|
|
|
|
|
|
def test_opportunity_scoring_plan_preview_blocks_scoring_and_alerts():
|
|
plan = MarketIntelService().build_opportunity_scoring_plan()
|
|
|
|
assert plan["mode"] == "opportunity_scoring_plan_preview"
|
|
assert plan["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert plan["ready_for_scoring_job"] is False
|
|
assert plan["scoring_job_created"] is False
|
|
assert plan["score_calculation_executed"] is False
|
|
assert plan["sample_scores_generated"] is False
|
|
assert plan["opportunity_queue_created"] is False
|
|
assert plan["review_queue_created"] is False
|
|
assert plan["threat_alert_dispatched"] is False
|
|
assert plan["telegram_dispatched"] is False
|
|
assert plan["ai_summary_generated"] is False
|
|
assert plan["database_session_created"] is False
|
|
assert plan["database_write_executed"] is False
|
|
assert plan["database_commit_executed"] is False
|
|
assert plan["external_network_executed"] is False
|
|
assert plan["scheduler_attached"] is False
|
|
assert plan["writes_executed"] is False
|
|
assert plan["would_write_database"] is False
|
|
assert plan["dimension_count"] == 5
|
|
assert plan["total_weight"] == 100
|
|
assert {item["key"] for item in plan["dimensions"]} == {
|
|
"price_gap_pct",
|
|
"discount_depth",
|
|
"match_confidence",
|
|
"campaign_urgency",
|
|
"data_freshness",
|
|
}
|
|
assert "opportunity_queue_ready" in plan["blocked_reasons"]
|
|
assert "confirmed_match_source_ready" in plan["blocked_reasons"]
|
|
assert "manual_operator_approval" in plan["blocked_reasons"]
|
|
assert "do_not_write_scoring_results_from_preview" in plan["safe_boundaries"]
|
|
assert "do_not_auto_adjust_price" in plan["safe_boundaries"]
|
|
|
|
|
|
def test_opportunity_scoring_plan_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/opportunity_scoring_plan")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "opportunity_scoring_plan_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["scoring_job_created"] is False
|
|
assert data["score_calculation_executed"] is False
|
|
assert data["sample_scores_generated"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["external_network_executed"] is False
|
|
|
|
|
|
def test_opportunity_evidence_plan_preview_blocks_queries_and_alerts():
|
|
plan = MarketIntelService().build_opportunity_evidence_plan()
|
|
|
|
assert plan["mode"] == "opportunity_evidence_plan_preview"
|
|
assert plan["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert plan["ready_for_evidence_bundle"] is False
|
|
assert plan["evidence_bundle_created"] is False
|
|
assert plan["evidence_query_executed"] is False
|
|
assert plan["sample_evidence_generated"] is False
|
|
assert plan["alert_candidate_created"] is False
|
|
assert plan["telegram_dispatched"] is False
|
|
assert plan["ai_summary_generated"] is False
|
|
assert plan["database_session_created"] is False
|
|
assert plan["database_write_executed"] is False
|
|
assert plan["database_commit_executed"] is False
|
|
assert plan["external_network_executed"] is False
|
|
assert plan["scheduler_attached"] is False
|
|
assert plan["writes_executed"] is False
|
|
assert plan["would_write_database"] is False
|
|
assert plan["section_count"] == 5
|
|
assert {item["key"] for item in plan["sections"]} == {
|
|
"campaign_context",
|
|
"market_product_snapshot",
|
|
"match_review_state",
|
|
"momo_reference",
|
|
"scoring_trace",
|
|
}
|
|
assert "confirmed_match_evidence_available" in plan["blocked_reasons"]
|
|
assert "scoring_trace_available" in plan["blocked_reasons"]
|
|
assert "manual_operator_approval" in plan["blocked_reasons"]
|
|
assert "do_not_query_database_from_evidence_preview" in plan["safe_boundaries"]
|
|
assert "do_not_generate_placeholder_evidence" in plan["safe_boundaries"]
|
|
assert plan["bundle_contract"]["freshness_window_hours"] == 24
|
|
|
|
|
|
def test_opportunity_evidence_plan_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/opportunity_evidence_plan")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "opportunity_evidence_plan_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["evidence_bundle_created"] is False
|
|
assert data["evidence_query_executed"] is False
|
|
assert data["sample_evidence_generated"] is False
|
|
assert data["alert_candidate_created"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["external_network_executed"] is False
|
|
|
|
|
|
def test_opportunity_alert_plan_preview_blocks_dispatch_and_llm_calls():
|
|
plan = MarketIntelService().build_opportunity_alert_plan()
|
|
|
|
assert plan["mode"] == "opportunity_alert_plan_preview"
|
|
assert plan["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert plan["ready_for_alert_candidates"] is False
|
|
assert plan["alert_candidate_created"] is False
|
|
assert plan["alert_queue_created"] is False
|
|
assert plan["review_queue_created"] is False
|
|
assert plan["review_queue_contract_defined"] is True
|
|
assert plan["review_queue_contract_written"] is False
|
|
assert plan["review_queue_table_created"] is False
|
|
assert plan["review_action_executed"] is False
|
|
assert plan["approval_record_written"] is False
|
|
assert plan["telegram_dispatched"] is False
|
|
assert plan["ai_summary_generated"] is False
|
|
assert plan["llm_call_executed"] is False
|
|
assert plan["notification_sent"] is False
|
|
assert plan["database_session_created"] is False
|
|
assert plan["database_write_executed"] is False
|
|
assert plan["database_commit_executed"] is False
|
|
assert plan["external_network_executed"] is False
|
|
assert plan["scheduler_attached"] is False
|
|
assert plan["writes_executed"] is False
|
|
assert plan["would_write_database"] is False
|
|
assert plan["channel_count"] == 4
|
|
assert {item["key"] for item in plan["channels"]} == {
|
|
"operator_review",
|
|
"daily_digest",
|
|
"telegram_candidate",
|
|
"ai_briefing_candidate",
|
|
}
|
|
assert plan["review_state_count"] == 6
|
|
assert {item["key"] for item in plan["review_states"]} == {
|
|
"draft",
|
|
"needs_review",
|
|
"approved_for_digest",
|
|
"approved_for_telegram",
|
|
"rejected",
|
|
"deferred",
|
|
}
|
|
assert {item["key"] for item in plan["review_actions"]} == {
|
|
"approve_digest",
|
|
"approve_telegram",
|
|
"reject",
|
|
"defer",
|
|
}
|
|
assert plan["review_queue_contract"]["table_name"] == "market_alert_review_queue"
|
|
assert "alert_candidate_id" in plan["review_queue_contract"]["required_fields"]
|
|
assert "reviewer_identity" in plan["review_queue_contract"]["audit_fields"]
|
|
assert "payment_or_shipping_data" in plan["review_queue_contract"]["forbidden_fields"]
|
|
assert {item["key"] for item in plan["review_priority_lanes"]} == {
|
|
"critical",
|
|
"high",
|
|
"medium",
|
|
"watch",
|
|
}
|
|
assert {item["key"] for item in plan["review_queue_indexes"]} == {
|
|
"idx_market_alert_review_queue_state_priority",
|
|
"ux_market_alert_review_queue_dedupe",
|
|
"idx_market_alert_review_queue_bundle",
|
|
}
|
|
assert plan["approval_policy"]["manual_approval_required_for_dispatch"] is True
|
|
assert plan["approval_policy"]["reviewer_identity_required"] is True
|
|
assert "evidence_bundle_ready" in plan["blocked_reasons"]
|
|
assert "scoring_job_ready" in plan["blocked_reasons"]
|
|
assert "operator_approval" in plan["blocked_reasons"]
|
|
assert "do_not_dispatch_telegram_from_alert_preview" in plan["safe_boundaries"]
|
|
assert "do_not_create_review_queue_table_from_preview" in plan["safe_boundaries"]
|
|
assert "do_not_write_review_queue_contract_from_preview" in plan["safe_boundaries"]
|
|
assert "do_not_call_llm_from_alert_preview" in plan["safe_boundaries"]
|
|
assert "customer_personal_data" in plan["payload_contract"]["forbidden_fields"]
|
|
|
|
|
|
def test_opportunity_alert_plan_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/opportunity_alert_plan")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "opportunity_alert_plan_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["alert_candidate_created"] is False
|
|
assert data["alert_queue_created"] is False
|
|
assert data["review_queue_created"] is False
|
|
assert data["review_queue_contract_defined"] is True
|
|
assert data["review_queue_contract_written"] is False
|
|
assert data["review_queue_table_created"] is False
|
|
assert data["review_action_executed"] is False
|
|
assert data["approval_record_written"] is False
|
|
assert data["telegram_dispatched"] is False
|
|
assert data["llm_call_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["external_network_executed"] is False
|
|
|
|
|
|
def test_mcp_deploy_preflight_blocks_without_required_env():
|
|
preflight = build_mcp_deploy_preflight_plan(env={})
|
|
|
|
assert preflight["mode"] == "mcp_external_deploy_preflight_preview"
|
|
assert preflight["compose_file_present"] is True
|
|
assert preflight["ready_to_start_stack"] is False
|
|
assert preflight["checks"]["compose_file_present"] is True
|
|
assert preflight["checks"]["all_expected_services_declared"] is True
|
|
assert preflight["checks"]["all_expected_containers_declared"] is True
|
|
assert preflight["checks"]["all_public_mcp_ports_localhost_only"] is True
|
|
assert preflight["checks"]["required_env_vars_present"] is False
|
|
assert preflight["checks"]["router_flag_still_off_before_health"] is True
|
|
assert "required_env_vars_present" in preflight["blocked_reasons"]
|
|
assert preflight["operator_command_preview"] == "docker compose -f docker-compose.mcp.yml up -d"
|
|
assert preflight["deployment_actions_executed"] is False
|
|
assert preflight["docker_command_executed"] is False
|
|
assert preflight["ssh_command_executed"] is False
|
|
assert preflight["database_session_created"] is False
|
|
assert preflight["database_write_executed"] is False
|
|
assert preflight["database_commit_executed"] is False
|
|
assert preflight["external_network_executed"] is False
|
|
assert preflight["scheduler_attached"] is False
|
|
assert preflight["would_write_database"] is False
|
|
|
|
|
|
def test_mcp_compose_is_mounted_read_only_for_preflight():
|
|
compose = Path("docker-compose.yml").read_text(encoding="utf-8")
|
|
|
|
assert "./docker-compose.mcp.yml:/app/docker-compose.mcp.yml:ro" in compose
|
|
|
|
|
|
def test_mcp_deploy_preflight_ready_when_env_contract_is_present():
|
|
preflight = build_mcp_deploy_preflight_plan(
|
|
env={
|
|
"MCP_POSTGRES_PASSWORD": "secret",
|
|
"TAVILY_API_KEY": "tavily",
|
|
"EXA_API_KEY": "exa",
|
|
"MCP_ROUTER_ENABLED": "false",
|
|
}
|
|
)
|
|
|
|
assert preflight["ready_to_start_stack"] is True
|
|
assert preflight["blocked_reasons"] == []
|
|
assert preflight["checks"]["required_env_vars_present"] is True
|
|
assert preflight["checks"]["router_flag_still_off_before_health"] is True
|
|
assert all(item["localhost_only"] for item in preflight["port_statuses"])
|
|
|
|
|
|
def test_mcp_deploy_preflight_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/mcp_deploy_preflight")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "mcp_external_deploy_preflight_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["deployment_actions_executed"] is False
|
|
assert data["docker_command_executed"] is False
|
|
assert data["ssh_command_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["external_network_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
|
|
|
|
def test_mcp_readiness_default_is_planned_only(monkeypatch):
|
|
monkeypatch.delenv("MCP_ROUTER_ENABLED", raising=False)
|
|
|
|
readiness = MarketIntelService().build_mcp_readiness()
|
|
|
|
assert readiness["mode"] == "mcp_readiness_planned"
|
|
assert readiness["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert readiness["execute_requested"] is False
|
|
assert readiness["router_enabled"] is False
|
|
assert readiness["external_mcp_complete"] is False
|
|
assert readiness["internal_mcp_complete"] is False
|
|
assert readiness["market_intel_mcp_integrated"] is True
|
|
assert readiness["mcp_tool_contract"]["contract_ready"] is True
|
|
assert readiness["database_session_created"] is False
|
|
assert readiness["database_write_executed"] is False
|
|
assert readiness["database_commit_executed"] is False
|
|
assert readiness["external_network_executed"] is False
|
|
assert readiness["scheduler_attached"] is False
|
|
assert readiness["writes_executed"] is False
|
|
assert readiness["would_write_database"] is False
|
|
assert readiness["telemetry"]["read_only_query_executed"] is False
|
|
assert readiness["telemetry"]["database_session_created"] is False
|
|
assert readiness["telemetry"]["database_write_executed"] is False
|
|
assert readiness["readiness_checks"]["base_callers_registered"] is True
|
|
assert readiness["readiness_checks"]["market_intel_caller_registered"] is True
|
|
assert readiness["readiness_checks"]["market_intel_tools_registered"] is True
|
|
assert readiness["readiness_checks"]["market_intel_tool_contract_ready"] is True
|
|
assert len(readiness["server_statuses"]) == 4
|
|
assert all(item["health_checked"] is False for item in readiness["server_statuses"])
|
|
assert all(item["healthy"] is False for item in readiness["server_statuses"])
|
|
assert "execute_false_planned_only" in readiness["blocked_reasons"]
|
|
assert "market_intel_caller_registered" not in readiness["blocked_reasons"]
|
|
assert "market_intel_tools_registered" not in readiness["blocked_reasons"]
|
|
|
|
|
|
def test_mcp_readiness_sqlite_read_only_counts_telemetry(monkeypatch):
|
|
monkeypatch.delenv("MCP_ROUTER_ENABLED", raising=False)
|
|
monkeypatch.setattr(
|
|
"services.market_intel.mcp_readiness._health_check_servers",
|
|
lambda base_hosts, timeout_sec: [
|
|
{
|
|
"server": "postgres",
|
|
"base_url": "http://127.0.0.1:3001",
|
|
"configured": True,
|
|
"health_checked": True,
|
|
"healthy": False,
|
|
"status": "error",
|
|
"error_message": "test skipped network",
|
|
},
|
|
{
|
|
"server": "omnisearch",
|
|
"base_url": "http://127.0.0.1:3003",
|
|
"configured": True,
|
|
"health_checked": True,
|
|
"healthy": False,
|
|
"status": "error",
|
|
"error_message": "test skipped network",
|
|
},
|
|
{
|
|
"server": "firecrawl",
|
|
"base_url": "http://127.0.0.1:3002",
|
|
"configured": True,
|
|
"health_checked": True,
|
|
"healthy": False,
|
|
"status": "error",
|
|
"error_message": "test skipped network",
|
|
},
|
|
{
|
|
"server": "filesystem",
|
|
"base_url": "http://127.0.0.1:3004",
|
|
"configured": True,
|
|
"health_checked": True,
|
|
"healthy": False,
|
|
"status": "error",
|
|
"error_message": "test skipped network",
|
|
},
|
|
],
|
|
)
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE mcp_calls (
|
|
id INTEGER PRIMARY KEY,
|
|
server TEXT,
|
|
called_at TEXT
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
INSERT INTO mcp_calls (server, called_at)
|
|
VALUES
|
|
('omnisearch', '2026-05-18 10:00:00'),
|
|
('omnisearch', '2026-05-18 10:05:00'),
|
|
('postgres', '2026-05-18 10:10:00')
|
|
"""
|
|
)
|
|
)
|
|
|
|
readiness = build_mcp_readiness_plan(
|
|
execute_requested=True,
|
|
timeout_sec=1,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
|
|
assert readiness["mode"] == "mcp_readiness_read_only"
|
|
assert readiness["execute_requested"] is True
|
|
assert readiness["router_enabled"] is False
|
|
assert readiness["external_mcp_complete"] is False
|
|
assert readiness["internal_mcp_complete"] is True
|
|
assert readiness["market_intel_mcp_integrated"] is True
|
|
assert readiness["mcp_tool_contract"]["contract_ready"] is True
|
|
assert readiness["telemetry"]["mode"] == "mcp_telemetry_read_only"
|
|
assert readiness["telemetry"]["table_exists"] is True
|
|
assert readiness["telemetry"]["total_calls"] == 3
|
|
assert readiness["telemetry"]["recent_24h_calls"] == 3
|
|
assert readiness["telemetry"]["read_only_query_executed"] is True
|
|
assert readiness["telemetry"]["database_session_created"] is False
|
|
assert readiness["telemetry"]["database_write_executed"] is False
|
|
assert readiness["telemetry"]["database_commit_executed"] is False
|
|
assert readiness["database_session_created"] is False
|
|
assert readiness["database_write_executed"] is False
|
|
assert readiness["database_commit_executed"] is False
|
|
assert readiness["scheduler_attached"] is False
|
|
assert readiness["writes_executed"] is False
|
|
assert readiness["would_write_database"] is False
|
|
assert readiness["server_statuses"][0]["health_checked"] is True
|
|
assert {item["server"]: item["calls"] for item in readiness["telemetry"]["server_counts"]} == {
|
|
"omnisearch": 2,
|
|
"postgres": 1,
|
|
}
|
|
assert "mcp_router_enabled" in readiness["blocked_reasons"]
|
|
assert "market_intel_caller_registered" not in readiness["blocked_reasons"]
|
|
|
|
|
|
def test_market_intel_schema_smoke_checks_platform_columns():
|
|
smoke = MarketIntelService().build_schema_smoke()["schema_smoke"]
|
|
|
|
assert smoke["passed"] is True
|
|
assert smoke["missing_tables"] == []
|
|
assert smoke["missing_market_platform_columns"] == []
|
|
assert "crawl_policy_json" in smoke["market_platform_required_columns"]
|
|
|
|
|
|
def test_platform_seed_plan_is_read_only_and_adapter_derived():
|
|
plan = MarketIntelService().build_platform_seed_plan()
|
|
seed_codes = {seed["code"] for seed in plan["seeds"]}
|
|
|
|
assert {"momo", "pchome", "coupang", "shopee"} <= seed_codes
|
|
assert plan["would_write_database"] is False
|
|
assert plan["required_gates"]["schema_smoke_required"] is True
|
|
assert plan["required_gates"]["migration_required"] is True
|
|
assert plan["required_gates"]["manual_operator_approval_required"] is True
|
|
|
|
for seed in plan["seeds"]:
|
|
policy = seed["crawl_policy_json"]
|
|
assert seed["enabled"] is False
|
|
assert seed["source_count"] == len(seed["sources"])
|
|
assert policy["allow_login"] is False
|
|
assert policy["allow_database_write"] is False
|
|
assert policy["allow_scheduler_attach"] is False
|
|
|
|
|
|
def test_platform_seed_plan_unknown_adapter_returns_diagnostic_error():
|
|
plan = MarketIntelService().build_platform_seed_plan("unknown")
|
|
|
|
assert plan["found"] is False
|
|
assert plan["seed_count"] == 0
|
|
assert plan["error"] == "未知平台 adapter"
|
|
|
|
|
|
def test_platform_seed_write_guard_blocks_default_environment():
|
|
guard = MarketIntelService().build_platform_seed_write_guard()
|
|
|
|
assert guard["ready_to_write"] is False
|
|
assert guard["would_write_database"] is False
|
|
assert guard["database_write_allowed"] is False
|
|
assert guard["seed_count"] == 4
|
|
assert "market_intel_enabled" in guard["blocked_reasons"]
|
|
assert "market_intel_write_enabled" in guard["blocked_reasons"]
|
|
assert "database_write_allowed" in guard["blocked_reasons"]
|
|
assert "migration_confirmed" in guard["blocked_reasons"]
|
|
assert "manual_operator_approval" in guard["blocked_reasons"]
|
|
assert guard["schema_smoke"]["passed"] is True
|
|
assert "schema_smoke_confirmed" not in guard["blocked_reasons"]
|
|
|
|
|
|
def test_platform_seed_writer_plan_is_dry_run_only():
|
|
writer_plan = MarketIntelService().build_platform_seed_writer_plan()
|
|
|
|
assert writer_plan["mode"] == "dry_run"
|
|
assert writer_plan["ready_to_write"] is False
|
|
assert writer_plan["writes_executed"] is False
|
|
assert writer_plan["would_write_database"] is False
|
|
assert writer_plan["operation_count"] == 4
|
|
assert writer_plan["schema_smoke"]["passed"] is True
|
|
|
|
first_operation = writer_plan["operations"][0]
|
|
assert first_operation["operation"] == "upsert"
|
|
assert first_operation["table"] == "market_platforms"
|
|
assert first_operation["write_status"] == "blocked_dry_run_only"
|
|
assert first_operation["values"]["enabled"] is False
|
|
assert "ON CONFLICT(code)" in first_operation["sql_shape"]
|
|
|
|
|
|
def test_schema_db_probe_planned_does_not_connect_or_write():
|
|
probe = MarketIntelService().build_schema_db_probe()
|
|
|
|
assert probe["mode"] == "schema_db_probe_planned"
|
|
assert probe["execute_requested"] is False
|
|
assert probe["read_only_query_executed"] is False
|
|
assert probe["database_connection_opened"] is False
|
|
assert probe["database_session_created"] is False
|
|
assert probe["explicit_transaction_opened"] is False
|
|
assert probe["database_write_executed"] is False
|
|
assert probe["database_commit_executed"] is False
|
|
assert probe["migration_executed"] is False
|
|
assert probe["missing_tables"] == list(MARKET_INTEL_TABLES)
|
|
assert "execute_false_planned_only" in probe["blocked_reasons"]
|
|
|
|
|
|
def test_schema_db_probe_sqlite_read_only_reports_existing_and_missing_tables():
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(text("CREATE TABLE market_platforms (id INTEGER PRIMARY KEY)"))
|
|
|
|
probe = build_schema_db_probe_plan(
|
|
["market_platforms", "market_campaigns"],
|
|
execute_requested=True,
|
|
database_type="sqlite",
|
|
engine=engine,
|
|
)
|
|
|
|
assert probe["mode"] == "schema_db_probe_read_only"
|
|
assert probe["execute_requested"] is True
|
|
assert probe["read_only_query_executed"] is True
|
|
assert probe["database_connection_opened"] is True
|
|
assert probe["database_session_created"] is False
|
|
assert probe["explicit_transaction_opened"] is False
|
|
assert probe["database_write_executed"] is False
|
|
assert probe["database_commit_executed"] is False
|
|
assert probe["existing_tables"] == ["market_platforms"]
|
|
assert probe["missing_tables"] == ["market_campaigns"]
|
|
assert probe["schema_tables_exist"] is False
|
|
assert "market_tables_missing" in probe["blocked_reasons"]
|
|
|
|
|
|
def test_platform_seed_db_diff_planned_does_not_connect_or_write():
|
|
diff = MarketIntelService().build_platform_seed_db_diff()
|
|
|
|
assert diff["mode"] == "platform_seed_db_diff_planned"
|
|
assert diff["execute_requested"] is False
|
|
assert diff["read_only_query_executed"] is False
|
|
assert diff["database_connection_opened"] is False
|
|
assert diff["database_session_created"] is False
|
|
assert diff["explicit_transaction_opened"] is False
|
|
assert diff["database_write_executed"] is False
|
|
assert diff["database_commit_executed"] is False
|
|
assert diff["seed_write_executed"] is False
|
|
assert diff["expected_seed_count"] == 4
|
|
assert set(diff["missing_codes"]) == {"momo", "pchome", "coupang", "shopee"}
|
|
assert "execute_false_planned_only" in diff["blocked_reasons"]
|
|
assert "seed_write_still_blocked" in diff["blocked_reasons"]
|
|
|
|
|
|
def test_platform_seed_db_diff_sqlite_read_only_reports_missing_and_matching_seed_rows():
|
|
seed_plan = {
|
|
"seeds": [
|
|
{
|
|
"code": "momo",
|
|
"name": "MOMO",
|
|
"base_url": "https://momo.example",
|
|
"enabled": False,
|
|
"crawl_policy_json": {
|
|
"allow_login": False,
|
|
"allow_database_write": False,
|
|
"seed_source_keys": ["momo_edm"],
|
|
},
|
|
},
|
|
{
|
|
"code": "pchome",
|
|
"name": "PChome",
|
|
"base_url": "https://pchome.example",
|
|
"enabled": False,
|
|
"crawl_policy_json": {
|
|
"allow_login": False,
|
|
"allow_database_write": False,
|
|
"seed_source_keys": ["pchome_region"],
|
|
},
|
|
},
|
|
]
|
|
}
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE market_platforms (
|
|
code TEXT PRIMARY KEY,
|
|
name TEXT,
|
|
base_url TEXT,
|
|
enabled BOOLEAN,
|
|
crawl_policy_json TEXT
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
INSERT INTO market_platforms
|
|
(code, name, base_url, enabled, crawl_policy_json)
|
|
VALUES
|
|
(:code, :name, :base_url, :enabled, :crawl_policy_json)
|
|
"""
|
|
),
|
|
{
|
|
"code": "momo",
|
|
"name": "MOMO",
|
|
"base_url": "https://momo.example",
|
|
"enabled": False,
|
|
"crawl_policy_json": json.dumps(
|
|
seed_plan["seeds"][0]["crawl_policy_json"],
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
),
|
|
},
|
|
)
|
|
|
|
diff = build_platform_seed_db_diff_plan(
|
|
seed_plan,
|
|
execute_requested=True,
|
|
database_type="sqlite",
|
|
engine=engine,
|
|
)
|
|
|
|
assert diff["mode"] == "platform_seed_db_diff_read_only"
|
|
assert diff["execute_requested"] is True
|
|
assert diff["read_only_query_executed"] is True
|
|
assert diff["database_connection_opened"] is True
|
|
assert diff["database_session_created"] is False
|
|
assert diff["explicit_transaction_opened"] is False
|
|
assert diff["database_write_executed"] is False
|
|
assert diff["database_commit_executed"] is False
|
|
assert diff["seed_write_executed"] is False
|
|
assert diff["expected_seed_count"] == 2
|
|
assert diff["existing_seed_count"] == 1
|
|
assert diff["existing_codes"] == ["momo"]
|
|
assert diff["missing_codes"] == ["pchome"]
|
|
assert diff["changed_codes"] == []
|
|
assert diff["matching_codes"] == ["momo"]
|
|
assert diff["seed_rows_ready"] is False
|
|
assert {item["code"]: item["diff_status"] for item in diff["seed_diffs"]} == {
|
|
"momo": "matches_expected",
|
|
"pchome": "missing",
|
|
}
|
|
assert "seed_rows_missing" in diff["blocked_reasons"]
|
|
assert "seed_write_still_blocked" in diff["blocked_reasons"]
|
|
|
|
|
|
def test_deployment_readiness_reports_app_only_release_gate():
|
|
readiness = MarketIntelService().build_deployment_readiness()
|
|
|
|
step_keys = {step["key"] for step in readiness["required_manual_steps"]}
|
|
fallback_keys = {item["key"] for item in readiness["fallback_plan"]}
|
|
boundary_keys = {item["key"] for item in readiness["safe_deploy_boundaries"]}
|
|
|
|
assert readiness["mode"] == "app_only_release_gate"
|
|
assert readiness["production_deployed"] is False
|
|
assert readiness["git_committed"] is False
|
|
assert readiness["git_pushed"] is False
|
|
assert readiness["ready_for_production_deploy"] is True
|
|
assert readiness["deployment_actions_executed"] is False
|
|
assert readiness["execution_boundary"]["api_executes_scp"] is False
|
|
assert readiness["execution_boundary"]["api_recreates_container"] is False
|
|
assert readiness["execution_boundary"]["api_runs_migration"] is False
|
|
assert readiness["execution_boundary"]["api_writes_database"] is False
|
|
assert readiness["requires_backup_before_major_update"] is True
|
|
assert readiness["backup_command"] == "python backup_system.py"
|
|
assert readiness["checks"]["schema_smoke_passed"] is True
|
|
assert readiness["checks"]["schema_db_probe_planned_safe"] is True
|
|
assert readiness["checks"]["platform_seed_db_diff_planned_safe"] is True
|
|
assert readiness["checks"]["legacy_source_bridge_planned_safe"] is True
|
|
assert readiness["checks"]["mcp_readiness_planned_safe"] is True
|
|
assert readiness["checks"]["mcp_tool_contract_ready"] is True
|
|
assert readiness["checks"]["mcp_deploy_preflight_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_activation_runbook_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_fetch_gate_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_completion_audit_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_activation_evidence_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_runtime_smoke_receipt_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_runtime_promotion_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_manual_fetch_handoff_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_fetch_target_review_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_fetch_run_package_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_fetch_run_readiness_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_fetch_run_receipt_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_fetch_result_parser_review_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_fetch_candidate_handoff_review_preview_safe"] is True
|
|
assert readiness["checks"]["mcp_fetch_candidate_queue_review_preview_safe"] is True
|
|
assert readiness["checks"]["scheduler_plan_preview_safe"] is True
|
|
assert readiness["checks"]["manual_sample_plan_preview_safe"] is True
|
|
assert readiness["checks"]["manual_sample_acceptance_preview_safe"] is True
|
|
assert readiness["checks"]["manual_sample_review_preview_safe"] is True
|
|
assert readiness["checks"]["manual_sample_review_evaluation_post_safe"] is True
|
|
assert readiness["checks"]["manual_sample_candidate_handoff_post_safe"] is True
|
|
assert readiness["checks"]["manual_sample_candidate_queue_draft_post_safe"] is True
|
|
assert readiness["checks"]["manual_sample_candidate_queue_approval_post_safe"] is True
|
|
assert readiness["checks"]["manual_sample_candidate_queue_transaction_post_safe"] is True
|
|
assert readiness["checks"]["candidate_queue_writer_cli_status_safe"] is True
|
|
assert readiness["checks"]["candidate_queue_writer_preflight_planned_safe"] is True
|
|
assert (
|
|
readiness["checks"]["candidate_queue_writer_postwrite_smoke_planned_safe"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"]["candidate_queue_writer_operator_drill_preview_safe"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"]["candidate_queue_writer_run_package_preview_safe"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"]["candidate_queue_writer_run_readiness_preview_safe"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"]["candidate_queue_writer_run_receipt_preview_safe"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"]["candidate_queue_writer_run_closeout_preview_safe"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"]["candidate_queue_review_handoff_preview_safe"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"]["candidate_queue_review_inventory_preview_safe"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"]["candidate_queue_review_decision_preview_safe"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_approval_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_transaction_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_writer_preflight_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_writer_postwrite_smoke_planned_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_writer_operator_drill_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_writer_run_package_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_writer_run_readiness_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_writer_run_receipt_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_writer_run_closeout_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_post_closeout_inventory_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_completion_archive_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_archive_summary_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_preflight_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_run_package_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_output_receipt_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_preflight_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_transaction_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_writer_preflight_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_run_package_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_run_readiness_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_run_receipt_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_run_closeout_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout_preview_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["checks"][
|
|
"candidate_queue_review_decision_writer_cli_status_safe"
|
|
]
|
|
is True
|
|
)
|
|
assert readiness["checks"]["match_review_plan_preview_safe"] is True
|
|
assert readiness["checks"]["opportunity_plan_preview_safe"] is True
|
|
assert readiness["checks"]["opportunity_scoring_plan_preview_safe"] is True
|
|
assert readiness["checks"]["opportunity_evidence_plan_preview_safe"] is True
|
|
assert readiness["checks"]["opportunity_alert_plan_preview_safe"] is True
|
|
assert readiness["checks"]["migration_apply_drill_preview_safe"] is True
|
|
assert readiness["checks"]["migration_catalog_review_preview_safe"] is True
|
|
assert readiness["checks"]["migration_live_smoke_preview_safe"] is True
|
|
assert readiness["checks"]["live_db_inventory_preview_safe"] is True
|
|
assert readiness["checks"]["writer_plan_dry_run_only"] is True
|
|
assert readiness["writer_plan_summary"]["writes_executed"] is False
|
|
assert "readiness_checks_not_all_passed" not in readiness["blocked_reasons"]
|
|
assert "production_deploy_not_executed_by_api" in readiness["blocked_reasons"]
|
|
assert "backup_must_be_verified_by_operator" in readiness["blocked_reasons"]
|
|
assert "run_backup_system" in step_keys
|
|
assert "verify_health_endpoint" in step_keys
|
|
assert "feature_flag_kill_switch" in fallback_keys
|
|
assert "database_write_blocked" in fallback_keys
|
|
assert "no_remove_orphans" in boundary_keys
|
|
assert "no_momo_db_lifecycle_change" in boundary_keys
|
|
assert "/health" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/deployment_readiness" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/platform_seed_db_diff" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/legacy_source_bridge" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_readiness" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_tool_contract" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_deploy_preflight" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_activation_runbook" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_fetch_gate" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_completion_audit" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_activation_evidence" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_runtime_smoke_receipt" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_runtime_promotion" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_manual_fetch_handoff" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_fetch_target_review" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_fetch_run_package" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_fetch_run_readiness" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/mcp_fetch_run_receipt" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/scheduler_plan" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/manual_sample_plan" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/manual_sample_acceptance" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/manual_sample_review" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/match_review_plan" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/opportunity_plan" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/opportunity_scoring_plan" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/opportunity_evidence_plan" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/opportunity_alert_plan" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/migration_apply_drill" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/migration_catalog_review" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/migration_live_smoke" in readiness["production_smoke_targets"]
|
|
assert "/api/market_intel/live_db_inventory" in readiness["production_smoke_targets"]
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/candidate_queue_writer_postwrite_smoke"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/candidate_queue_writer_operator_drill"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/candidate_queue_writer_run_package"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/candidate_queue_writer_run_readiness"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/candidate_queue_writer_run_receipt"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/candidate_queue_writer_run_closeout"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/candidate_queue_review_handoff"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/candidate_queue_review_inventory"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/candidate_queue_review_decision"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_approval"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_transaction"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_preflight"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_postwrite_smoke"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_operator_drill"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_package"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_readiness"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_receipt"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_run_closeout"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_post_closeout_inventory"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_completion_archive"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_archive_summary"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_preflight"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_run_package"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_output_receipt"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_preflight"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_transaction"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_writer_preflight"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_package"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_readiness"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_receipt"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_run_closeout"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert (
|
|
"/api/market_intel/manual_sample_review/"
|
|
"candidate_queue_review_decision_writer_status"
|
|
in readiness["production_smoke_targets"]
|
|
)
|
|
assert readiness["write_approval_runbook"]["ready_for_real_write"] is False
|
|
assert readiness["write_approval_runbook"]["writes_executed"] is False
|
|
assert readiness["migration_blueprint"]["migration_executed"] is False
|
|
assert readiness["migration_blueprint"]["file_created"] is True
|
|
assert readiness["migration_blueprint"]["file_matches_blueprint"] is True
|
|
assert readiness["migration_apply_drill"]["mode"] == "migration_apply_drill_preview"
|
|
assert readiness["migration_apply_drill"]["migration_executed"] is False
|
|
assert readiness["migration_apply_drill"]["rollback_executed"] is False
|
|
assert readiness["migration_apply_drill"]["database_write_executed"] is False
|
|
assert readiness["migration_apply_drill"]["api_executes_migration"] is False
|
|
assert readiness["migration_catalog_review"]["mode"] == "migration_catalog_review_preview"
|
|
assert readiness["migration_catalog_review"]["catalog_state"] == "planned_no_probe"
|
|
assert readiness["migration_catalog_review"]["migration_executed"] is False
|
|
assert readiness["migration_catalog_review"]["database_write_executed"] is False
|
|
assert readiness["migration_catalog_review"]["api_executes_migration"] is False
|
|
assert readiness["migration_live_smoke"]["mode"] == "migration_live_smoke_preview"
|
|
assert readiness["migration_live_smoke"]["smoke_result"] == "planned_no_execution"
|
|
assert readiness["migration_live_smoke"]["migration_executed"] is False
|
|
assert readiness["migration_live_smoke"]["database_write_executed"] is False
|
|
assert readiness["migration_live_smoke"]["api_executes_migration"] is False
|
|
assert readiness["live_db_inventory"]["mode"] == "live_db_inventory_planned"
|
|
assert readiness["live_db_inventory"]["read_only_query_executed"] is False
|
|
assert readiness["live_db_inventory"]["database_write_executed"] is False
|
|
assert readiness["live_db_inventory"]["migration_executed"] is False
|
|
assert readiness["schema_db_probe"]["read_only_query_executed"] is False
|
|
assert readiness["platform_seed_db_diff"]["read_only_query_executed"] is False
|
|
assert readiness["legacy_source_bridge"]["read_only_query_executed"] is False
|
|
assert readiness["mcp_readiness"]["mode"] == "mcp_readiness_planned"
|
|
assert readiness["mcp_readiness"]["telemetry"]["read_only_query_executed"] is False
|
|
assert readiness["mcp_tool_contract"]["contract_ready"] is True
|
|
assert readiness["mcp_tool_contract"]["database_write_executed"] is False
|
|
assert readiness["mcp_deploy_preflight"]["deployment_actions_executed"] is False
|
|
assert readiness["mcp_deploy_preflight"]["docker_command_executed"] is False
|
|
assert readiness["mcp_activation_runbook"]["deployment_actions_executed"] is False
|
|
assert readiness["mcp_activation_runbook"]["docker_command_executed"] is False
|
|
assert readiness["mcp_fetch_gate"]["network_request_allowed"] is False
|
|
assert readiness["mcp_fetch_gate"]["external_network_executed"] is False
|
|
assert readiness["mcp_completion_audit"]["mode"] == "mcp_completion_audit_preview"
|
|
assert readiness["mcp_completion_audit"]["audit_preview_safe"] is True
|
|
assert readiness["mcp_completion_audit"]["api_writes_database"] is False
|
|
assert readiness["mcp_completion_audit"]["api_uses_external_network"] is False
|
|
assert readiness["mcp_completion_audit"]["ready_for_manual_fetch"] is False
|
|
assert readiness["mcp_activation_evidence"]["mode"] == "mcp_activation_evidence_preview"
|
|
assert readiness["mcp_activation_evidence"]["evidence_payload_received"] is False
|
|
assert readiness["mcp_activation_evidence"]["payload_persisted"] is False
|
|
assert readiness["mcp_activation_evidence"]["api_executes_health_check"] is False
|
|
assert readiness["mcp_activation_evidence"]["api_writes_database"] is False
|
|
assert readiness["mcp_activation_evidence"]["api_uses_external_network"] is False
|
|
assert readiness["mcp_runtime_smoke_receipt"]["mode"] == "mcp_runtime_smoke_receipt_preview"
|
|
assert readiness["mcp_runtime_smoke_receipt"]["receipt_payload_received"] is False
|
|
assert readiness["mcp_runtime_smoke_receipt"]["payload_persisted"] is False
|
|
assert readiness["mcp_runtime_smoke_receipt"]["receipt_persisted"] is False
|
|
assert readiness["mcp_runtime_smoke_receipt"]["api_executes_health_check"] is False
|
|
assert readiness["mcp_runtime_smoke_receipt"]["api_writes_database"] is False
|
|
assert readiness["mcp_runtime_smoke_receipt"]["api_uses_external_network"] is False
|
|
assert readiness["mcp_runtime_promotion"]["mode"] == "mcp_runtime_promotion_preview"
|
|
assert readiness["mcp_runtime_promotion"]["promotion_payload_received"] is False
|
|
assert readiness["mcp_runtime_promotion"]["payload_persisted"] is False
|
|
assert readiness["mcp_runtime_promotion"]["promotion_persisted"] is False
|
|
assert readiness["mcp_runtime_promotion"]["api_executes_health_check"] is False
|
|
assert readiness["mcp_runtime_promotion"]["api_writes_database"] is False
|
|
assert readiness["mcp_runtime_promotion"]["api_uses_external_network"] is False
|
|
assert readiness["mcp_manual_fetch_handoff"]["mode"] == "mcp_manual_fetch_handoff_preview"
|
|
assert readiness["mcp_manual_fetch_handoff"]["handoff_payload_received"] is False
|
|
assert readiness["mcp_manual_fetch_handoff"]["payload_persisted"] is False
|
|
assert readiness["mcp_manual_fetch_handoff"]["handoff_persisted"] is False
|
|
assert readiness["mcp_manual_fetch_handoff"]["manual_fetch_gate_opened_by_api"] is False
|
|
assert readiness["mcp_manual_fetch_handoff"]["network_request_allowed"] is False
|
|
assert readiness["mcp_manual_fetch_handoff"]["api_writes_database"] is False
|
|
assert readiness["mcp_manual_fetch_handoff"]["api_uses_external_network"] is False
|
|
assert readiness["mcp_fetch_target_review"]["mode"] == "mcp_fetch_target_review_preview"
|
|
assert readiness["mcp_fetch_target_review"]["target_payload_received"] is False
|
|
assert readiness["mcp_fetch_target_review"]["payload_persisted"] is False
|
|
assert readiness["mcp_fetch_target_review"]["target_review_persisted"] is False
|
|
assert readiness["mcp_fetch_target_review"]["manual_fetch_gate_opened_by_api"] is False
|
|
assert readiness["mcp_fetch_target_review"]["network_request_allowed"] is False
|
|
assert readiness["mcp_fetch_target_review"]["fetch_executed"] is False
|
|
assert readiness["mcp_fetch_target_review"]["api_writes_database"] is False
|
|
assert readiness["mcp_fetch_target_review"]["api_uses_external_network"] is False
|
|
assert readiness["mcp_fetch_target_review"]["scheduler_attached"] is False
|
|
assert readiness["mcp_fetch_run_package"]["mode"] == "mcp_fetch_run_package_preview"
|
|
assert readiness["mcp_fetch_run_package"]["run_payload_received"] is False
|
|
assert readiness["mcp_fetch_run_package"]["payload_persisted"] is False
|
|
assert readiness["mcp_fetch_run_package"]["run_package_persisted"] is False
|
|
assert readiness["mcp_fetch_run_package"]["command_preview_persisted"] is False
|
|
assert readiness["mcp_fetch_run_package"]["package_artifact_created"] is False
|
|
assert readiness["mcp_fetch_run_package"]["manual_fetch_gate_opened_by_api"] is False
|
|
assert readiness["mcp_fetch_run_package"]["network_request_allowed"] is False
|
|
assert readiness["mcp_fetch_run_package"]["fetch_executed"] is False
|
|
assert readiness["mcp_fetch_run_package"]["cli_executed"] is False
|
|
assert readiness["mcp_fetch_run_package"]["api_executes_cli"] is False
|
|
assert readiness["mcp_fetch_run_package"]["api_writes_database"] is False
|
|
assert readiness["mcp_fetch_run_package"]["api_uses_external_network"] is False
|
|
assert readiness["mcp_fetch_run_package"]["file_written"] is False
|
|
assert readiness["mcp_fetch_run_package"]["scheduler_attached"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["mode"] == "mcp_fetch_run_readiness_preview"
|
|
assert readiness["mcp_fetch_run_readiness"]["run_readiness_payload_received"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["payload_persisted"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["run_readiness_persisted"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["run_readiness_artifact_created"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["run_readiness_file_written"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["receipt_file_written"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["manual_fetch_gate_opened_by_api"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["network_request_allowed"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["fetch_executed"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["cli_executed"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["api_executes_cli"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["api_writes_database"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["api_uses_external_network"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["file_written"] is False
|
|
assert readiness["mcp_fetch_run_readiness"]["scheduler_attached"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["mode"] == "mcp_fetch_run_receipt_preview"
|
|
assert readiness["mcp_fetch_run_receipt"]["run_receipt_payload_received"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["payload_persisted"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["run_receipt_persisted"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["receipt_persisted"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["run_receipt_file_written"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["receipt_file_written"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["manual_fetch_gate_opened_by_api"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["network_request_allowed"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["fetch_executed"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["fetch_executed_by_api"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["cli_executed"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["api_executes_cli"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["api_writes_database"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["api_uses_external_network"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["file_written"] is False
|
|
assert readiness["mcp_fetch_run_receipt"]["scheduler_attached"] is False
|
|
assert readiness["manual_sample_plan"]["mode"] == "manual_sample_fetch_plan_preview"
|
|
assert readiness["manual_sample_plan"]["sample_fetch_executed"] is False
|
|
assert readiness["manual_sample_plan"]["external_network_executed"] is False
|
|
assert readiness["manual_sample_plan"]["database_write_executed"] is False
|
|
assert readiness["manual_sample_plan"]["scheduler_attached"] is False
|
|
assert readiness["manual_sample_acceptance"]["mode"] == "manual_sample_acceptance_preview"
|
|
assert readiness["manual_sample_acceptance"]["sample_result_loaded"] is False
|
|
assert readiness["manual_sample_acceptance"]["candidate_import_allowed"] is False
|
|
assert readiness["manual_sample_acceptance"]["external_network_executed"] is False
|
|
assert readiness["manual_sample_acceptance"]["database_write_executed"] is False
|
|
assert readiness["manual_sample_acceptance"]["scheduler_attached"] is False
|
|
assert readiness["manual_sample_review"]["mode"] == "manual_sample_review_preview"
|
|
assert readiness["manual_sample_review"]["sample_result_loaded"] is False
|
|
assert readiness["manual_sample_review"]["sample_result_reviewed"] is False
|
|
assert readiness["manual_sample_review"]["candidate_import_allowed"] is False
|
|
assert readiness["manual_sample_review"]["external_network_executed"] is False
|
|
assert readiness["manual_sample_review"]["database_write_executed"] is False
|
|
assert readiness["manual_sample_review"]["scheduler_attached"] is False
|
|
assert (
|
|
readiness["manual_sample_review_evaluation"]["mode"]
|
|
== "manual_sample_review_evaluation_preview"
|
|
)
|
|
assert readiness["manual_sample_review_evaluation"]["payload_received"] is True
|
|
assert readiness["manual_sample_review_evaluation"]["payload_persisted"] is False
|
|
assert readiness["manual_sample_review_evaluation"]["sample_result_persisted"] is False
|
|
assert (
|
|
readiness["manual_sample_review_evaluation"]["candidate_import_allowed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_review_evaluation"]["external_network_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_review_evaluation"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert readiness["manual_sample_review_evaluation"]["scheduler_attached"] is False
|
|
assert (
|
|
readiness["manual_sample_candidate_handoff"]["mode"]
|
|
== "manual_sample_candidate_handoff_preview"
|
|
)
|
|
assert readiness["manual_sample_candidate_handoff"]["payload_received"] is True
|
|
assert readiness["manual_sample_candidate_handoff"]["payload_persisted"] is False
|
|
assert (
|
|
readiness["manual_sample_candidate_handoff"]["candidate_handoff_persisted"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_handoff"]["candidate_import_allowed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_handoff"]["external_network_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_handoff"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert readiness["manual_sample_candidate_handoff"]["scheduler_attached"] is False
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_draft"]["mode"]
|
|
== "manual_sample_candidate_queue_draft_preview"
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_draft"]["payload_received"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_draft"]["payload_persisted"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_draft"]["review_queue_created"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_draft"]["review_queue_persisted"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_draft"]["candidate_import_allowed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_draft"]["external_network_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_draft"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_draft"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"]["mode"]
|
|
== "manual_sample_candidate_queue_approval_preview"
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"]["payload_received"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"]["payload_persisted"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"][
|
|
"approval_request_created"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"][
|
|
"approval_record_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"][
|
|
"review_queue_write_allowed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"]["review_queue_created"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"][
|
|
"review_queue_persisted"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"][
|
|
"candidate_import_allowed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"][
|
|
"external_network_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_approval"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"]["mode"]
|
|
== "manual_sample_candidate_queue_transaction_preview"
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"]["payload_received"]
|
|
is True
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"]["payload_persisted"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"]["transaction_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"]["transaction_opened"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"]["transaction_committed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"][
|
|
"approval_record_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"]["review_queue_created"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"][
|
|
"review_queue_persisted"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"][
|
|
"candidate_import_allowed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"][
|
|
"external_network_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["manual_sample_candidate_queue_transaction"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_cli_status"]["mode"]
|
|
== "candidate_queue_writer_cli_blocked"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_cli_status"]["ready_for_real_write"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_writer_cli_status"]["writes_executed"] is False
|
|
assert (
|
|
readiness["candidate_queue_writer_cli_status"]["would_write_database"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_cli_status"]["database_connection_opened"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_cli_status"]["explicit_transaction_opened"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_cli_status"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_cli_status"]["database_commit_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_cli_status"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_preflight"]["mode"]
|
|
== "candidate_queue_writer_preflight_planned"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_preflight"]["read_only_query_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_preflight"]["database_connection_opened"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_preflight"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_preflight"]["database_commit_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_preflight"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_postwrite_smoke"]["mode"]
|
|
== "candidate_queue_writer_postwrite_smoke_planned"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_postwrite_smoke"][
|
|
"read_only_query_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_postwrite_smoke"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_postwrite_smoke"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_postwrite_smoke"][
|
|
"database_commit_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_postwrite_smoke"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_operator_drill"]["mode"]
|
|
== "candidate_queue_writer_operator_drill_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_operator_drill"]["api_executes_cli"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_operator_drill"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_operator_drill"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_operator_drill"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_operator_drill"][
|
|
"database_commit_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_operator_drill"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_package"]["mode"]
|
|
== "candidate_queue_writer_run_package_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_package"]["package_artifact_created"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_writer_run_package"]["api_writes_file"] is False
|
|
assert (
|
|
readiness["candidate_queue_writer_run_package"]["api_executes_cli"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_package"]["api_reads_approval_token"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_package"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_package"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_package"]["database_commit_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_package"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_readiness"]["mode"]
|
|
== "candidate_queue_writer_run_readiness_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_readiness"][
|
|
"ready_for_api_database_write"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_readiness"]["api_executes_cli"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_readiness"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_writer_run_readiness"]["api_writes_file"] is False
|
|
assert (
|
|
readiness["candidate_queue_writer_run_readiness"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_readiness"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_readiness"][
|
|
"database_commit_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_readiness"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_receipt"]["mode"]
|
|
== "candidate_queue_writer_run_receipt_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_receipt"]["ready_for_api_database_write"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_receipt"]["ready_for_scheduler_attach"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_writer_run_receipt"]["api_executes_cli"] is False
|
|
assert (
|
|
readiness["candidate_queue_writer_run_receipt"]["api_reads_approval_token"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_writer_run_receipt"]["api_writes_file"] is False
|
|
assert (
|
|
readiness["candidate_queue_writer_run_receipt"]["database_connection_opened"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_receipt"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_receipt"]["database_commit_executed"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_writer_run_receipt"]["scheduler_attached"] is False
|
|
assert (
|
|
readiness["candidate_queue_writer_run_closeout"]["mode"]
|
|
== "candidate_queue_writer_run_closeout_preview"
|
|
)
|
|
assert readiness["candidate_queue_writer_run_closeout"]["closeout_passed"] is False
|
|
assert (
|
|
readiness["candidate_queue_writer_run_closeout"]["ready_for_api_database_write"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_closeout"]["ready_for_scheduler_attach"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_writer_run_closeout"]["api_executes_cli"] is False
|
|
assert (
|
|
readiness["candidate_queue_writer_run_closeout"]["api_reads_approval_token"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_writer_run_closeout"]["api_writes_file"] is False
|
|
assert (
|
|
readiness["candidate_queue_writer_run_closeout"]["database_connection_opened"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_closeout"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_writer_run_closeout"]["database_commit_executed"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_writer_run_closeout"]["scheduler_attached"] is False
|
|
assert (
|
|
readiness["candidate_queue_review_handoff"]["mode"]
|
|
== "candidate_queue_review_handoff_preview"
|
|
)
|
|
assert readiness["candidate_queue_review_handoff"]["handoff_ready"] is False
|
|
assert (
|
|
readiness["candidate_queue_review_handoff"]["ready_for_api_database_write"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_handoff"]["ready_for_scheduler_attach"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_review_handoff"]["api_executes_cli"] is False
|
|
assert (
|
|
readiness["candidate_queue_review_handoff"]["api_reads_approval_token"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_handoff"]["api_writes_database"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_handoff"]["api_updates_review_state"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_handoff"]["database_connection_opened"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_handoff"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_handoff"]["database_commit_executed"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_review_handoff"]["scheduler_attached"] is False
|
|
assert (
|
|
readiness["candidate_queue_review_inventory"]["mode"]
|
|
== "candidate_queue_review_inventory_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_inventory"]["review_inventory_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_inventory"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_inventory"][
|
|
"ready_for_api_database_write"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_inventory"]["api_updates_review_state"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_inventory"]["read_only_query_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_inventory"]["database_connection_opened"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_inventory"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_inventory"]["database_commit_executed"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_review_inventory"]["scheduler_attached"] is False
|
|
assert (
|
|
readiness["candidate_queue_review_decision"]["mode"]
|
|
== "candidate_queue_review_decision_preview"
|
|
)
|
|
assert readiness["candidate_queue_review_decision"]["decision_ready"] is False
|
|
assert (
|
|
readiness["candidate_queue_review_decision"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision"]["api_updates_review_state"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision"]["decision_record_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision"]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision"]["database_commit_executed"]
|
|
is False
|
|
)
|
|
assert readiness["candidate_queue_review_decision"]["scheduler_attached"] is False
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"]["mode"]
|
|
== "candidate_queue_review_decision_approval_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"]["approval_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"][
|
|
"ready_for_api_database_write"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"][
|
|
"approval_record_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"][
|
|
"decision_record_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"][
|
|
"database_commit_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_approval"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"]["mode"]
|
|
== "candidate_queue_review_decision_transaction_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"transaction_preview_created"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"transaction_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"approval_record_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"decision_record_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"transaction_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"transaction_committed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"database_commit_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_transaction"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"]["mode"]
|
|
== "candidate_queue_review_decision_writer_preflight_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"][
|
|
"preflight_payload_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"][
|
|
"read_only_query_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"][
|
|
"database_commit_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_preflight"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_postwrite_smoke"]["mode"]
|
|
== "candidate_queue_review_decision_writer_postwrite_smoke_planned"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
|
|
"read_only_query_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
|
|
"database_commit_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_postwrite_smoke"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_operator_drill"]["mode"]
|
|
== "candidate_queue_review_decision_writer_operator_drill_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_operator_drill"][
|
|
"api_executes_cli"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_operator_drill"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_operator_drill"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_operator_drill"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_operator_drill"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_operator_drill"][
|
|
"database_commit_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_operator_drill"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_operator_drill"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_package"]["mode"]
|
|
== "candidate_queue_review_decision_writer_run_package_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_package"][
|
|
"package_artifact_created"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_package"][
|
|
"api_writes_file"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_package"][
|
|
"api_executes_cli"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_package"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_package"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_package"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_package"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_readiness"]["mode"]
|
|
== "candidate_queue_review_decision_writer_run_readiness_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_readiness"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_readiness"][
|
|
"ready_for_api_database_write"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_readiness"][
|
|
"api_executes_cli"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_readiness"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_readiness"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_readiness"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_readiness"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_readiness"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_receipt"]["mode"]
|
|
== "candidate_queue_review_decision_writer_run_receipt_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_receipt"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_receipt"][
|
|
"ready_for_api_database_write"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_receipt"][
|
|
"api_executes_cli"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_receipt"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_receipt"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_receipt"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_receipt"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_receipt"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"]["mode"]
|
|
== "candidate_queue_review_decision_writer_run_closeout_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"][
|
|
"closeout_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"][
|
|
"ready_for_api_database_write"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"][
|
|
"api_executes_cli"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_run_closeout"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"mode"
|
|
]
|
|
== "candidate_queue_review_decision_post_closeout_inventory_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"post_closeout_inventory_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"ready_for_api_database_write"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"api_executes_cli"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"read_only_query_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_post_closeout_inventory"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"]["mode"]
|
|
== "candidate_queue_review_completion_archive_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"review_completion_archive_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"archive_manifest_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"ready_for_api_review_state_update"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"ready_for_api_database_write"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"]["api_executes_cli"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"archive_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"archive_record_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"read_only_query_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_completion_archive"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"]["mode"]
|
|
== "candidate_queue_review_archive_summary_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"archive_summary_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"summary_input_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"ready_for_ai_summary_generation"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"]["ready_for_llm_call"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"ready_for_telegram_dispatch"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"summary_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"ai_summary_generated"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"]["llm_call_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_archive_summary"]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"]["mode"]
|
|
== "candidate_queue_review_ai_summary_preflight_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"ai_summary_preflight_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"ready_for_manual_ollama_summary_run"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"ready_for_ai_summary_generation"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"ready_for_llm_call"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"ready_for_telegram_dispatch"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"api_reads_approval_token"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"api_writes_file"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"summary_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"summary_record_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"ai_summary_generated"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"llm_call_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"ollama_call_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"gemini_call_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_preflight"][
|
|
"model_route_policy"
|
|
]["primary_policy"]
|
|
== "ollama_first"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"]["mode"]
|
|
== "candidate_queue_review_ai_summary_run_package_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"ai_summary_run_package_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"ready_for_manual_ollama_summary_run"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"ready_for_ai_summary_generation"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"ready_for_llm_call"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"ready_for_telegram_dispatch"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"api_executes_llm"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"run_package_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"summary_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"ai_summary_generated"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"llm_call_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"ollama_call_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"gemini_call_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_run_package"][
|
|
"summary_output_schema"
|
|
]["schema_version"]
|
|
== "market_intel_ai_summary_v1"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"]["mode"]
|
|
== "candidate_queue_review_ai_summary_output_receipt_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"ai_summary_output_receipt_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"ready_for_summary_persistence_review"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"manual_ai_summary_output_provided"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"summary_output_schema_valid"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"summary_output_evidence_refs_grounded"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"summary_output_model_route_accepted"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"api_executes_llm"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"summary_receipt_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"summary_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"ai_summary_generated"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"llm_call_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_output_receipt"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_preflight_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"summary_persistence_preflight_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"ready_for_summary_transaction_preview"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"ready_for_summary_persistence_cli_run"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"api_executes_llm"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"summary_persistence_preflight_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"summary_persistence_record_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"metadata_patch_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_preflight"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"mode"
|
|
]
|
|
== "candidate_queue_review_ai_summary_persistence_transaction_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"summary_persistence_transaction_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"ready_for_summary_persistence_writer_gate"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"ready_for_summary_persistence_cli_run"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"statement_count"
|
|
]
|
|
== 0
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"api_executes_llm"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"summary_persistence_transaction_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"metadata_patch_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_transaction"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"mode"
|
|
]
|
|
== "candidate_queue_review_ai_summary_persistence_writer_preflight_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"summary_persistence_writer_preflight_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"ready_for_summary_persistence_run_package"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"ready_for_summary_persistence_cli_run"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"statement_count"
|
|
]
|
|
== 0
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"api_executes_llm"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"summary_persistence_writer_preflight_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"writer_preflight_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"metadata_patch_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_writer_preflight"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"mode"
|
|
]
|
|
== "candidate_queue_review_ai_summary_persistence_run_package_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"package_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"ready_for_summary_persistence_run_readiness"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"ready_for_summary_persistence_cli_run"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"statement_count"
|
|
]
|
|
== 0
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"payload_manifest"
|
|
]["payload_count"]
|
|
== 0
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"api_executes_llm"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"package_artifact_created"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"summary_persistence_run_package_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_package"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"mode"
|
|
]
|
|
== "candidate_queue_review_ai_summary_persistence_run_readiness_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"run_readiness_ready"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"ready_for_summary_persistence_cli_run"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"statement_count"
|
|
]
|
|
== 0
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"run_package_summary"
|
|
]["payload_count"]
|
|
== 0
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"summary_persistence_run_readiness_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"run_readiness_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"api_executes_llm"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_readiness"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"mode"
|
|
]
|
|
== "candidate_queue_review_ai_summary_persistence_run_receipt_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"run_receipt_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"ready_for_summary_persistence_closeout"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"statement_count"
|
|
]
|
|
== 0
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"expected_dedupe_keys"
|
|
]
|
|
== []
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"summary_persistence_run_receipt_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"run_receipt_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"api_executes_llm"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_receipt"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"mode"
|
|
]
|
|
== "candidate_queue_review_ai_summary_persistence_run_closeout_preview"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"closeout_passed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"ready_for_summary_persistence_telegram_dispatch_gate"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"statement_count"
|
|
]
|
|
== 0
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"summary_persistence_closeout_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"closeout_file_written"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"api_executes_llm"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"telegram_dispatched"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"database_connection_opened"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_ai_summary_persistence_run_closeout"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
]["telegram_dispatch_gate_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
]["ready_for_summary_persistence_telegram_dispatch_run_package"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
]["telegram_dispatch_gate_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_gate"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
]["telegram_dispatch_run_package_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
]["ready_for_summary_persistence_telegram_dispatch_run_readiness"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
]["telegram_dispatch_run_package_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_package"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
]["telegram_dispatch_run_readiness_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
]["ready_for_manual_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
]["telegram_dispatch_run_readiness_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_readiness"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
]["telegram_dispatch_run_receipt_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
]["ready_for_summary_persistence_telegram_dispatch_closeout"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
]["telegram_dispatch_run_receipt_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_run_receipt"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
]["telegram_dispatch_closeout_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
]["telegram_dispatch_closeout_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_closeout"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
]["telegram_dispatch_archive_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
]["telegram_dispatch_archive_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
]["archive_manifest_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
]["telegram_dispatch_archive_summary_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
]["telegram_dispatch_archive_summary_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
]["archive_summary_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_archive_summary"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["telegram_dispatch_report_input_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["ready_for_report_generation"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["telegram_dispatch_report_input_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["report_input_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["report_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_input"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["telegram_dispatch_report_run_package_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["ready_for_report_generation"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["telegram_dispatch_report_run_package_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["report_run_package_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["report_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_package"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["telegram_dispatch_report_run_readiness_ready"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["ready_for_manual_report_generation"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["ready_for_report_generation"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["telegram_dispatch_report_run_readiness_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["report_run_readiness_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["report_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_readiness"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["telegram_dispatch_report_run_receipt_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["ready_for_report_generation"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["telegram_dispatch_report_run_receipt_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["report_run_receipt_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["report_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_run_receipt"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["telegram_dispatch_report_closeout_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["ready_for_market_intel_report_archive"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["ready_for_report_generation"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["telegram_dispatch_report_closeout_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["report_closeout_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["report_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_closeout"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["telegram_dispatch_report_archive_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["ready_for_market_intel_report_archive_summary"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["ready_for_report_generation"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["ready_for_telegram_dispatch"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["api_dispatches_telegram"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["telegram_dispatch_report_archive_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["report_archive_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["archive_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["report_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["telegram_dispatched"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
]["telegram_dispatch_report_archive_summary_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
]["ready_for_market_intel_report_catalog_handoff"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
]["report_archive_summary_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_archive_summary"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
]["telegram_dispatch_report_catalog_handoff_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
]["ready_for_market_intel_report_catalog_index"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
]["report_catalog_handoff_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
]["catalog_record_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_handoff"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
]["telegram_dispatch_report_catalog_index_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
]["ready_for_market_intel_report_catalog_write_preflight"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
]["report_catalog_index_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
]["catalog_record_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_index"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
]["telegram_dispatch_report_catalog_write_preflight_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
]["ready_for_market_intel_report_catalog_record_write"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
]["report_catalog_write_preflight_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
]["catalog_record_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_write_preflight"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
]["telegram_dispatch_report_catalog_record_write_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
]["ready_for_market_intel_report_catalog_record_cli_run"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
]["catalog_record_write_gate_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
]["catalog_record_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_write"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
]["telegram_dispatch_report_catalog_record_run_package_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
]["ready_for_market_intel_report_catalog_record_run_readiness"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
]["catalog_record_run_package_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
]["catalog_record_cli_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_package"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
]["telegram_dispatch_report_catalog_record_run_readiness_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
]["ready_for_cli_operator_run"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
]["catalog_record_run_readiness_gate_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
]["catalog_record_run_readiness_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
]["catalog_record_cli_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_readiness"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
]["telegram_dispatch_report_catalog_record_run_receipt_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
]["ready_for_market_intel_report_catalog_record_commit"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
]["catalog_record_run_receipt_gate_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
]["catalog_record_run_receipt_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
]["catalog_record_commit_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_run_receipt"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
]["telegram_dispatch_report_catalog_record_commit_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
]["ready_for_market_intel_report_catalog_record_closeout"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
]["catalog_record_commit_gate_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
]["catalog_record_commit_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_commit"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
]["telegram_dispatch_report_catalog_record_closeout_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
]["ready_for_market_intel_report_catalog_record_archive"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
]["catalog_record_closeout_gate_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
]["catalog_record_closeout_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_closeout"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
]["telegram_dispatch_report_catalog_record_archive_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
]["ready_for_market_intel_report_catalog_record_archive_summary"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
]["catalog_record_archive_gate_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
]["catalog_record_archive_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
]["telegram_dispatch_report_catalog_record_archive_summary_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
]["ready_for_market_intel_report_catalog_record_final_closeout"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
]["catalog_record_archive_summary_gate_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
]["catalog_record_archive_summary_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_archive_summary"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
]["mode"]
|
|
== "candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout_preview"
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
]["telegram_dispatch_report_catalog_record_final_closeout_passed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
]["market_intel_report_catalog_record_pipeline_complete"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
]["catalog_record_final_closeout_gate_file_written"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
]["catalog_record_final_closeout_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
]["database_write_executed"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness[
|
|
"candidate_queue_review_ai_summary_persistence_telegram_dispatch_report_catalog_record_final_closeout"
|
|
]["scheduler_attached"]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_status"]["mode"]
|
|
== "candidate_queue_review_decision_writer_cli_blocked"
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_status"][
|
|
"ready_for_real_write"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_status"][
|
|
"writer_implementation_enabled"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_status"][
|
|
"api_updates_review_state"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_status"][
|
|
"review_state_update_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_status"][
|
|
"database_write_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_status"][
|
|
"database_commit_executed"
|
|
]
|
|
is False
|
|
)
|
|
assert (
|
|
readiness["candidate_queue_review_decision_writer_status"][
|
|
"scheduler_attached"
|
|
]
|
|
is False
|
|
)
|
|
assert readiness["scheduler_plan"]["scheduler_registration_executed"] is False
|
|
assert readiness["scheduler_plan"]["crawler_job_started"] is False
|
|
assert readiness["scheduler_plan"]["database_write_executed"] is False
|
|
assert readiness["match_review_plan"]["review_queue_created"] is False
|
|
assert readiness["match_review_plan"]["auto_confirm_executed"] is False
|
|
assert readiness["match_review_plan"]["database_write_executed"] is False
|
|
assert readiness["opportunity_plan"]["opportunity_queue_created"] is False
|
|
assert readiness["opportunity_plan"]["threat_alert_dispatched"] is False
|
|
assert readiness["opportunity_plan"]["database_write_executed"] is False
|
|
assert readiness["opportunity_scoring_plan"]["scoring_job_created"] is False
|
|
assert readiness["opportunity_scoring_plan"]["score_calculation_executed"] is False
|
|
assert readiness["opportunity_scoring_plan"]["database_write_executed"] is False
|
|
assert readiness["opportunity_evidence_plan"]["evidence_bundle_created"] is False
|
|
assert readiness["opportunity_evidence_plan"]["evidence_query_executed"] is False
|
|
assert readiness["opportunity_evidence_plan"]["database_write_executed"] is False
|
|
assert readiness["opportunity_alert_plan"]["alert_candidate_created"] is False
|
|
assert readiness["opportunity_alert_plan"]["review_queue_contract_written"] is False
|
|
assert readiness["opportunity_alert_plan"]["review_queue_table_created"] is False
|
|
assert readiness["opportunity_alert_plan"]["review_action_executed"] is False
|
|
assert readiness["opportunity_alert_plan"]["approval_record_written"] is False
|
|
assert readiness["opportunity_alert_plan"]["telegram_dispatched"] is False
|
|
assert readiness["opportunity_alert_plan"]["llm_call_executed"] is False
|
|
assert readiness["opportunity_alert_plan"]["database_write_executed"] is False
|
|
|
|
|
|
def test_market_intel_service_keeps_readiness_modularized():
|
|
service_path = Path("services/market_intel/service.py")
|
|
readiness_path = Path("services/market_intel/deployment_readiness.py")
|
|
|
|
assert service_path.exists()
|
|
assert readiness_path.exists()
|
|
assert len(service_path.read_text().splitlines()) < 800
|
|
assert "build_deployment_readiness_preview" in readiness_path.read_text()
|
|
|
|
|
|
def test_write_approval_runbook_is_read_only_and_blocks_real_write():
|
|
runbook = MarketIntelService().build_write_approval_runbook()
|
|
gate_keys = {gate["key"] for gate in runbook["approval_gates"]}
|
|
|
|
assert runbook["mode"] == "approval_runbook_read_only"
|
|
assert runbook["ready_for_real_write"] is False
|
|
assert runbook["writes_executed"] is False
|
|
assert runbook["would_write_database"] is False
|
|
assert runbook["database_session_created"] is False
|
|
assert runbook["database_commit_executed"] is False
|
|
assert runbook["external_network_executed"] is False
|
|
assert runbook["scheduler_attached"] is False
|
|
assert runbook["approval_required"] is True
|
|
assert runbook["approval_token_present"] is False
|
|
assert runbook["seed_count"] == 4
|
|
assert runbook["writer_operation_count"] == 4
|
|
assert runbook["schema_smoke"]["passed"] is True
|
|
assert "schema_smoke_passed" in gate_keys
|
|
assert "backup_completed" in gate_keys
|
|
assert "migration_file_reviewed" in gate_keys
|
|
assert "manual_operator_approval" in gate_keys
|
|
assert "database_write_allowed" in runbook["blocked_reasons"]
|
|
assert "manual_operator_approval" in runbook["blocked_reasons"]
|
|
assert "no_momo_db_container_lifecycle_change" in runbook["hard_safety_boundaries"]
|
|
assert "no_remove_orphans" in runbook["hard_safety_boundaries"]
|
|
|
|
|
|
def test_migration_blueprint_is_additive_preview_only():
|
|
blueprint = MarketIntelService().build_migration_blueprint()
|
|
forward_sql_lower = blueprint["forward_sql"].lower()
|
|
migration_file = Path(blueprint["suggested_filename"])
|
|
|
|
assert blueprint["mode"] == "migration_file_draft_read_only"
|
|
assert blueprint["suggested_filename"] == "migrations/032_market_intel_core_schema.sql"
|
|
assert blueprint["file_created"] is True
|
|
assert blueprint["file_matches_blueprint"] is True
|
|
assert blueprint["file_status"] == "local_draft_matches_blueprint"
|
|
assert blueprint["migration_executed"] is False
|
|
assert blueprint["database_session_created"] is False
|
|
assert blueprint["database_commit_executed"] is False
|
|
assert blueprint["external_network_executed"] is False
|
|
assert blueprint["scheduler_attached"] is False
|
|
assert blueprint["table_count"] == 8
|
|
assert blueprint["forward_has_destructive_sql"] is False
|
|
assert blueprint["safety_checks"]["forward_sql_additive_only"] is True
|
|
assert blueprint["safety_checks"]["writes_seed_rows_only_with_cli_apply_flag"] is True
|
|
assert "migration_not_executed" in blueprint["blocked_reasons"]
|
|
assert "migration_file_not_created" not in blueprint["blocked_reasons"]
|
|
assert "seed_writer_real_write_requires_cli_apply_flag" in blueprint["blocked_reasons"]
|
|
assert migration_file.exists()
|
|
assert migration_file.read_text(encoding="utf-8").strip() == blueprint["forward_sql"]
|
|
assert "CREATE TABLE IF NOT EXISTS market_platforms".lower() in forward_sql_lower
|
|
assert "CREATE TABLE IF NOT EXISTS market_crawler_runs".lower() in forward_sql_lower
|
|
assert "CREATE TABLE IF NOT EXISTS market_alert_review_queue".lower() in forward_sql_lower
|
|
assert "ux_market_alert_review_queue_dedupe".lower() in forward_sql_lower
|
|
assert "drop table" not in forward_sql_lower
|
|
assert "truncate " not in forward_sql_lower
|
|
assert "delete from" not in forward_sql_lower
|
|
assert "MARKET_INTEL_CRAWLER_ENABLED=false" in blueprint["command_plan"]["seed_writer_command"]["command"]
|
|
assert blueprint["command_plan"]["seed_writer_command"]["script_created"] is True
|
|
assert blueprint["command_plan"]["seed_writer_command"]["script_path"] == "scripts/market_intel_seed_writer.py"
|
|
assert blueprint["rollback_requires_manual_approval"] is True
|
|
assert "DROP TABLE IF EXISTS market_alert_review_queue" in blueprint["rollback_sql"]
|
|
|
|
|
|
def test_migration_apply_drill_planned_is_safe_and_manual_only():
|
|
drill = MarketIntelService().build_migration_apply_drill()
|
|
|
|
assert drill["mode"] == "migration_apply_drill_preview"
|
|
assert drill["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert drill["execute_requested"] is False
|
|
assert drill["schema_state"] == "planned_no_db_probe"
|
|
assert drill["drill_ready_for_operator_review"] is True
|
|
assert drill["ready_for_manual_apply_review"] is False
|
|
assert drill["ready_to_apply_migration"] is False
|
|
assert drill["read_only_query_executed"] is False
|
|
assert drill["database_connection_opened"] is False
|
|
assert drill["database_session_created"] is False
|
|
assert drill["database_write_executed"] is False
|
|
assert drill["database_commit_executed"] is False
|
|
assert drill["migration_executed"] is False
|
|
assert drill["rollback_executed"] is False
|
|
assert drill["api_executes_migration"] is False
|
|
assert drill["api_executes_rollback"] is False
|
|
assert drill["checks"]["migration_file_matches_blueprint"] is True
|
|
assert drill["checks"]["forward_sql_additive_only"] is True
|
|
assert "read_only_db_probe_not_executed" in drill["blocked_reasons"]
|
|
assert "api_never_runs_migration" in drill["blocked_reasons"]
|
|
assert drill["rollback_drill"]["rollback_executed"] is False
|
|
assert drill["rollback_drill"]["requires_manual_approval"] is True
|
|
assert "market_alert_review_queue" in drill["rollback_drill"]["rollback_table_order"]
|
|
assert len(drill["pre_apply_checklist"]) >= 6
|
|
assert len(drill["post_apply_verification"]) >= 4
|
|
assert len(drill["risk_register"]) >= 4
|
|
|
|
|
|
def test_migration_apply_drill_sqlite_read_only_reports_already_applied():
|
|
service = MarketIntelService()
|
|
seed_rows = service.build_platform_seed_plan()["seeds"]
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE market_platforms (
|
|
code TEXT PRIMARY KEY,
|
|
name TEXT,
|
|
base_url TEXT,
|
|
enabled BOOLEAN,
|
|
crawl_policy_json TEXT
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
for table_name in MARKET_INTEL_TABLES:
|
|
if table_name == "market_platforms":
|
|
continue
|
|
conn.execute(text(f"CREATE TABLE {table_name} (id INTEGER PRIMARY KEY)"))
|
|
for seed in seed_rows:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
INSERT INTO market_platforms
|
|
(code, name, base_url, enabled, crawl_policy_json)
|
|
VALUES
|
|
(:code, :name, :base_url, :enabled, :crawl_policy_json)
|
|
"""
|
|
),
|
|
{
|
|
"code": seed["code"],
|
|
"name": seed["name"],
|
|
"base_url": seed["base_url"],
|
|
"enabled": seed["enabled"],
|
|
"crawl_policy_json": json.dumps(
|
|
seed["crawl_policy_json"],
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
),
|
|
},
|
|
)
|
|
|
|
drill = service.build_migration_apply_drill(
|
|
execute_requested=True,
|
|
schema_engine=engine,
|
|
seed_diff_engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
|
|
assert drill["mode"] == "migration_apply_drill_preview"
|
|
assert drill["execute_requested"] is True
|
|
assert drill["read_only_query_executed"] is True
|
|
assert drill["database_connection_opened"] is True
|
|
assert drill["schema_state"] == "already_applied"
|
|
assert drill["schema_db_probe_summary"]["schema_tables_exist"] is True
|
|
assert drill["schema_db_probe_summary"]["missing_tables"] == []
|
|
assert drill["platform_seed_db_diff_summary"]["seed_rows_ready"] is True
|
|
assert set(drill["platform_seed_db_diff_summary"]["matching_codes"]) == {
|
|
"momo",
|
|
"pchome",
|
|
"coupang",
|
|
"shopee",
|
|
}
|
|
assert drill["database_session_created"] is False
|
|
assert drill["database_write_executed"] is False
|
|
assert drill["database_commit_executed"] is False
|
|
assert drill["migration_executed"] is False
|
|
assert "market_schema_already_present_apply_not_required" in drill["blocked_reasons"]
|
|
|
|
|
|
def test_migration_apply_drill_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/migration_apply_drill?execute=false")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "migration_apply_drill_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["migration_executed"] is False
|
|
assert data["rollback_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["api_executes_migration"] is False
|
|
|
|
|
|
def test_migration_catalog_review_planned_is_safe_and_diagnostic():
|
|
review = MarketIntelService().build_migration_catalog_review()
|
|
|
|
assert review["mode"] == "migration_catalog_review_preview"
|
|
assert review["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert review["execute_requested"] is False
|
|
assert review["catalog_state"] == "planned_no_probe"
|
|
assert review["seed_state"] == "planned_no_probe"
|
|
assert review["risk_level"] == "info"
|
|
assert review["apply_path"] == "run_execute_true_read_only_probe_first"
|
|
assert review["review_ready"] is True
|
|
assert review["ready_for_manual_migration_review"] is False
|
|
assert review["ready_to_apply_migration"] is False
|
|
assert review["read_only_query_executed"] is False
|
|
assert review["database_connection_opened"] is False
|
|
assert review["database_session_created"] is False
|
|
assert review["database_write_executed"] is False
|
|
assert review["database_commit_executed"] is False
|
|
assert review["migration_executed"] is False
|
|
assert review["rollback_executed"] is False
|
|
assert review["api_executes_migration"] is False
|
|
assert review["table_catalog"]["expected_count"] == 8
|
|
assert review["table_catalog"]["existing_count"] == 0
|
|
assert review["table_catalog"]["missing_count"] == 8
|
|
assert "execute_false_planned_only" in review["blocked_reasons"]
|
|
assert "migration_not_executed_by_catalog_review" in review["blocked_reasons"]
|
|
assert {item["key"] for item in review["findings"]} >= {
|
|
"catalog_probe_not_executed",
|
|
"seed_diff_not_executed",
|
|
}
|
|
|
|
|
|
def test_migration_catalog_review_sqlite_read_only_detects_partial_schema():
|
|
service = MarketIntelService()
|
|
seed_rows = service.build_platform_seed_plan()["seeds"]
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE market_platforms (
|
|
code TEXT PRIMARY KEY,
|
|
name TEXT,
|
|
base_url TEXT,
|
|
enabled BOOLEAN,
|
|
crawl_policy_json TEXT
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
for seed in seed_rows:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
INSERT INTO market_platforms
|
|
(code, name, base_url, enabled, crawl_policy_json)
|
|
VALUES
|
|
(:code, :name, :base_url, :enabled, :crawl_policy_json)
|
|
"""
|
|
),
|
|
{
|
|
"code": seed["code"],
|
|
"name": seed["name"],
|
|
"base_url": seed["base_url"],
|
|
"enabled": seed["enabled"],
|
|
"crawl_policy_json": json.dumps(
|
|
seed["crawl_policy_json"],
|
|
ensure_ascii=False,
|
|
sort_keys=True,
|
|
),
|
|
},
|
|
)
|
|
|
|
review = service.build_migration_catalog_review(
|
|
execute_requested=True,
|
|
schema_engine=engine,
|
|
seed_diff_engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
|
|
assert review["mode"] == "migration_catalog_review_preview"
|
|
assert review["execute_requested"] is True
|
|
assert review["read_only_query_executed"] is True
|
|
assert review["database_connection_opened"] is True
|
|
assert review["catalog_state"] == "partial_schema"
|
|
assert review["seed_state"] == "ready"
|
|
assert review["risk_level"] == "high"
|
|
assert review["apply_path"] == "blocked_until_partial_schema_reviewed"
|
|
assert review["ready_for_manual_migration_review"] is False
|
|
assert review["table_catalog"]["expected_count"] == 8
|
|
assert review["table_catalog"]["existing_count"] == 1
|
|
assert review["table_catalog"]["missing_count"] == 7
|
|
assert review["seed_catalog"]["seed_rows_ready"] is True
|
|
assert "partial_schema_requires_manual_reconciliation" in review["blocked_reasons"]
|
|
assert review["database_session_created"] is False
|
|
assert review["database_write_executed"] is False
|
|
assert review["database_commit_executed"] is False
|
|
assert review["migration_executed"] is False
|
|
assert {item["key"] for item in review["findings"]} >= {
|
|
"partial_market_schema_detected",
|
|
"platform_seed_ready",
|
|
}
|
|
|
|
|
|
def test_migration_catalog_review_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/migration_catalog_review?execute=false")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "migration_catalog_review_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["catalog_state"] == "planned_no_probe"
|
|
assert data["migration_executed"] is False
|
|
assert data["rollback_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["api_executes_migration"] is False
|
|
|
|
|
|
def test_migration_live_smoke_planned_is_preview_only():
|
|
smoke = MarketIntelService().build_migration_live_smoke()
|
|
|
|
assert smoke["mode"] == "migration_live_smoke_preview"
|
|
assert smoke["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert smoke["execute_requested"] is False
|
|
assert smoke["smoke_result"] == "planned_no_execution"
|
|
assert smoke["live_smoke_passed"] is False
|
|
assert smoke["catalog_state"] == "planned_no_probe"
|
|
assert smoke["seed_state"] == "planned_no_probe"
|
|
assert smoke["read_only_probe_completed"] is False
|
|
assert smoke["database_connection_opened"] is False
|
|
assert smoke["database_session_created"] is False
|
|
assert smoke["database_write_executed"] is False
|
|
assert smoke["database_commit_executed"] is False
|
|
assert smoke["migration_executed"] is False
|
|
assert smoke["rollback_executed"] is False
|
|
assert smoke["api_executes_migration"] is False
|
|
assert "execute_false_planned_only" in smoke["blocked_reasons"]
|
|
assert "migration_not_executed_by_live_smoke" in smoke["blocked_reasons"]
|
|
|
|
|
|
def test_migration_live_smoke_sqlite_not_applied_tolerates_seed_table_missing():
|
|
service = MarketIntelService()
|
|
engine = create_engine("sqlite:///:memory:")
|
|
|
|
smoke = service.build_migration_live_smoke(
|
|
execute_requested=True,
|
|
schema_engine=engine,
|
|
seed_diff_engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
|
|
assert smoke["mode"] == "migration_live_smoke_preview"
|
|
assert smoke["execute_requested"] is True
|
|
assert smoke["read_only_query_executed"] is True
|
|
assert smoke["database_connection_opened"] is True
|
|
assert smoke["catalog_state"] == "not_applied"
|
|
assert smoke["seed_state"] == "probe_error"
|
|
assert smoke["seed_probe_error_tolerated"] is True
|
|
assert smoke["smoke_result"] == "passed_not_applied_seed_table_missing"
|
|
assert smoke["live_smoke_passed"] is True
|
|
assert smoke["read_only_probe_completed"] is True
|
|
assert smoke["ready_for_manual_migration_review"] is True
|
|
assert smoke["database_session_created"] is False
|
|
assert smoke["database_write_executed"] is False
|
|
assert smoke["database_commit_executed"] is False
|
|
assert smoke["migration_executed"] is False
|
|
assert smoke["catalog_review_summary"]["table_catalog"]["missing_count"] == 8
|
|
|
|
|
|
def test_migration_live_smoke_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/migration_live_smoke?execute=false")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "migration_live_smoke_preview"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["smoke_result"] == "planned_no_execution"
|
|
assert data["migration_executed"] is False
|
|
assert data["rollback_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["api_executes_migration"] is False
|
|
|
|
|
|
def test_live_db_inventory_planned_is_preview_only():
|
|
inventory = MarketIntelService().build_live_db_inventory()
|
|
|
|
assert inventory["mode"] == "live_db_inventory_planned"
|
|
assert inventory["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert inventory["execute_requested"] is False
|
|
assert inventory["read_only_query_executed"] is False
|
|
assert inventory["database_connection_opened"] is False
|
|
assert inventory["database_session_created"] is False
|
|
assert inventory["database_write_executed"] is False
|
|
assert inventory["database_commit_executed"] is False
|
|
assert inventory["migration_executed"] is False
|
|
assert inventory["external_network_executed"] is False
|
|
assert inventory["scheduler_attached"] is False
|
|
assert inventory["summary_ready"] is False
|
|
assert inventory["total_rows"] == 0
|
|
assert "execute_false_planned_only" in inventory["blocked_reasons"]
|
|
assert "inventory_not_loaded" in inventory["blocked_reasons"]
|
|
|
|
|
|
def test_live_db_inventory_sqlite_read_only_counts_market_tables():
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(text("CREATE TABLE market_platforms (code TEXT, name TEXT, enabled BOOLEAN)"))
|
|
conn.execute(text("CREATE TABLE market_campaigns (platform_code TEXT, status TEXT)"))
|
|
conn.execute(text("CREATE TABLE market_campaign_snapshots (status TEXT)"))
|
|
conn.execute(
|
|
text(
|
|
"CREATE TABLE market_campaign_products "
|
|
"(platform_code TEXT, is_active BOOLEAN, last_seen_at TEXT, discount_rate FLOAT)"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"CREATE TABLE market_product_price_history "
|
|
"(platform_code TEXT, crawled_at TEXT, price FLOAT)"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"CREATE TABLE market_product_matches "
|
|
"(match_status TEXT, match_score FLOAT, reviewed_at TEXT)"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"CREATE TABLE market_crawler_runs "
|
|
"(platform_code TEXT, status TEXT, dry_run BOOLEAN, started_at TEXT, finished_at TEXT, error_count INTEGER)"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"CREATE TABLE market_alert_review_queue "
|
|
"(review_state TEXT, priority_lane TEXT, total_score FLOAT, updated_at TEXT)"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO market_platforms (code, name, enabled) "
|
|
"VALUES ('momo', 'MOMO', 0), ('pchome', 'PChome', 0)"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO market_campaigns (platform_code, status) "
|
|
"VALUES ('momo', 'active'), ('pchome', 'unknown')"
|
|
)
|
|
)
|
|
conn.execute(text("INSERT INTO market_campaign_snapshots (status) VALUES ('success')"))
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO market_campaign_products "
|
|
"(platform_code, is_active, last_seen_at, discount_rate) "
|
|
"VALUES ('momo', 1, '2026-05-18 09:00:00', 0.2), "
|
|
"('pchome', 0, '2026-05-18 08:00:00', 0.1)"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO market_product_price_history (platform_code, crawled_at, price) "
|
|
"VALUES ('momo', '2026-05-18 09:00:00', 199)"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO market_product_matches (match_status, match_score, reviewed_at) "
|
|
"VALUES ('needs_review', 0.72, NULL), ('confirmed', 0.91, '2026-05-18 10:00:00')"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO market_crawler_runs "
|
|
"(platform_code, status, dry_run, started_at, finished_at, error_count) "
|
|
"VALUES ('momo', 'success', 1, '2026-05-18 09:00:00', '2026-05-18 09:01:00', 0)"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO market_alert_review_queue "
|
|
"(review_state, priority_lane, total_score, updated_at) "
|
|
"VALUES ('draft', 'watch', 0.61, '2026-05-18 11:00:00')"
|
|
)
|
|
)
|
|
|
|
inventory = build_live_db_inventory_preview(
|
|
MARKET_INTEL_TABLES,
|
|
execute_requested=True,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
|
|
assert inventory["mode"] == "live_db_inventory_read_only"
|
|
assert inventory["execute_requested"] is True
|
|
assert inventory["read_only_query_executed"] is True
|
|
assert inventory["database_connection_opened"] is True
|
|
assert inventory["database_session_created"] is False
|
|
assert inventory["database_write_executed"] is False
|
|
assert inventory["database_commit_executed"] is False
|
|
assert inventory["migration_executed"] is False
|
|
assert inventory["external_network_executed"] is False
|
|
assert inventory["scheduler_attached"] is False
|
|
assert inventory["missing_tables"] == []
|
|
assert inventory["summary_ready"] is True
|
|
assert inventory["table_counts"]["market_platforms"] == 2
|
|
assert inventory["table_counts"]["market_campaign_products"] == 2
|
|
assert inventory["total_rows"] == 12
|
|
assert {item["code"] for item in inventory["platform_breakdown"]} == {"momo", "pchome"}
|
|
assert {item["status"] for item in inventory["campaign_status_breakdown"]} == {"active", "unknown"}
|
|
assert {item["match_status"] for item in inventory["match_status_breakdown"]} == {"confirmed", "needs_review"}
|
|
assert inventory["alert_review_state_breakdown"][0]["review_state"] == "draft"
|
|
assert inventory["crawler_run_summary"][0]["status"] == "success"
|
|
|
|
|
|
def test_live_db_inventory_route_is_preview_only():
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/live_db_inventory?execute=false")
|
|
data = response.get_json()
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "live_db_inventory_planned"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["read_only_query_executed"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["migration_executed"] is False
|
|
|
|
|
|
def test_seed_writer_cli_status_blocks_real_write():
|
|
status = MarketIntelService().build_seed_writer_cli_status(
|
|
platform_code="all",
|
|
execute_requested=True,
|
|
approval_token=TEST_APPROVAL_TOKEN,
|
|
approval_token_secret=TEST_APPROVAL_TOKEN,
|
|
)
|
|
|
|
assert status["mode"] == "seed_writer_cli_blocked"
|
|
assert status["execute_requested"] is True
|
|
assert status["apply_real_write_requested"] is False
|
|
assert status["approval_token_present"] is True
|
|
assert status["approval_token_valid"] is True
|
|
assert status["approval_token_secret_configured"] is True
|
|
assert "approval_token_hint" not in status
|
|
assert status["api_reads_approval_token"] is False
|
|
assert status["api_executes_cli"] is False
|
|
assert status["api_writes_database"] is False
|
|
assert status["ready_for_real_write"] is False
|
|
assert status["writes_executed"] is False
|
|
assert status["would_write_database"] is False
|
|
assert status["database_session_created"] is False
|
|
assert status["explicit_transaction_opened"] is False
|
|
assert status["database_write_executed"] is False
|
|
assert status["database_commit_executed"] is False
|
|
assert status["external_network_executed"] is False
|
|
assert status["scheduler_attached"] is False
|
|
assert status["exit_code"] == 2
|
|
assert "apply_real_write_requested" in status["blocked_reasons"]
|
|
assert "approval_token_valid" not in status["blocked_reasons"]
|
|
preview = status["transaction_preview"]
|
|
assert preview["mode"] == "seed_transaction_preview_no_session"
|
|
assert preview["statement_count"] == 4
|
|
assert preview["database_session_created"] is False
|
|
assert preview["transaction_opened"] is False
|
|
assert preview["database_commit_executed"] is False
|
|
assert preview["database_snapshot_loaded"] is False
|
|
assert preview["statements"][0]["table"] == "market_platforms"
|
|
assert preview["statements"][0]["diff_status"] == "not_loaded_no_db_session"
|
|
assert "ON CONFLICT (code) DO UPDATE SET" in preview["statements"][0]["sql_template"]
|
|
assert preview["statements"][0]["parameter_payload_hash"]
|
|
assert status["safety_contract"]["refuses_execute_without_apply_flag"] is True
|
|
assert status["safety_contract"]["keeps_crawler_disabled_for_seed_write"] is True
|
|
assert status["safety_contract"]["uses_core_connection_not_orm_session"] is True
|
|
|
|
|
|
def test_seed_writer_cli_status_route_never_leaks_approval_token(monkeypatch):
|
|
from routes.market_intel_routes import market_intel_bp
|
|
|
|
monkeypatch.setenv("MARKET_INTEL_SEED_WRITE_APPROVAL", TEST_APPROVAL_TOKEN)
|
|
|
|
app = Flask(__name__)
|
|
app.secret_key = "test-secret"
|
|
app.register_blueprint(market_intel_bp)
|
|
client = app.test_client()
|
|
with client.session_transaction() as session:
|
|
session["logged_in"] = True
|
|
|
|
response = client.get("/api/market_intel/seed_writer_cli_status?execute=true&platform=all")
|
|
data = response.get_json()
|
|
payload = json.dumps(data, ensure_ascii=False, sort_keys=True)
|
|
|
|
assert response.status_code == 200
|
|
assert data["mode"] == "seed_writer_cli_blocked"
|
|
assert data["execute_requested"] is True
|
|
assert data["apply_real_write_requested"] is False
|
|
assert data["approval_token_present"] is False
|
|
assert data["approval_token_valid"] is False
|
|
assert data["approval_token_secret_configured"] is True
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_writes_database"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["writes_executed"] is False
|
|
assert data["would_write_database"] is False
|
|
assert data["database_session_created"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert "approval_token_present" in data["blocked_reasons"]
|
|
assert "approval_token_valid" in data["blocked_reasons"]
|
|
assert "apply_real_write_requested" in data["blocked_reasons"]
|
|
assert "approval_token_hint" not in payload
|
|
assert TEST_APPROVAL_TOKEN not in payload
|
|
assert "APPROVED_MARKET_INTEL_SEED_WRITE" not in payload
|
|
|
|
|
|
def test_seed_writer_cli_real_write_sqlite_upserts_seed_rows():
|
|
engine = create_engine("sqlite:///:memory:")
|
|
with engine.begin() as conn:
|
|
conn.execute(
|
|
text(
|
|
"""
|
|
CREATE TABLE market_platforms (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
code TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
base_url TEXT,
|
|
enabled BOOLEAN NOT NULL DEFAULT 0,
|
|
crawl_policy_json TEXT,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
)
|
|
"""
|
|
)
|
|
)
|
|
|
|
status = MarketIntelService().build_seed_writer_cli_status(
|
|
platform_code="all",
|
|
execute_requested=True,
|
|
apply_real_write=True,
|
|
approval_token=TEST_APPROVAL_TOKEN,
|
|
approval_token_secret=TEST_APPROVAL_TOKEN,
|
|
engine=engine,
|
|
database_type="sqlite",
|
|
)
|
|
|
|
with engine.connect() as conn:
|
|
rows = conn.execute(
|
|
text("SELECT code, enabled FROM market_platforms ORDER BY code")
|
|
).fetchall()
|
|
|
|
assert status["mode"] == "seed_writer_cli_executed"
|
|
assert status["api_reads_approval_token"] is False
|
|
assert status["api_executes_cli"] is False
|
|
assert status["api_writes_database"] is False
|
|
assert status["ready_for_real_write"] is True
|
|
assert status["writes_executed"] is True
|
|
assert status["would_write_database"] is True
|
|
assert status["database_connection_opened"] is True
|
|
assert status["database_session_created"] is False
|
|
assert status["explicit_transaction_opened"] is True
|
|
assert status["database_write_executed"] is True
|
|
assert status["database_commit_executed"] is True
|
|
assert status["database_rollback_executed"] is False
|
|
assert status["external_network_executed"] is False
|
|
assert status["scheduler_attached"] is False
|
|
assert status["exit_code"] == 0
|
|
assert status["blocked_reasons"] == []
|
|
assert status["execution_result"]["inserted_codes"] == [
|
|
"momo",
|
|
"pchome",
|
|
"coupang",
|
|
"shopee",
|
|
]
|
|
assert status["execution_result"]["updated_codes"] == []
|
|
assert [row[0] for row in rows] == ["coupang", "momo", "pchome", "shopee"]
|
|
assert all(row[1] in (False, 0) for row in rows)
|
|
|
|
|
|
def test_seed_writer_cli_script_outputs_blocked_plan():
|
|
env = {
|
|
**os.environ,
|
|
"MOMO_ALLOW_INSECURE_CONFIG_FOR_TESTS": "true",
|
|
"SECRET_KEY": "test",
|
|
"LOGIN_PASSWORD": "test",
|
|
}
|
|
result = subprocess.run(
|
|
[sys.executable, "scripts/market_intel_seed_writer.py", "--platform", "all"],
|
|
capture_output=True,
|
|
check=False,
|
|
env=env,
|
|
text=True,
|
|
)
|
|
data = json.loads(result.stdout)
|
|
|
|
assert result.returncode == 0
|
|
assert data["mode"] == "seed_writer_cli_blocked"
|
|
assert data["execute_requested"] is False
|
|
assert data["apply_real_write_requested"] is False
|
|
assert data["writes_executed"] is False
|
|
assert data["database_session_created"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["exit_code"] == 0
|
|
assert data["transaction_preview"]["statement_count"] == 4
|
|
assert data["transaction_preview"]["transaction_opened"] is False
|
|
|
|
|
|
def test_candidate_queue_writer_cli_script_outputs_blocked_gate(tmp_path):
|
|
sample_file = tmp_path / "sample.json"
|
|
sample_file.write_text(
|
|
json.dumps(
|
|
{
|
|
"batch_id": "sample-batch-15",
|
|
"platform_code": "momo",
|
|
"source_key": "homepage",
|
|
"source_url": "https://www.momoshop.com.tw/",
|
|
"status": "fetched",
|
|
"status_code": 200,
|
|
"content_length": 1700,
|
|
"page_hash": "c" * 64,
|
|
"title": "MOMO 活動",
|
|
"diagnostics": {
|
|
"link_count": 1,
|
|
"same_host_link_count": 1,
|
|
"campaign_link_candidates": [
|
|
{
|
|
"confidence_band": "high",
|
|
"score": 94,
|
|
"url": "https://www.momoshop.com.tw/activity/sample",
|
|
"text": "品牌活動",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
ensure_ascii=False,
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
env = {
|
|
**os.environ,
|
|
"MOMO_ALLOW_INSECURE_CONFIG_FOR_TESTS": "true",
|
|
"SECRET_KEY": "test",
|
|
"LOGIN_PASSWORD": "test",
|
|
}
|
|
result = subprocess.run(
|
|
[
|
|
sys.executable,
|
|
"scripts/market_intel_candidate_queue_writer.py",
|
|
"--sample-json",
|
|
str(sample_file),
|
|
],
|
|
capture_output=True,
|
|
check=False,
|
|
env=env,
|
|
text=True,
|
|
)
|
|
data = json.loads(result.stdout)
|
|
|
|
assert result.returncode == 0
|
|
assert data["mode"] == "candidate_queue_writer_cli_blocked"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["apply_real_write_requested"] is False
|
|
assert data["writes_executed"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["transaction_preview_summary"]["statement_count"] == 1
|
|
assert "execute_requested" in data["blocked_reasons"]
|
|
|
|
|
|
def test_review_decision_writer_cli_script_outputs_blocked_gate_without_login_env():
|
|
env = {
|
|
key: value
|
|
for key, value in os.environ.items()
|
|
if key not in {"LOGIN_PASSWORD", "SECRET_KEY"}
|
|
}
|
|
result = subprocess.run(
|
|
[sys.executable, "scripts/market_intel_review_decision_writer.py"],
|
|
capture_output=True,
|
|
check=False,
|
|
env=env,
|
|
text=True,
|
|
)
|
|
data = json.loads(result.stdout)
|
|
|
|
assert result.returncode == 0
|
|
assert data["mode"] == "candidate_queue_review_decision_writer_cli_blocked"
|
|
assert data["phase"] == "phase_127_market_intel_mcp_fetch_candidate_queue_review"
|
|
assert data["execute_requested"] is False
|
|
assert data["apply_real_write_requested"] is False
|
|
assert data["approval_token_present"] is False
|
|
assert data["writer_implementation_enabled"] is False
|
|
assert data["ready_for_real_write"] is False
|
|
assert data["api_executes_cli"] is False
|
|
assert data["api_reads_approval_token"] is False
|
|
assert data["database_connection_opened"] is False
|
|
assert data["database_write_executed"] is False
|
|
assert data["database_commit_executed"] is False
|
|
assert data["scheduler_attached"] is False
|
|
assert data["writes_executed"] is False
|
|
assert data["exit_code"] == 0
|