@@ -1744,6 +1745,60 @@ const DASHA_SHADBALA_CALIBRATION_STATUS = {
nextAction: '继续采集 JHora/PyJHora 黑盒截图与分量值;未达标前不得把大运起点或 Shadbala 绝对值说成已完成外部校准。',
};
+const ORACLE_EVIDENCE_PACKET_REQUIRED_METADATA = [
+ 'tool_name',
+ 'tool_version_or_url',
+ 'capture_date',
+ 'source_artifact',
+ 'ayanamsa',
+ 'node_mode',
+ 'timezone',
+ 'operator_note',
+];
+
+const ORACLE_EVIDENCE_INTAKE_TASKS = [
+ {
+ caseId: 'template_user_REDACTED_YEAR_moon_longitude_lahiri',
+ title: 'REDACTED_YEAR 用户盘 · Lahiri 月亮/大运',
+ birth: 'REDACTED_DATE 14:45:20 · REDACTED_PLACE · 36.466667, 114.2 · TZ +08:00',
+ settings: 'ayanamsa=lahiri · node_mode=mean',
+ preferredSources: 'JHora screenshot / PyJHora stdout / VedAstro HTTP',
+ targetFields: ['moon_sidereal_longitude_deg', 'vimshottari_start_date', 'shadbala_components'],
+ },
+ {
+ caseId: 'template_steve_jobs_dasha_lahiri',
+ title: 'Steve Jobs · Dasha 边界样本',
+ birth: '1955-02-24 19:15 · San Francisco · 37.7749, -122.4194 · TZ -08:00',
+ settings: 'ayanamsa=lahiri · node_mode=mean',
+ preferredSources: 'JHora / PyJHora 黑盒输出',
+ targetFields: ['vimshottari_start_date', 'shadbala_components'],
+ },
+ {
+ caseId: 'template_redacted_place_shadbala_raman',
+ title: 'REDACTED_PLACE样本 · Raman Shadbala',
+ birth: 'REDACTED_DATE 14:45:20 · REDACTED_PLACE · 36.466667, 114.2 · TZ +08:00',
+ settings: 'ayanamsa=raman · node_mode=mean',
+ preferredSources: 'JHora Shadbala table screenshot',
+ targetFields: ['shadbala_components'],
+ },
+ {
+ caseId: 'template_extreme_latitude_kp',
+ title: '高纬样本 · KP/Ayanamsa 边界',
+ birth: 'Extreme latitude fixture · local civil time retained',
+ settings: 'ayanamsa=kp · node_mode=mean',
+ preferredSources: 'JHora / VedAstro longitude cross-check',
+ targetFields: ['ascendant_longitude_deg', 'shadbala_components'],
+ },
+ {
+ caseId: 'template_historical_epoch_lahiri',
+ title: '历史年代样本 · Lahiri 回归',
+ birth: 'Historical epoch fixture · Julian/Gregorian policy noted',
+ settings: 'ayanamsa=lahiri · node_mode=mean',
+ preferredSources: 'JHora date policy screenshot',
+ targetFields: ['sun_sidereal_longitude_deg', 'vimshottari_start_date'],
+ },
+];
+
function renderDashaShadbalaCalibrationPanel() {
return `
@@ -1765,6 +1820,168 @@ function renderDashaShadbalaCalibrationPanel() {
`;
}
+function renderOracleEvidenceIntakePanel() {
+ return `
+
+
+ Oracle Evidence Intake
+ 下载 5 个外部真值空白包;只接受 JHora/PyJHora/VedAstro 黑盒证据,禁止本地输出冒充 external_verified。
+
+
+ ${ORACLE_EVIDENCE_INTAKE_TASKS.map(task => `
+
+
+ ${escapeHtml(task.title)}
+ ${escapeHtml(task.birth)}
+ ${escapeHtml(task.settings)} · ${escapeHtml(task.preferredSources)}
+
+
+ ${task.targetFields.map(field => `${escapeHtml(field)}`).join('')}
+
+
+
+ `).join('')}
+
+
+ 晋级规则
+ 默认 status=draft;必须补齐 ${escapeHtml(ORACLE_EVIDENCE_PACKET_REQUIRED_METADATA.join(', '))} 与目标字段,且通过 external_oracle_evidence_validation 后,才允许进入 external_verified 审核。
+
+
+
+
+ 等待填写后的 Evidence Packet;draft、空字段、本地输出会被 external_oracle_evidence_validation 拦截。常见红灯:status_not_external_verified、local_engine_artifact_rejected。
+
+
+
+ `;
+}
+
+function buildOracleEvidencePacket(task) {
+ const target = {};
+ task.targetFields.forEach(field => {
+ target[field] = field === 'shadbala_components' ? {} : null;
+ });
+ return {
+ schema_version: 1,
+ packet_type: 'dasha_shadbala_external_oracle_evidence',
+ case_id: task.caseId,
+ status: 'draft',
+ source_policy: {
+ allowed_sources: task.preferredSources,
+ forbidden_sources: ['local_engine_output', 'copied_agpl_or_commercial_code'],
+ integrity_checks: [
+ 'must_not_come_from_local_engine',
+ 'requires_external_artifact',
+ 'reject_global_shadbala_scaling',
+ ],
+ promotion_target: 'external_verified',
+ },
+ case_context: {
+ title: task.title,
+ birth: task.birth,
+ settings: task.settings,
+ target_fields: task.targetFields,
+ },
+ target,
+ evidence_packet: {
+ status: 'draft',
+ metadata: ORACLE_EVIDENCE_PACKET_REQUIRED_METADATA.reduce((acc, key) => {
+ acc[key] = key === 'capture_date' ? toDateISO(new Date()) : '';
+ return acc;
+ }, {}),
+ },
+ operator_checklist: [
+ 'Fill tool_name and tool_version_or_url from the external product.',
+ 'Attach source_artifact as a screenshot/export path outside this local engine.',
+ 'Fill every target value from black-box output before requesting review.',
+ ],
+ };
+}
+
+function downloadOracleEvidencePacket(caseId) {
+ const task = ORACLE_EVIDENCE_INTAKE_TASKS.find(item => item.caseId === caseId);
+ const status = $('trust-center-status');
+ if (!task) {
+ if (status) status.textContent = '未找到对应的外部真值采集任务。';
+ return;
+ }
+ const packet = buildOracleEvidencePacket(task);
+ downloadText(JSON.stringify(packet, null, 2), `jyotish-oracle-evidence-${task.caseId}.json`, 'application/json;charset=utf-8');
+ if (status) {
+ status.textContent = `已下载 ${task.caseId} 空白证据包;填入外部截图和数值后再运行 evidence validator。`;
+ }
+}
+
+async function importOracleEvidencePacket(file) {
+ const result = $('oracle-evidence-validation-result');
+ if (!file) return;
+ if (!file.name.toLowerCase().endsWith('.json') && file.type !== 'application/json') {
+ if (result) result.textContent = '请选择 JSON Evidence Packet 文件。';
+ return;
+ }
+ try {
+ const packet = JSON.parse(await readWorkspaceFileAsText(file));
+ if (result) result.textContent = '正在调用本地 external_oracle_evidence_validation 判卷...';
+ const response = await validateOracleEvidencePacket(packet);
+ if (result) result.innerHTML = renderOracleEvidenceValidationResult(response);
+ } catch (error) {
+ if (result) {
+ result.innerHTML = renderOracleEvidenceValidationResult({
+ summary: {
+ valid_packets: 0,
+ ready_for_calibration: 0,
+ production_tuning_allowed: false,
+ },
+ packets: [{
+ case_id: 'uploaded',
+ valid: false,
+ problems: [error?.message || 'JSON 格式不正确或本地 API 未连接'],
+ }],
+ boundary: 'Evidence Packet 必须是 JSON,并通过 /api/oracle_evidence 调用本地 validator。',
+ });
+ }
+ }
+}
+
+async function validateOracleEvidencePacket(packet) {
+ if (!window.JyotishAPI?.validateOracleEvidence) {
+ throw new Error('/api/oracle_evidence 不可用,请先启动本地 API 服务。');
+ }
+ return window.JyotishAPI.validateOracleEvidence({ packet });
+}
+
+function renderOracleEvidenceValidationResult(response = {}) {
+ const summary = response.summary || response.report?.summary || {};
+ const packets = response.packets || response.report?.packets || [];
+ const valid = Number(summary.valid_packets || 0);
+ const ready = Number(summary.ready_for_calibration || 0);
+ const tuningAllowed = summary.production_tuning_allowed === true;
+ const tone = tuningAllowed ? 'ok' : (valid > 0 || ready > 0 ? 'warn' : 'blocked');
+ const rows = packets.map(packet => {
+ const problems = Array.isArray(packet.problems) ? packet.problems : [];
+ return `
+
+ ${escapeHtml(packet.case_id || packet.task_id || 'uploaded')}
+ ${escapeHtml(packet.valid ? 'external_verified 可进入人工复核' : '未通过')}
+ ${problems.length ? `${problems.map(escapeHtml).join(' · ')}` : '无 problems;仍需人工确认外部截图与数值。'}
+
+ `;
+ }).join('');
+ return `
+
+
+ external_oracle_evidence_validation
+ valid_packets: ${escapeHtml(String(valid))} · ready_for_calibration: ${escapeHtml(String(ready))} · production_tuning_allowed: ${escapeHtml(String(Boolean(tuningAllowed)).toLowerCase())}
+
+
${rows || '- uploaded没有返回 packet 明细请检查 JSON 格式。
'}
+
${escapeHtml(response.boundary || response.report?.boundary || 'Local engine output remains rejected as an external oracle source.')}
+
+ `;
+}
+
const VALIDATION_TRANSPARENCY = {
source: 'Yoga logic benchmark',
charts: '60 charts',
@@ -2689,6 +2906,9 @@ function bindProvenanceActions() {
if (btn.dataset.action === 'trust-clear-local') {
clearTrustCenterLocalData();
}
+ if (btn.dataset.action === 'oracle-download-packet') {
+ downloadOracleEvidencePacket(btn.dataset.caseId || '');
+ }
if (btn.dataset.action === 'workspace-export-selected') {
exportSelectedWorkspaceChart();
}
@@ -2745,6 +2965,12 @@ function bindProvenanceActions() {
input.value = '';
return;
}
+ const oracleInput = event.target.closest('#oracle-evidence-upload');
+ if (oracleInput) {
+ importOracleEvidencePacket(oracleInput.files?.[0]);
+ oracleInput.value = '';
+ return;
+ }
const caseToggle = event.target.closest('[data-action="workspace-toggle-case"]');
if (caseToggle) {
if (caseToggle.checked) {
diff --git a/jyotish-app/style.css b/jyotish-app/style.css
index b7bd7a62..125c15d8 100644
--- a/jyotish-app/style.css
+++ b/jyotish-app/style.css
@@ -5876,6 +5876,108 @@ body { font-family: var(--font-body); background: var(--bg-page); color: var(--t
flex: 0 0 auto;
color: var(--red);
}
+.oracle-evidence-intake-panel {
+ margin: 10px 0;
+ padding: 10px;
+ border: 1px solid var(--border-light);
+ border-left: 3px solid var(--purple);
+ border-radius: var(--radius-sm);
+ background: var(--bg-surface);
+}
+.oracle-evidence-intake-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 8px;
+ margin-top: 8px;
+}
+.oracle-evidence-card {
+ display: grid;
+ min-width: 0;
+ gap: 8px;
+ padding: 10px;
+ border: 1px solid var(--border-light);
+ border-radius: var(--radius-sm);
+ background: var(--bg-soft);
+}
+.oracle-evidence-card strong,
+.oracle-evidence-card span,
+.oracle-evidence-card small {
+ display: block;
+ overflow-wrap: anywhere;
+}
+.oracle-evidence-card strong {
+ color: var(--text-heading);
+ font-size: 13px;
+}
+.oracle-evidence-card span,
+.oracle-evidence-card small {
+ color: var(--text-muted);
+ font-size: 11px;
+ line-height: 1.45;
+}
+.oracle-evidence-fields {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+}
+.oracle-evidence-fields span {
+ width: auto;
+ padding: 4px 6px;
+ border: 1px solid var(--border-light);
+ border-radius: 999px;
+ background: var(--bg-surface);
+ color: var(--text-heading);
+ font-size: 10px;
+}
+.oracle-evidence-card button {
+ justify-self: start;
+}
+.oracle-evidence-import {
+ display: grid;
+ gap: 8px;
+ margin-top: 10px;
+}
+.oracle-evidence-validation-result {
+ min-width: 0;
+ padding: 10px;
+ border: 1px solid var(--border-light);
+ border-radius: var(--radius-sm);
+ background: var(--bg-soft);
+ color: var(--text-muted);
+ font-size: 12px;
+ line-height: 1.55;
+ overflow-wrap: anywhere;
+}
+.oracle-evidence-validation-result strong,
+.oracle-evidence-validation-result span,
+.oracle-evidence-validation-result small {
+ display: block;
+}
+.oracle-evidence-validation-result ul {
+ display: grid;
+ gap: 6px;
+ margin: 8px 0;
+ padding: 0;
+ list-style: none;
+}
+.oracle-evidence-validation-result li {
+ padding: 8px;
+ border: 1px solid var(--border-light);
+ border-radius: var(--radius-sm);
+ background: var(--bg-surface);
+}
+.oracle-evidence-validation-result strong {
+ color: var(--text-heading);
+}
+.oracle-evidence-validation-ok {
+ border-left: 3px solid var(--green);
+}
+.oracle-evidence-validation-warn {
+ border-left: 3px solid var(--amber);
+}
+.oracle-evidence-validation-blocked {
+ border-left: 3px solid var(--red);
+}
.runtime-health-panel {
margin: 10px 0;
padding: 10px;
@@ -6420,6 +6522,7 @@ body { font-family: var(--font-body); background: var(--bg-page); color: var(--t
.first-use-grid,
.runtime-health-grid,
.trust-status-grid,
+ .oracle-evidence-intake-grid,
.terminology-mode-options,
.case-workspace-controls { grid-template-columns: 1fr; }
.static-demo-boundary-grid { grid-template-columns: 1fr; }
diff --git a/progress.md b/progress.md
index f19265fe..0543093c 100644
--- a/progress.md
+++ b/progress.md
@@ -351,3 +351,8 @@
- 完成导出报告校准边界同步:`jyotish-app/export.js` 新增 `DASHA_SHADBALA_EXPORT_CALIBRATION_STATUS`,JSON 导出在 `meta.calibration_status` 与 `modules.calibration_status.dasha_shadbala` 携带 `ready_for_calibration: 0`、`valid_packets: 0`、`production_tuning_allowed: false`;HTML 报告新增“高级技法校准状态”区块。
- TDD/验证完成:`test_provenance_panchanga_workspace_panel_is_productized` 先因导出模块缺 `DASHA_SHADBALA_EXPORT_CALIBRATION_STATUS` 红灯,修复后转绿;相关 10 项 pytest 通过;`npm run build --prefix jyotish-app` 通过;`oracle_collection_queue.py` + `oracle_evidence_validator.py` 复验仍保持 `valid_packets: 0` / `production_tuning_allowed: false`。
- 当前下一最高优先级:发布 Round 12 副手任务,复核导出 HTML/JSON 校准边界,并推进“外部真值采集表单化 / 手工 JHora 证据包录入模板”。
+- 完成 Oracle Evidence Intake 用户端闭环第一层:Trust Center 新增 5 个外部真值 Evidence Packet 下载卡,覆盖 `template_user_REDACTED_YEAR_moon_longitude_lahiri`、`template_steve_jobs_dasha_lahiri`、`template_redacted_place_shadbala_raman`、`template_extreme_latitude_kp`、`template_historical_epoch_lahiri`,目标字段与 `oracle_collection_queue.py` 当前队列对齐。
+- 完成 Evidence Packet 导入判卷:前端可导入填写后的 JSON,调用后端 `/api/oracle_evidence`,并展示 `valid_packets`、`ready_for_calibration`、`production_tuning_allowed` 与每个 packet 的 `problems`;后端复用 `oracle_collection_queue` 和 `oracle_evidence_validator` 规则,本地输出、空字段与 `draft` 仍被拒绝。
+- 完成副手任务升级:新增 Round 13/14/15 工作单;Round 15 改为 6 个并行包,覆盖 Evidence 判卷闭环、Shadbala 六分量、Dasha 边界日期、高需求技法、外部截图存档规范与下一轮 Codex 任务建议。
+- 验证完成:`python3 -B -m pytest tests/test_frontend_productization.py::test_trust_center_exposes_oracle_evidence_intake_cards tests/test_frontend_productization.py::test_trust_center_and_ai_expose_dasha_shadbala_calibration_status tests/test_frontend_productization.py::test_provenance_panchanga_workspace_panel_is_productized tests/test_api_server_security.py::test_oracle_evidence_api_validates_uploaded_packets tests/test_oracle_collection_queue.py tests/test_oracle_evidence_validator.py -q` 通过;`python3 scripts/oracle_collection_queue.py ...` + `python3 scripts/oracle_evidence_validator.py ...` 仍显示 `valid_packets: 0` / `ready_for_calibration: 0`;`npm run build --prefix jyotish-app` 通过;`git diff --check` 通过。
+- 当前下一最高优先级:创建 `references/oracle/artifacts/` 存档规范和第一条真实 JHora/PyJHora 黑盒证据包,优先推动 Shadbala 六分量与 Vimshottari Dasha 边界日期从 0/5 进入至少 1/5 可人工复核状态。
diff --git a/scripts/jyotish_api_server.py b/scripts/jyotish_api_server.py
index b4009745..56928ea6 100644
--- a/scripts/jyotish_api_server.py
+++ b/scripts/jyotish_api_server.py
@@ -239,6 +239,9 @@ class JyotishAPIHandler(BaseHTTPRequestHandler):
elif path == '/api/report_artifact':
result = self._compute_report_artifact(body)
self._json(result)
+ elif path == '/api/oracle_evidence':
+ result = self._compute_oracle_evidence(body)
+ self._json(result)
elif path == '/api/annual':
result = self._compute_annual(body)
self._json(result)
@@ -404,6 +407,61 @@ class JyotishAPIHandler(BaseHTTPRequestHandler):
with open(path, 'rb') as fh:
return base64.b64encode(fh.read()).decode('ascii')
+ def _compute_oracle_evidence(self, body):
+ packet = body.get('packet')
+ if not isinstance(packet, dict):
+ raise BadRequest('packet must be an object')
+ case_id = packet.get('case_id')
+ if not case_id:
+ raise BadRequest('packet.case_id is required')
+
+ collection_queue = _load_local_module('oracle_collection_queue')
+ evidence_validator = _load_local_module('oracle_evidence_validator')
+ target = packet.get('target') if isinstance(packet.get('target'), dict) else {}
+ target_fields = collection_queue._target_fields(target)
+ status = packet.get('status') or packet.get('evidence_packet', {}).get('status') or 'draft'
+ evidence_packet = packet.get('evidence_packet') if isinstance(packet.get('evidence_packet'), dict) else {}
+ metadata = evidence_packet.get('metadata') if isinstance(evidence_packet.get('metadata'), dict) else {}
+ task = {
+ 'task_id': f'uploaded_{case_id}',
+ 'case_id': case_id,
+ 'status': status,
+ 'target_fields': target_fields,
+ 'missing_target_fields': collection_queue._missing_target_fields(target),
+ 'evidence_packet': {
+ 'capture_id': evidence_packet.get('capture_id') or f'uploaded_{case_id}',
+ 'status': evidence_packet.get('status') or status,
+ 'case_id': case_id,
+ 'required_metadata_fields': collection_queue.REQUIRED_EVIDENCE_METADATA_FIELDS,
+ 'metadata': metadata,
+ 'target_placeholders': {
+ field: collection_queue._target_value(target, field)
+ for field in target_fields
+ },
+ 'integrity_checks': {
+ 'must_not_come_from_local_engine': True,
+ 'requires_external_artifact': True,
+ 'requires_status_external_verified_before_calibration': True,
+ 'reject_global_shadbala_scaling': 'target.shadbala_components' in target_fields,
+ },
+ 'promotion_status_after_fill': 'external_verified',
+ },
+ }
+ report = evidence_validator.build_report({
+ 'scope': 'uploaded_oracle_evidence_packet',
+ 'schema_version': 1,
+ 'tasks': [task],
+ })
+ return {
+ 'success': True,
+ 'endpoint': 'oracle_evidence',
+ 'scope': report['scope'],
+ 'report': report,
+ 'summary': report['summary'],
+ 'packets': report['packets'],
+ 'boundary': report['boundary'],
+ }
+
def _compute_report_artifact(self, body):
html = self._validate_report_html(body.get('html'))
fmt = body.get('format', 'html')
diff --git a/tests/test_api_server_security.py b/tests/test_api_server_security.py
index 3a30e7b4..b18196b4 100644
--- a/tests/test_api_server_security.py
+++ b/tests/test_api_server_security.py
@@ -387,6 +387,83 @@ def test_report_artifact_rejects_active_html(html: str) -> None:
handler._compute_report_artifact({'format': 'html', 'html': html})
+def test_oracle_evidence_api_validates_uploaded_packets() -> None:
+ handler = _handler()
+ draft_packet = {
+ 'case_id': 'template_user_REDACTED_YEAR_moon_longitude_lahiri',
+ 'status': 'draft',
+ 'evidence_packet': {
+ 'status': 'draft',
+ 'metadata': {
+ 'tool_name': '',
+ 'tool_version_or_url': '',
+ 'capture_date': '',
+ 'source_artifact': '',
+ 'ayanamsa': '',
+ 'node_mode': '',
+ 'timezone': '',
+ 'operator_note': '',
+ },
+ },
+ 'target': {
+ 'moon_sidereal_longitude_deg': None,
+ 'vimshottari_start_date': None,
+ 'shadbala_components': {},
+ },
+ }
+
+ draft_result = handler._compute_oracle_evidence({'packet': draft_packet})
+
+ assert draft_result['success'] is True
+ assert draft_result['endpoint'] == 'oracle_evidence'
+ assert draft_result['report']['summary']['valid_packets'] == 0
+ assert draft_result['report']['summary']['ready_for_calibration'] == 0
+ assert draft_result['report']['summary']['production_tuning_allowed'] is False
+ first = draft_result['report']['packets'][0]
+ assert first['valid'] is False
+ assert 'missing_metadata:tool_name' in first['problems']
+ assert 'missing_external_artifact' in first['problems']
+ assert 'status_not_external_verified:draft' in first['problems']
+
+ filled_packet = {
+ **draft_packet,
+ 'status': 'external_verified',
+ 'evidence_packet': {
+ 'status': 'external_verified',
+ 'metadata': {
+ 'tool_name': 'Local Engine',
+ 'tool_version_or_url': 'this-repo',
+ 'capture_date': '2026-06-25',
+ 'source_artifact': 'scripts/jyotish_engine.py output',
+ 'ayanamsa': 'lahiri',
+ 'node_mode': 'mean',
+ 'timezone': 'UTC+08:00',
+ 'operator_note': 'Local run',
+ },
+ },
+ 'target': {
+ 'moon_sidereal_longitude_deg': 311.7897,
+ 'vimshottari_start_date': '1986-05-18',
+ 'shadbala_components': {
+ 'Sun': {
+ 'sthana': 100.0,
+ 'dig': 50.0,
+ 'kala': 100.0,
+ 'chesta': 40.0,
+ 'naisargika': 60.0,
+ 'drik': 30.0,
+ },
+ },
+ },
+ }
+
+ local_result = handler._compute_oracle_evidence({'packet': filled_packet})
+
+ local_first = local_result['report']['packets'][0]
+ assert local_first['valid'] is False
+ assert 'local_engine_artifact_rejected' in local_first['problems']
+
+
def test_capability_audit_scans_registry_and_local_sources() -> None:
handler = _handler()
audit = handler._capability_audit()
diff --git a/tests/test_frontend_productization.py b/tests/test_frontend_productization.py
index ed6b8fb9..b57dbb2b 100644
--- a/tests/test_frontend_productization.py
+++ b/tests/test_frontend_productization.py
@@ -582,6 +582,65 @@ def test_trust_center_and_ai_expose_dasha_shadbala_calibration_status() -> None:
assert token in text
+def test_trust_center_exposes_oracle_evidence_intake_cards() -> None:
+ main = read("main.js")
+ style = read("style.css")
+ api_bridge = read("api-bridge.js")
+ api_server = (ROOT / "scripts" / "jyotish_api_server.py").read_text(encoding="utf-8")
+
+ for token in [
+ "ORACLE_EVIDENCE_INTAKE_TASKS",
+ "ORACLE_EVIDENCE_PACKET_REQUIRED_METADATA",
+ "renderOracleEvidenceIntakePanel",
+ "renderOracleEvidenceValidationResult",
+ "downloadOracleEvidencePacket",
+ "importOracleEvidencePacket",
+ "validateOracleEvidencePacket",
+ "Oracle Evidence Intake",
+ "data-action=\"oracle-download-packet\"",
+ "oracle-evidence-upload",
+ "导入 Evidence Packet 判卷",
+ "/api/oracle_evidence",
+ "external_verified",
+ "must_not_come_from_local_engine",
+ "requires_external_artifact",
+ "reject_global_shadbala_scaling",
+ "status_not_external_verified",
+ "local_engine_artifact_rejected",
+ "template_user_REDACTED_YEAR_moon_longitude_lahiri",
+ "template_steve_jobs_dasha_lahiri",
+ "template_redacted_place_shadbala_raman",
+ "template_extreme_latitude_kp",
+ "template_historical_epoch_lahiri",
+ "moon_sidereal_longitude_deg",
+ "ascendant_longitude_deg",
+ "sun_sidereal_longitude_deg",
+ "vimshottari_start_date",
+ "shadbala_components",
+ "tool_name",
+ "tool_version_or_url",
+ "capture_date",
+ "source_artifact",
+ "operator_note",
+ ]:
+ assert token in main
+
+ assert "validateOracleEvidence" in api_bridge
+ assert "postJson('/api/oracle_evidence'" in api_bridge
+ assert "'/api/oracle_evidence'" in api_server
+ assert "_compute_oracle_evidence" in api_server
+
+ for token in [
+ ".oracle-evidence-intake-panel",
+ ".oracle-evidence-intake-grid",
+ ".oracle-evidence-card",
+ ".oracle-evidence-fields",
+ ".oracle-evidence-validation-result",
+ ".oracle-evidence-card button",
+ ]:
+ assert token in style
+
+
def test_trust_center_exposes_real_case_revalidation_to_users() -> None:
main = read("main.js")
style = read("style.css")