V10.500 add market intel queue writer run closeout review gate

This commit is contained in:
OoO
2026-05-31 15:52:56 +08:00
parent 8f10930cca
commit 2e8f57dfbe
12 changed files with 1425 additions and 203 deletions

View File

@@ -968,6 +968,32 @@
</div>
</div>
<div class="market-intel-panel" data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review>
<div class="market-intel-preview-head">
<div>
<p class="market-intel-muted momo-mono mb-1">MCP / WRITER RUN CLOSEOUT</p>
<h2 class="market-intel-preview-title">MCP Candidate Queue Writer Run Closeout Review</h2>
</div>
<button class="market-intel-icon-button" type="button" title="重新整理 MCP Writer Run Closeout Review" data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-refresh>
<i class="fas fa-rotate-right" aria-hidden="true"></i>
</button>
</div>
<div class="market-intel-preview-meta" data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-meta>
<span class="market-intel-pill">loading</span>
</div>
<div data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-body>
<div class="market-intel-empty">讀取 MCP Writer Run Closeout Review 中...</div>
</div>
<div class="market-intel-control-row mt-3">
<textarea class="market-intel-json-input" rows="9" spellcheck="false" data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-input placeholder="writer run receipt review and closeout JSON"></textarea>
<div class="market-intel-control-actions">
<button class="market-intel-icon-button" type="button" title="審核 MCP Writer Run Closeout Review JSON" data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-review>
<i class="fas fa-check" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<div class="market-intel-panel" data-market-intel-manual-sample>
<div class="market-intel-preview-head">
<div>
@@ -1488,6 +1514,7 @@
const mcpFetchCandidateQueueWriterRunPackageReviewRoot = document.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-package-review]');
const mcpFetchCandidateQueueWriterRunReadinessRoot = document.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-readiness]');
const mcpFetchCandidateQueueWriterRunReceiptReviewRoot = document.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-receipt-review]');
const mcpFetchCandidateQueueWriterRunCloseoutReviewRoot = document.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review]');
const manualSampleRoot = document.querySelector('[data-market-intel-manual-sample]');
const sampleAcceptanceRoot = document.querySelector('[data-market-intel-sample-acceptance]');
const sampleReviewRoot = document.querySelector('[data-market-intel-sample-review]');
@@ -1504,7 +1531,7 @@
const liveInventoryRoot = document.querySelector('[data-market-intel-live-inventory]');
const approvalRoot = document.querySelector('[data-market-intel-approval]');
const deployRoot = document.querySelector('[data-market-intel-deploy]');
if (!root && !writerRoot && !cliRoot && !dbProbeRoot && !seedDiffRoot && !legacyBridgeRoot && !mcpReadinessRoot && !mcpPreflightRoot && !mcpActivationRoot && !mcpFetchGateRoot && !mcpCompletionRoot && !mcpActivationEvidenceRoot && !mcpRuntimeSmokeRoot && !mcpRuntimePromotionRoot && !mcpManualFetchHandoffRoot && !mcpFetchTargetReviewRoot && !mcpFetchRunPackageRoot && !mcpFetchRunReadinessRoot && !mcpFetchRunReceiptRoot && !mcpFetchResultParserReviewRoot && !mcpFetchCandidateHandoffReviewRoot && !mcpFetchCandidateQueueReviewRoot && !mcpFetchCandidateQueueWriterPreflightRoot && !mcpFetchCandidateQueueWriterCliReviewRoot && !mcpFetchCandidateQueueWriterRunPackageReviewRoot && !mcpFetchCandidateQueueWriterRunReadinessRoot && !mcpFetchCandidateQueueWriterRunReceiptReviewRoot && !manualSampleRoot && !sampleAcceptanceRoot && !sampleReviewRoot && !schedulerRoot && !matchReviewRoot && !opportunityRoot && !opportunityScoringRoot && !opportunityEvidenceRoot && !opportunityAlertRoot && !migrationRoot && !migrationDrillRoot && !catalogReviewRoot && !liveSmokeRoot && !liveInventoryRoot && !approvalRoot && !deployRoot) return;
if (!root && !writerRoot && !cliRoot && !dbProbeRoot && !seedDiffRoot && !legacyBridgeRoot && !mcpReadinessRoot && !mcpPreflightRoot && !mcpActivationRoot && !mcpFetchGateRoot && !mcpCompletionRoot && !mcpActivationEvidenceRoot && !mcpRuntimeSmokeRoot && !mcpRuntimePromotionRoot && !mcpManualFetchHandoffRoot && !mcpFetchTargetReviewRoot && !mcpFetchRunPackageRoot && !mcpFetchRunReadinessRoot && !mcpFetchRunReceiptRoot && !mcpFetchResultParserReviewRoot && !mcpFetchCandidateHandoffReviewRoot && !mcpFetchCandidateQueueReviewRoot && !mcpFetchCandidateQueueWriterPreflightRoot && !mcpFetchCandidateQueueWriterCliReviewRoot && !mcpFetchCandidateQueueWriterRunPackageReviewRoot && !mcpFetchCandidateQueueWriterRunReadinessRoot && !mcpFetchCandidateQueueWriterRunReceiptReviewRoot && !mcpFetchCandidateQueueWriterRunCloseoutReviewRoot && !manualSampleRoot && !sampleAcceptanceRoot && !sampleReviewRoot && !schedulerRoot && !matchReviewRoot && !opportunityRoot && !opportunityScoringRoot && !opportunityEvidenceRoot && !opportunityAlertRoot && !migrationRoot && !migrationDrillRoot && !catalogReviewRoot && !liveSmokeRoot && !liveInventoryRoot && !approvalRoot && !deployRoot) return;
const meta = root ? root.querySelector('[data-market-intel-preview-meta]') : null;
const body = root ? root.querySelector('[data-market-intel-preview-body]') : null;
@@ -1647,6 +1674,12 @@
const mcpFetchCandidateQueueWriterRunReceiptReviewReview = mcpFetchCandidateQueueWriterRunReceiptReviewRoot ? mcpFetchCandidateQueueWriterRunReceiptReviewRoot.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-receipt-review-review]') : null;
const mcpFetchCandidateQueueWriterRunReceiptReviewRefresh = mcpFetchCandidateQueueWriterRunReceiptReviewRoot ? mcpFetchCandidateQueueWriterRunReceiptReviewRoot.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-receipt-review-refresh]') : null;
const mcpFetchCandidateQueueWriterRunReceiptReviewEndpoint = "{{ url_for('market_intel.market_intel_mcp_fetch_candidate_queue_writer_run_receipt_review') }}";
const mcpFetchCandidateQueueWriterRunCloseoutReviewMeta = mcpFetchCandidateQueueWriterRunCloseoutReviewRoot ? mcpFetchCandidateQueueWriterRunCloseoutReviewRoot.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-meta]') : null;
const mcpFetchCandidateQueueWriterRunCloseoutReviewBody = mcpFetchCandidateQueueWriterRunCloseoutReviewRoot ? mcpFetchCandidateQueueWriterRunCloseoutReviewRoot.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-body]') : null;
const mcpFetchCandidateQueueWriterRunCloseoutReviewInput = mcpFetchCandidateQueueWriterRunCloseoutReviewRoot ? mcpFetchCandidateQueueWriterRunCloseoutReviewRoot.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-input]') : null;
const mcpFetchCandidateQueueWriterRunCloseoutReviewReview = mcpFetchCandidateQueueWriterRunCloseoutReviewRoot ? mcpFetchCandidateQueueWriterRunCloseoutReviewRoot.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-review]') : null;
const mcpFetchCandidateQueueWriterRunCloseoutReviewRefresh = mcpFetchCandidateQueueWriterRunCloseoutReviewRoot ? mcpFetchCandidateQueueWriterRunCloseoutReviewRoot.querySelector('[data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-refresh]') : null;
const mcpFetchCandidateQueueWriterRunCloseoutReviewEndpoint = "{{ url_for('market_intel.market_intel_mcp_fetch_candidate_queue_writer_run_closeout_review') }}";
const manualSampleMeta = manualSampleRoot ? manualSampleRoot.querySelector('[data-market-intel-manual-sample-meta]') : null;
const manualSampleBody = manualSampleRoot ? manualSampleRoot.querySelector('[data-market-intel-manual-sample-body]') : null;
const manualSampleRefresh = manualSampleRoot ? manualSampleRoot.querySelector('[data-market-intel-manual-sample-refresh]') : null;
@@ -4618,6 +4651,135 @@
}
};
const renderMcpFetchCandidateQueueWriterRunCloseoutReviewMeta = data => {
mcpFetchCandidateQueueWriterRunCloseoutReviewMeta.innerHTML = [
`mode=${data.mode || 'unknown'}`,
`accepted=${data.mcp_fetch_candidate_queue_writer_run_closeout_review_accepted ? 'yes' : 'no'}`,
`gates=${data.passed_gate_count || 0}/${data.gate_count || 0}`,
`rows=${data.payload_row_count || 0}`,
`inventory=${data.ready_for_candidate_queue_post_closeout_inventory_review ? 'ready' : 'blocked'}`,
`db=${data.api_writes_database ? 'write' : 'blocked'}`
].map(item => `<span class="market-intel-pill">${escapeHtml(item)}</span>`).join('');
};
const renderMcpFetchCandidateQueueWriterRunCloseoutReviewBody = data => {
const blockers = (data.blocked_reasons || []).join(' / ');
const gates = data.gates || [];
const receipt = data.writer_run_receipt_review_summary || {};
const closeout = data.operator_closeout_summary || {};
const artifacts = [
['closeout_artifact_path', closeout.closeout_artifact_path, closeout.closeout_artifact_path_safe],
['receipt_review_artifact_path', closeout.receipt_review_artifact_path, closeout.receipt_review_artifact_path_safe],
['post_closeout_inventory_plan_path', closeout.post_closeout_inventory_plan_path, closeout.post_closeout_inventory_plan_path_safe],
['manifest_writer_output_path', closeout.manifest_writer_output_path, closeout.manifest_writer_output_path_safe],
['manifest_postwrite_smoke_result_path', closeout.manifest_postwrite_smoke_result_path, closeout.manifest_postwrite_smoke_result_path_safe],
['manifest_backup_artifact_path', closeout.manifest_backup_artifact_path, closeout.manifest_backup_artifact_path_safe]
];
const steps = data.next_operator_steps || [];
const renderCheck = (key, label, status) => `
<div class="market-intel-check">
<div>
<strong>${escapeHtml(key)}</strong>
<small>${escapeHtml(label || '')}</small>
</div>
<span>${escapeHtml(status)}</span>
</div>
`;
mcpFetchCandidateQueueWriterRunCloseoutReviewBody.innerHTML = `
<div class="market-intel-empty mb-3">此 run closeout review 只審核 receipt review 後的收尾摘要API 不讀 receipt 原文、不執行 CLI、不讀 approval token、不開 DB、不寫 queue、不做 post-closeout query、不掛 scheduler。${blockers ? `阻擋:${escapeHtml(blockers)}` : ''}</div>
<div class="market-intel-deploy-grid">
<div data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-gates>
<p class="market-intel-deploy-section-title">CLOSEOUT GATES</p>
<div class="market-intel-check-list">${
gates.length
? gates.map(item => renderCheck(item.key, item.label, item.passed ? 'PASS' : 'BLOCK')).join('')
: '<div class="market-intel-empty">尚未提供 closeout gates。</div>'
}</div>
</div>
<div data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-receipt>
<p class="market-intel-deploy-section-title">RECEIPT REVIEW LINK</p>
<div class="market-intel-check-list">
${renderCheck('receipt_review', `${receipt.accepted ? 'accepted' : 'pending'} / rows=${receipt.payload_row_count || 0}`, receipt.accepted ? 'ACCEPTED' : 'PENDING')}
${renderCheck('receipt_id', receipt.receipt_id || 'missing', receipt.receipt_id ? 'LINKED' : 'BLOCK')}
${renderCheck('api_boundary', 'no CLI / no token / no DB / no scheduler', receipt.side_effects_clear ? 'CLOSED' : 'BLOCK')}
</div>
</div>
<div data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-closeout>
<p class="market-intel-deploy-section-title">CLOSEOUT SUMMARY</p>
<div class="market-intel-check-list">
${renderCheck('closeout_id', closeout.closeout_id || 'missing', closeout.closeout_id ? 'RECORDED' : 'BLOCK')}
${renderCheck('run_package_id', closeout.run_package_id || 'missing', closeout.run_package_id === receipt.run_package_id ? 'MATCH' : 'BLOCK')}
${renderCheck('receipt_id', closeout.receipt_id || 'missing', closeout.receipt_id === receipt.receipt_id ? 'MATCH' : 'BLOCK')}
${renderCheck('notes', 'closeout notes + rollback note', closeout.closeout_notes_recorded && closeout.rollback_note_recorded ? 'RECORDED' : 'BLOCK')}
</div>
</div>
<div data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-artifacts>
<p class="market-intel-deploy-section-title">ARTIFACT TRACE</p>
<div class="market-intel-check-list">
${artifacts.map(item => renderCheck(item[0], item[1] || 'missing', item[2] ? 'SAFE' : 'BLOCK')).join('')}
</div>
</div>
<div data-market-intel-mcp-fetch-candidate-queue-writer-run-closeout-review-next>
<p class="market-intel-deploy-section-title">BOUNDARY / NEXT</p>
<div class="market-intel-check-list">
${renderCheck('operator_boundaries', 'artifact preserved, read-only inventory, no API DB/CLI/file/scheduler', closeout.receipt_reviewed && closeout.artifacts_preserved && closeout.post_closeout_inventory_read_only && closeout.no_api_database_write && closeout.no_scheduler_attach ? 'CONFIRMED' : 'BLOCK')}
${renderCheck('api_side_effects', 'no closeout file / no CLI / no token / no DB / no queue', data.run_closeout_file_written || data.api_executes_cli || data.api_reads_approval_token || data.api_writes_database || data.post_closeout_query_executed_by_api ? 'BLOCK' : 'CLOSED')}
${steps.map((item, index) => renderCheck(`step_${index + 1}`, item, 'NEXT')).join('')}
</div>
</div>
</div>
`;
if (mcpFetchCandidateQueueWriterRunCloseoutReviewInput && !mcpFetchCandidateQueueWriterRunCloseoutReviewInput.value.trim() && data.sample_writer_run_closeout_review_package) {
mcpFetchCandidateQueueWriterRunCloseoutReviewInput.value = JSON.stringify(data.sample_writer_run_closeout_review_package, null, 2);
}
};
const loadMcpFetchCandidateQueueWriterRunCloseoutReview = async () => {
if (!mcpFetchCandidateQueueWriterRunCloseoutReviewMeta || !mcpFetchCandidateQueueWriterRunCloseoutReviewBody) return;
mcpFetchCandidateQueueWriterRunCloseoutReviewBody.innerHTML = '<div class="market-intel-empty">讀取 MCP Writer Run Closeout Review 中...</div>';
try {
const response = await fetch(mcpFetchCandidateQueueWriterRunCloseoutReviewEndpoint, { credentials: 'same-origin' });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
renderMcpFetchCandidateQueueWriterRunCloseoutReviewMeta(data);
renderMcpFetchCandidateQueueWriterRunCloseoutReviewBody(data);
} catch (error) {
mcpFetchCandidateQueueWriterRunCloseoutReviewMeta.innerHTML = '<span class="market-intel-pill">error</span>';
mcpFetchCandidateQueueWriterRunCloseoutReviewBody.innerHTML = `<div class="market-intel-empty">MCP Writer Run Closeout Review 讀取失敗:${escapeHtml(error.message)}</div>`;
}
};
const reviewMcpFetchCandidateQueueWriterRunCloseoutReview = async () => {
if (!mcpFetchCandidateQueueWriterRunCloseoutReviewMeta || !mcpFetchCandidateQueueWriterRunCloseoutReviewBody || !mcpFetchCandidateQueueWriterRunCloseoutReviewInput) return;
let parsed;
try {
parsed = JSON.parse(mcpFetchCandidateQueueWriterRunCloseoutReviewInput.value || '{}');
} catch (error) {
mcpFetchCandidateQueueWriterRunCloseoutReviewMeta.innerHTML = '<span class="market-intel-pill">json_error</span>';
mcpFetchCandidateQueueWriterRunCloseoutReviewBody.innerHTML = `<div class="market-intel-empty">JSON 格式錯誤:${escapeHtml(error.message)}</div>`;
return;
}
mcpFetchCandidateQueueWriterRunCloseoutReviewBody.innerHTML = '<div class="market-intel-empty">審核 MCP Writer Run Closeout Review 中...</div>';
try {
const response = await fetch(mcpFetchCandidateQueueWriterRunCloseoutReviewEndpoint, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken
},
body: JSON.stringify({ writer_run_closeout_review_package: parsed })
});
const data = await response.json();
if (!response.ok && !data.mode) throw new Error(`HTTP ${response.status}`);
renderMcpFetchCandidateQueueWriterRunCloseoutReviewMeta(data);
renderMcpFetchCandidateQueueWriterRunCloseoutReviewBody(data);
} catch (error) {
mcpFetchCandidateQueueWriterRunCloseoutReviewMeta.innerHTML = '<span class="market-intel-pill">error</span>';
mcpFetchCandidateQueueWriterRunCloseoutReviewBody.innerHTML = `<div class="market-intel-empty">MCP Writer Run Closeout Review 審核失敗:${escapeHtml(error.message)}</div>`;
}
};
const renderManualSampleMeta = data => {
manualSampleMeta.innerHTML = [
`mode=${data.mode || 'unknown'}`,
@@ -14117,6 +14279,12 @@
if (mcpFetchCandidateQueueWriterRunReceiptReviewReview) {
mcpFetchCandidateQueueWriterRunReceiptReviewReview.addEventListener('click', reviewMcpFetchCandidateQueueWriterRunReceiptReview);
}
if (mcpFetchCandidateQueueWriterRunCloseoutReviewRefresh) {
mcpFetchCandidateQueueWriterRunCloseoutReviewRefresh.addEventListener('click', loadMcpFetchCandidateQueueWriterRunCloseoutReview);
}
if (mcpFetchCandidateQueueWriterRunCloseoutReviewReview) {
mcpFetchCandidateQueueWriterRunCloseoutReviewReview.addEventListener('click', reviewMcpFetchCandidateQueueWriterRunCloseoutReview);
}
if (manualSampleRefresh) {
manualSampleRefresh.addEventListener('click', loadManualSample);
}
@@ -14387,6 +14555,7 @@
loadMcpFetchCandidateQueueWriterRunPackageReview();
loadMcpFetchCandidateQueueWriterRunReadiness();
loadMcpFetchCandidateQueueWriterRunReceiptReview();
loadMcpFetchCandidateQueueWriterRunCloseoutReview();
loadManualSample();
loadSampleAcceptance();
loadSampleReview();