eduevidence 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +506 -0
- package/README.zh-CN.md +434 -0
- package/SKILL.md +195 -0
- package/bin/eduevidence.js +127 -0
- package/domains/education/manifest.json +183 -0
- package/domains/education/outcome_taxonomy.json +127 -0
- package/domains/manifest.json +26 -0
- package/domains/policy/frame.schema.json +234 -0
- package/domains/policy/manifest.json +10 -0
- package/domains/policy/methodology_checklist.json +109 -0
- package/domains/policy/outcome_taxonomy.json +53 -0
- package/domains/policy/references/causal-identification.md +45 -0
- package/domains/policy/references/cost-evidence.md +44 -0
- package/domains/policy/references/equity.md +42 -0
- package/domains/policy/references/evidence-hierarchy.md +41 -0
- package/domains/policy/references/implementation-evidence.md +47 -0
- package/eduevidence_cli.py +26 -0
- package/engine/__init__.py +11 -0
- package/engine/__pycache__/__init__.cpython-312.pyc +0 -0
- package/engine/__pycache__/analysis.cpython-312.pyc +0 -0
- package/engine/__pycache__/bias.cpython-312.pyc +0 -0
- package/engine/__pycache__/briefs.cpython-312.pyc +0 -0
- package/engine/__pycache__/capabilities.cpython-312.pyc +0 -0
- package/engine/__pycache__/citation_check.cpython-312.pyc +0 -0
- package/engine/__pycache__/contracts.cpython-312.pyc +0 -0
- package/engine/__pycache__/datasets.cpython-312.pyc +0 -0
- package/engine/__pycache__/events.cpython-312.pyc +0 -0
- package/engine/__pycache__/evidence_graph.cpython-312.pyc +0 -0
- package/engine/__pycache__/evidence_review.cpython-312.pyc +0 -0
- package/engine/__pycache__/evidencecore.cpython-312.pyc +0 -0
- package/engine/__pycache__/gap_lens.cpython-312.pyc +0 -0
- package/engine/__pycache__/gaps.cpython-312.pyc +0 -0
- package/engine/__pycache__/graph_store.cpython-312.pyc +0 -0
- package/engine/__pycache__/graph_validate.cpython-312.pyc +0 -0
- package/engine/__pycache__/ids.cpython-312.pyc +0 -0
- package/engine/__pycache__/library.cpython-312.pyc +0 -0
- package/engine/__pycache__/library_builtin.cpython-312.pyc +0 -0
- package/engine/__pycache__/living.cpython-312.pyc +0 -0
- package/engine/__pycache__/log.cpython-312.pyc +0 -0
- package/engine/__pycache__/meta_analysis.cpython-312.pyc +0 -0
- package/engine/__pycache__/meta_synthesis.cpython-312.pyc +0 -0
- package/engine/__pycache__/migration.cpython-312.pyc +0 -0
- package/engine/__pycache__/mode_router.cpython-312.pyc +0 -0
- package/engine/__pycache__/paths.cpython-312.pyc +0 -0
- package/engine/__pycache__/pilot.cpython-312.pyc +0 -0
- package/engine/__pycache__/planner.cpython-312.pyc +0 -0
- package/engine/__pycache__/project.cpython-312.pyc +0 -0
- package/engine/__pycache__/projections.cpython-312.pyc +0 -0
- package/engine/__pycache__/robustness.cpython-312.pyc +0 -0
- package/engine/__pycache__/run.cpython-312.pyc +0 -0
- package/engine/__pycache__/semantics.cpython-312.pyc +0 -0
- package/engine/__pycache__/study_design.cpython-312.pyc +0 -0
- package/engine/__pycache__/synthesis.cpython-312.pyc +0 -0
- package/engine/__pycache__/tribunal.cpython-312.pyc +0 -0
- package/engine/__pycache__/update.cpython-312.pyc +0 -0
- package/engine/__pycache__/versions.cpython-312.pyc +0 -0
- package/engine/analysis.py +308 -0
- package/engine/bias.py +178 -0
- package/engine/briefs.py +106 -0
- package/engine/capabilities.py +99 -0
- package/engine/citation_check.py +192 -0
- package/engine/contracts.py +117 -0
- package/engine/datasets.py +165 -0
- package/engine/events.py +67 -0
- package/engine/evidence_graph.py +571 -0
- package/engine/evidence_review.py +88 -0
- package/engine/evidencecore.py +182 -0
- package/engine/gap_lens.py +132 -0
- package/engine/gaps.py +169 -0
- package/engine/graph_store.py +335 -0
- package/engine/graph_validate.py +87 -0
- package/engine/ids.py +77 -0
- package/engine/library.py +268 -0
- package/engine/library_builtin.py +301 -0
- package/engine/living.py +671 -0
- package/engine/log.py +39 -0
- package/engine/meta_analysis.py +333 -0
- package/engine/meta_synthesis.py +111 -0
- package/engine/migration.py +397 -0
- package/engine/mode_router.py +72 -0
- package/engine/paths.py +15 -0
- package/engine/pilot.py +368 -0
- package/engine/planner.py +126 -0
- package/engine/project.py +118 -0
- package/engine/projections.py +240 -0
- package/engine/robustness.py +109 -0
- package/engine/run.py +85 -0
- package/engine/semantics.py +135 -0
- package/engine/study_design.py +87 -0
- package/engine/synthesis.py +187 -0
- package/engine/tribunal.py +408 -0
- package/engine/update.py +113 -0
- package/engine/versions.py +12 -0
- package/install.sh +510 -0
- package/integrations/__init__.py +1 -0
- package/integrations/__pycache__/__init__.cpython-312.pyc +0 -0
- package/integrations/__pycache__/agent_mcp.cpython-312.pyc +0 -0
- package/integrations/__pycache__/smart_web_fetch.cpython-312.pyc +0 -0
- package/integrations/agent_mcp.py +856 -0
- package/integrations/smart_web_fetch.py +59 -0
- package/package.json +50 -0
- package/pyproject.toml +55 -0
- package/references/applicability-policy.md +88 -0
- package/references/education-framing.md +132 -0
- package/references/effect_size_formulas.md +35 -0
- package/references/evaluation-design.md +111 -0
- package/references/evidence-quality.md +79 -0
- package/references/grade_framework.md +29 -0
- package/references/intervention-design.md +98 -0
- package/references/methodology-audit.md +103 -0
- package/references/outcome-taxonomy.md +106 -0
- package/references/retrieval-protocol.md +142 -0
- package/references/skeptic-protocol.md +93 -0
- package/references/social_science_pitfalls.md +48 -0
- package/references/source-validity.md +140 -0
- package/references/tribunal-policy.md +112 -0
- package/references/wwc_standards.md +29 -0
- package/retrieval/__init__.py +1 -0
- package/retrieval/__pycache__/__init__.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/corpus_store.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/dedupe.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/failures.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/fetch.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/search.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/source.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/validate.cpython-312.pyc +0 -0
- package/retrieval/corpus_store.py +181 -0
- package/retrieval/dedupe.py +127 -0
- package/retrieval/failures.py +90 -0
- package/retrieval/fetch.py +435 -0
- package/retrieval/search.py +493 -0
- package/retrieval/source.py +160 -0
- package/retrieval/validate.py +257 -0
- package/schemas/agent-mcp-approval.schema.json +57 -0
- package/schemas/chart-spec.schema.json +88 -0
- package/schemas/cross-model-review.schema.json +28 -0
- package/schemas/education-frame.schema.json +106 -0
- package/schemas/evaluation.schema.json +35 -0
- package/schemas/evidence.schema.json +81 -0
- package/schemas/fetch-result.schema.json +119 -0
- package/schemas/intervention.schema.json +46 -0
- package/schemas/methodology.schema.json +102 -0
- package/schemas/report-result.schema.json +381 -0
- package/schemas/report-spec.schema.json +130 -0
- package/schemas/source.schema.json +311 -0
- package/schemas/v2/analysis-plan.schema.json +28 -0
- package/schemas/v2/analysis-run.schema.json +33 -0
- package/schemas/v2/claim.schema.json +26 -0
- package/schemas/v2/dataset-asset.schema.json +40 -0
- package/schemas/v2/decision-snapshot.schema.json +53 -0
- package/schemas/v2/evidence-link.schema.json +38 -0
- package/schemas/v2/finding.schema.json +47 -0
- package/schemas/v2/graph-revision.schema.json +30 -0
- package/schemas/v2/knowledge-gap.schema.json +40 -0
- package/schemas/v2/methodology-audit.schema.json +30 -0
- package/schemas/v2/outcome.schema.json +18 -0
- package/schemas/v2/project.schema.json +31 -0
- package/schemas/v2/research-intent.schema.json +24 -0
- package/schemas/v2/run.schema.json +43 -0
- package/schemas/v2/source.schema.json +24 -0
- package/schemas/v2/study-design.schema.json +67 -0
- package/schemas/v2/study.schema.json +37 -0
- package/schemas/v3/pilot-outcome.schema.json +132 -0
- package/schemas/v3/run-manifest.schema.json +193 -0
- package/schemas/v3/synthesis.schema.json +86 -0
- package/schemas/v4/drift-report.schema.json +66 -0
- package/schemas/v4/evidence-library.schema.json +42 -0
- package/schemas/v4/living-subscription.schema.json +55 -0
- package/schemas/v4/meta-analysis.schema.json +152 -0
- package/schemas/verdict.schema.json +56 -0
- package/scripts/__init__.py +0 -0
- package/scripts/__pycache__/__init__.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_evaluator.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_judge.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_routing.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_v2.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_v3.cpython-312.pyc +0 -0
- package/scripts/__pycache__/build_result.cpython-312.pyc +0 -0
- package/scripts/__pycache__/claim_audit.cpython-312.pyc +0 -0
- package/scripts/__pycache__/complexity_gate.cpython-312.pyc +0 -0
- package/scripts/__pycache__/compute_confidence.cpython-312.pyc +0 -0
- package/scripts/__pycache__/dashboard_server.cpython-312.pyc +0 -0
- package/scripts/__pycache__/did_regression.cpython-312.pyc +0 -0
- package/scripts/__pycache__/effect_calculator.cpython-312.pyc +0 -0
- package/scripts/__pycache__/evidence_matrix.cpython-312.pyc +0 -0
- package/scripts/__pycache__/evidence_score.cpython-312.pyc +0 -0
- package/scripts/__pycache__/evidence_semantics.cpython-312.pyc +0 -0
- package/scripts/__pycache__/fetch_benchmark.cpython-312.pyc +0 -0
- package/scripts/__pycache__/lint_report_layout.cpython-312.pyc +0 -0
- package/scripts/__pycache__/orchestrator.cpython-312.pyc +0 -0
- package/scripts/__pycache__/pre_verdict_gate.cpython-312.pyc +0 -0
- package/scripts/__pycache__/recompute_demo_quality.cpython-312.pyc +0 -0
- package/scripts/__pycache__/render_report.cpython-312.pyc +0 -0
- package/scripts/__pycache__/render_report_html.cpython-312.pyc +0 -0
- package/scripts/__pycache__/run_workspace.cpython-312.pyc +0 -0
- package/scripts/__pycache__/skill_lint.cpython-312.pyc +0 -0
- package/scripts/__pycache__/startup_probe.cpython-312.pyc +0 -0
- package/scripts/__pycache__/sync_killer_demo_report.cpython-312.pyc +0 -0
- package/scripts/__pycache__/test_adversarial_empirical.cpython-312-pytest-9.0.2.pyc +0 -0
- package/scripts/__pycache__/test_adversarial_empirical.cpython-312-pytest-9.1.1.pyc +0 -0
- package/scripts/__pycache__/validate_schema.cpython-312.pyc +0 -0
- package/scripts/audit_dois.py +292 -0
- package/scripts/bake_pack.sh +37 -0
- package/scripts/benchmark.py +183 -0
- package/scripts/benchmark_evaluator.py +371 -0
- package/scripts/benchmark_judge.py +535 -0
- package/scripts/benchmark_routing.py +120 -0
- package/scripts/benchmark_v2.py +304 -0
- package/scripts/benchmark_v3.py +552 -0
- package/scripts/build_esl_artifacts.py +1921 -0
- package/scripts/build_evidence_library.py +307 -0
- package/scripts/build_killer_demo.py +295 -0
- package/scripts/build_result.py +311 -0
- package/scripts/check_version_consistency.py +96 -0
- package/scripts/citation_check.py +123 -0
- package/scripts/claim_audit.py +157 -0
- package/scripts/complexity_gate.py +180 -0
- package/scripts/compute_confidence.py +176 -0
- package/scripts/dashboard_server.py +536 -0
- package/scripts/did_regression.py +315 -0
- package/scripts/effect_calculator.py +99 -0
- package/scripts/enrich_projects_human_and_lieflat.py +315 -0
- package/scripts/evidence_matrix.py +129 -0
- package/scripts/evidence_score.py +234 -0
- package/scripts/evidence_semantics.py +87 -0
- package/scripts/fetch_benchmark.py +177 -0
- package/scripts/generate_metrics.py +99 -0
- package/scripts/generate_new_projects.py +686 -0
- package/scripts/generate_promo.py +192 -0
- package/scripts/lint_report_layout.py +182 -0
- package/scripts/orchestrator.py +1456 -0
- package/scripts/pre_verdict_gate.py +513 -0
- package/scripts/quickstart.py +121 -0
- package/scripts/rebake_all_5themes.py +88 -0
- package/scripts/recompute_demo_quality.py +205 -0
- package/scripts/render_report.py +270 -0
- package/scripts/render_report_html.py +356 -0
- package/scripts/retraction_watch.py +110 -0
- package/scripts/run_workspace.py +337 -0
- package/scripts/serve_web.py +54 -0
- package/scripts/skill_lint.py +150 -0
- package/scripts/startup_probe.py +265 -0
- package/scripts/sync_killer_demo_report.py +270 -0
- package/scripts/test_adversarial_empirical.py +541 -0
- package/scripts/validate_schema.py +256 -0
- package/skill/agents/education-planner.md +80 -0
- package/skill/agents/evaluation-designer.md +74 -0
- package/skill/agents/evidence-analyst.md +106 -0
- package/skill/agents/evidence-judge.md +111 -0
- package/skill/agents/evidence-retriever.md +80 -0
- package/skill/agents/intervention-designer.md +82 -0
- package/skill/agents/method-reviewer.md +104 -0
- package/skill/agents/skeptic.md +89 -0
- package/skill/sub-skills/aihot-trend-analysis/SKILL.md +31 -0
- package/skill/sub-skills/contradiction-analysis/SKILL.md +17 -0
- package/skill/sub-skills/data-analysis/SKILL.md +23 -0
- package/skill/sub-skills/ethics-review/SKILL.md +25 -0
- package/skill/sub-skills/evidence-extraction/SKILL.md +19 -0
- package/skill/sub-skills/evidence-review/SKILL.md +18 -0
- package/skill/sub-skills/gap-analysis/SKILL.md +25 -0
- package/skill/sub-skills/literature-review/SKILL.md +21 -0
- package/skill/sub-skills/methodology-audit/SKILL.md +20 -0
- package/skill/sub-skills/report-generation/SKILL.md +51 -0
- package/skill/sub-skills/research-planning/SKILL.md +21 -0
- package/skill/sub-skills/study-design/SKILL.md +16 -0
- package/skill/task-briefs/adjudicate.md +17 -0
- package/skill/task-briefs/audit.md +15 -0
- package/skill/task-briefs/challenge.md +15 -0
- package/skill/task-briefs/evaluate.md +13 -0
- package/skill/task-briefs/extract.md +16 -0
- package/skill/task-briefs/frame.md +17 -0
- package/skill/task-briefs/intervene.md +14 -0
- package/skill/task-briefs/present.md +16 -0
- package/skill/task-briefs/retrieve.md +15 -0
- package/visualization/eduevidence-report/assets/base.css +337 -0
- package/visualization/eduevidence-report/motion/motion.css +157 -0
- package/visualization/eduevidence-report/motion/motion.js +107 -0
- package/visualization/eduevidence-report/references/bilingual-style.md +7 -0
- package/visualization/eduevidence-report/references/component-catalog.md +145 -0
- package/visualization/eduevidence-report/references/evidence-expansion.md +65 -0
- package/visualization/eduevidence-report/references/full-report-outline.md +86 -0
- package/visualization/eduevidence-report/references/layout-constraints.md +63 -0
- package/visualization/eduevidence-report/references/lieflat-composition.md +79 -0
- package/visualization/eduevidence-report/references/motion-system.md +31 -0
- package/visualization/eduevidence-report/schemas/adapter-envelope.schema.json +22 -0
- package/visualization/eduevidence-report/schemas/visual-layout.schema.json +87 -0
- package/visualization/eduevidence-report/scripts/__pycache__/adapter_contract.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_artifact_manifest.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_charts.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_figures.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_infographics.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_report.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/charts_data.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/lieflat_engine.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/zh_labels.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/adapter_contract.py +72 -0
- package/visualization/eduevidence-report/scripts/build_artifact_manifest.py +70 -0
- package/visualization/eduevidence-report/scripts/build_charts.py +283 -0
- package/visualization/eduevidence-report/scripts/build_figures.py +515 -0
- package/visualization/eduevidence-report/scripts/build_infographics.py +268 -0
- package/visualization/eduevidence-report/scripts/build_report.py +3211 -0
- package/visualization/eduevidence-report/scripts/charts_data.py +617 -0
- package/visualization/eduevidence-report/scripts/check_mobile_layout.js +220 -0
- package/visualization/eduevidence-report/scripts/lieflat_engine.py +852 -0
- package/visualization/eduevidence-report/scripts/zh_labels.py +245 -0
- package/visualization/eduevidence-report/themes/academic.css +94 -0
- package/visualization/eduevidence-report/themes/claude.css +96 -0
- package/visualization/eduevidence-report/themes/datalab-dark.css +147 -0
- package/visualization/eduevidence-report/themes/datalab.css +151 -0
- package/visualization/eduevidence-report/themes/presentation.css +140 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Source Validity(来源有效性校验)
|
|
2
|
+
|
|
3
|
+
## 1. 目的与定位
|
|
4
|
+
|
|
5
|
+
本协议是工作流第 4 步 Validate 的判定标准,回答一个问题:**这个来源能不能被引用?**
|
|
6
|
+
|
|
7
|
+
与 evidence-quality.md 的分工必须分清:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
source-validity.md → 来源是否真实、完整、可定位(能不能引用)
|
|
11
|
+
evidence-quality.md → 研究设计质量高低(值不值得信)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**来源有效 ≠ 证据 strong**。一篇真实存在、抓取完整、可精确定位的论文,其证据
|
|
15
|
+
质量仍可能因设计缺陷只有 `weak`;反过来,一篇设计精良的研究若来源无法验证
|
|
16
|
+
(撤稿、抓取残缺、引用错位),也不能进入 Evidence Matrix。两者都通过,证据
|
|
17
|
+
才能被裁判庭使用。
|
|
18
|
+
|
|
19
|
+
## 2. 抓取完整性校验(对齐 fetch-result.schema.json)
|
|
20
|
+
|
|
21
|
+
每次 Fetch 尝试必须记录 `fetch_status`,并按以下规则判定:
|
|
22
|
+
|
|
23
|
+
| 状态 | 判定条件(validation 字段) | 是否可进入 Extraction |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `FETCH_VALID` | `http_success=true` 且 `body_length_ok=true` 且 `title_matches!=false` 且 `is_login_page=false` 且 `is_error_page=false` 且 `is_captcha_page=false` 且 `navigation_only=false` | ✅ 是 |
|
|
26
|
+
| `FETCH_PARTIAL` | 正文主体可读,但部分内容缺失(如页脚、附录、部分图表) | ⚠️ 仅当缺失部分**不涉及**结论依赖的关键数字/统计量时,经规则确认后可进入 |
|
|
27
|
+
| `FETCH_FAILED` | 上述任一关键项失败,或正文为空/被拦截 | ❌ 否;snippet 不得作为 SUPPORTED Evidence(RULE 2) |
|
|
28
|
+
|
|
29
|
+
### 完整性自检(PDF 与清洗链路)
|
|
30
|
+
|
|
31
|
+
- 清洗/解析可能丢弃表格与数字。抽取前必须抽查:**关键统计量(样本量、效应量、
|
|
32
|
+
p 值、均值差)在清洗后正文中可找到**;找不到则按 `FETCH_PARTIAL` 处理并标注
|
|
33
|
+
缺失项,禁止从摘要或引用片段"补回"数字。
|
|
34
|
+
- `date_identifiable=false` 时不得声称"最新研究";按 `unknown + 如何获取` 标注
|
|
35
|
+
(FR-03)。
|
|
36
|
+
|
|
37
|
+
## 3. 来源真实性校验
|
|
38
|
+
|
|
39
|
+
即使抓取完整,来源本身也可能不可信。逐项检查:
|
|
40
|
+
|
|
41
|
+
### 3.1 同行评审与出版状态
|
|
42
|
+
|
|
43
|
+
- 期刊/会议是否为正规出版渠道(可查 ISSN、出版社、会议主办方);
|
|
44
|
+
- **撤稿检查**:检索 Retraction Watch / 出版方页面,确认无撤稿或更正记录;
|
|
45
|
+
- **掠夺性期刊筛查**:无同行评审流程、版面费可疑、ISSN 伪造等特征的期刊,
|
|
46
|
+
其论文按 `tier5_general_web` 处理,不得作 SUPPORTED 证据。
|
|
47
|
+
|
|
48
|
+
### 3.2 预印本处理规则(tier2 场景)
|
|
49
|
+
|
|
50
|
+
arXiv / SSRN / 机构知识库等预印本与未同行评审稿(`tier2_academic_database`):
|
|
51
|
+
|
|
52
|
+
- 预印本**可作候选证据**进入 Extraction,但结论中必须标注
|
|
53
|
+
`预印本、未同行评审`,证据质量评分不得因"来源在 arXiv 上"获得加分;
|
|
54
|
+
- 同一研究已有正式发表版的,**以正式发表版为准**(见第 4 节版本一致性);
|
|
55
|
+
仅存预印本时,其结论在 Tribunal 中按降半档权重处理(如原本可支撑
|
|
56
|
+
`moderate` 的仅能支撑 `weak`);
|
|
57
|
+
- 预印本被撤下(withdrawn)或经同行评审大幅修改的,以最新状态为准并记录变更。
|
|
58
|
+
|
|
59
|
+
### 3.3 AI 生成论文筛查
|
|
60
|
+
|
|
61
|
+
以下特征组合出现时,将论文标为疑似 AI 生成,降级处理或排除:
|
|
62
|
+
|
|
63
|
+
- 无方法细节、无原始数据、无样本描述;
|
|
64
|
+
- 引用异常(引文存在但内容不相关、引用数量异常);
|
|
65
|
+
- 讨论空洞、结论超出数据。
|
|
66
|
+
|
|
67
|
+
### 3.4 厂商与利益相关方声明
|
|
68
|
+
|
|
69
|
+
- 厂商/行业声明一律不得作独立证据(retrieval-protocol.md RP-03),即使
|
|
70
|
+
authority_level 字段误标为学术来源,校验时必须修正。
|
|
71
|
+
- 论文的**资助方与利益冲突**必须记录:厂商资助的研究,其结论按证据质量
|
|
72
|
+
评分后仍需在 applicability 的 `risk_factors` 中提示(applicability-policy.md)。
|
|
73
|
+
|
|
74
|
+
## 4. 内容一致性校验
|
|
75
|
+
|
|
76
|
+
| 检查 | 判定标准 | 失败处理 |
|
|
77
|
+
| --- | --- | --- |
|
|
78
|
+
| `title_matches` | 抓取到的页面标题与声称的来源标题一致 | 不一致 → `INVALID` 或回溯到正确 URL |
|
|
79
|
+
| `url_matches` | 内容确实来自 `canonical_url`,而非跳转后的无关页面 | 跳转后内容不符 → `INVALID` |
|
|
80
|
+
| 版本一致性 | 预印本与正式发表版并存时,**以正式发表版为准**;内容差异显著时两个版本分别记录并互相引用 | 未核对版本 → 结论限定"该版本" |
|
|
81
|
+
| 引文定位 | 引用的语句能在 `source_locator`(页码/段落/quote_hash)处找到原文 | 定位失败 → 证据标记 `UNSUPPORTED` |
|
|
82
|
+
|
|
83
|
+
引文定位是 Citation Audit 的前置条件:Claim → Evidence → Source → Source
|
|
84
|
+
Location 的追溯链(SKILL.md 第 10 章)在来源校验阶段就必须可走通,禁止"引用
|
|
85
|
+
存在但找不到原文位置"的证据进入 Matrix。
|
|
86
|
+
|
|
87
|
+
## 5. 去重(对齐 dedupe_keys)
|
|
88
|
+
|
|
89
|
+
`dedupe_keys` 四键:`canonical_url` / `doi` / `title_fingerprint` / `content_hash`。
|
|
90
|
+
任一键命中即视为同一来源:
|
|
91
|
+
|
|
92
|
+
| 情形 | 处理 |
|
|
93
|
+
| --- | --- |
|
|
94
|
+
| 同一论文多 URL(如出版社页 + PDF 直链) | 保留一个 `canonical_url`,其余标 `DUPLICATE` 并关联 |
|
|
95
|
+
| 同一研究多版本(会议版 + 期刊版 + 预印本) | 保留正式发表版为 primary,其余标 `DUPLICATE` 并关联;版本差异影响结论时按第 4 节处理 |
|
|
96
|
+
| 同一论文多个独立样本/子研究 | **不是重复**:各样本分别绑定 Evidence(Pre-Verdict Gate 的独立样本计数以此为准),但 `source_id` 需带样本后缀,禁止合并为一条 |
|
|
97
|
+
| 内容相同但 URL 不同的镜像站 | 按 `content_hash` 判重 |
|
|
98
|
+
|
|
99
|
+
## 6. 状态流转(对齐 source.schema.json `status` 枚举)
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
DISCOVERED ──Fetch──▶ FETCHED ──Validate──▶ VALID(可进入 Extraction)
|
|
103
|
+
│ ├─ PARTIAL(规则确认后可用)
|
|
104
|
+
│ └─ INVALID(真实性/一致性失败)
|
|
105
|
+
├──▶ FAILED(FETCH_FAILED,RULE 2)
|
|
106
|
+
└──▶ DUPLICATE(去重命中,关联 primary)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
- `VALID` / `PARTIAL`:可进入 Evidence Extraction;
|
|
110
|
+
- `FAILED`:来源保留在 sources.jsonl 中作记录,snippet 不得升级为证据;
|
|
111
|
+
- `DUPLICATE`:不进入 Extraction,关联到 primary;
|
|
112
|
+
- `INVALID`:从候选移除,禁止引用;
|
|
113
|
+
- Pre-Verdict Gate 的 `Sources valid` 项要求:进入裁判的全部来源状态为
|
|
114
|
+
`VALID` 或规则确认的 `PARTIAL`,且去重完成。
|
|
115
|
+
|
|
116
|
+
### 状态流转示例
|
|
117
|
+
|
|
118
|
+
> 某 arXiv 预印本声称"Copilot 提高作业正确率":
|
|
119
|
+
>
|
|
120
|
+
> 1. `DISCOVERED` → Fetch 成功(正文完整、统计量可定位)→ `FETCHED`;
|
|
121
|
+
> 2. Validate:`title_matches=true`、内容与声称一致 → 初步 `VALID`;
|
|
122
|
+
> 3. 检索发现同一研究已有正式期刊版(带 DOI)→ 预印本标 `DUPLICATE`,
|
|
123
|
+
> 关联期刊版为 primary(§3.2 / §5);
|
|
124
|
+
> 4. 期刊版结论为"正确率无显著差异" → 以期刊版为准,预印本不进入
|
|
125
|
+
> Extraction,其摘要不得作为任何 Evidence 的内容(RULE 2)。
|
|
126
|
+
|
|
127
|
+
## 7. 执行规则(必须遵守)
|
|
128
|
+
|
|
129
|
+
| 编号 | 内容 |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| SV-01 | 每条证据的绑定来源必须经过完整性、真实性、一致性、可定位性四类校验,缺一不可。 |
|
|
132
|
+
| SV-02 | `FETCH_FAILED` 时 snippet 不得作为 SUPPORTED Evidence(RULE 2);只能标注 `FAILED` 或 `DISCOVERED`。 |
|
|
133
|
+
| SV-03 | `FETCH_PARTIAL` 仅在缺失部分不涉及关键统计量时可用;涉及则降为 `FAILED`。 |
|
|
134
|
+
| SV-04 | 关键统计量(样本量/效应量/p 值/均值差)在清洗后正文中不可定位 → 按 `PARTIAL` 处理并标注缺失项。 |
|
|
135
|
+
| SV-05 | 撤稿论文、掠夺性期刊论文、疑似 AI 生成论文不得进入 Evidence Matrix;发现后从候选移除并记录原因。 |
|
|
136
|
+
| SV-06 | 厂商声明与利益相关方材料不得作独立证据(retrieval-protocol.md RP-03);资助方信息必须记录。 |
|
|
137
|
+
| SV-07 | 引文无法在 `source_locator` 处定位 → 证据标记 `UNSUPPORTED`,禁止进入 Matrix。 |
|
|
138
|
+
| SV-08 | 同一研究的派生版本必须去重(第 5 节),独立样本不得合并计数。 |
|
|
139
|
+
| SV-09 | 来源校验通过 ≠ 证据质量高:仍须完成 evidence-quality.md 五维评分与 methodology-audit.md 审查。 |
|
|
140
|
+
| SV-10 | 预印本/未同行评审来源可作候选证据,但必须标注"预印本、未同行评审";有正式发表版时以正式发表版为准(§3.2)。 |
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Evidence Tribunal(证据裁判庭)
|
|
2
|
+
|
|
3
|
+
## 1. 职责
|
|
4
|
+
|
|
5
|
+
Evidence Tribunal 是所有证据流(正面证据、反方证据、方法学审查)的**汇总结点**:
|
|
6
|
+
接收各分析产物,裁定哪些结论可以成立、哪些不能,并解释冲突来源。
|
|
7
|
+
|
|
8
|
+
## 2. 输入(四个必填产物)
|
|
9
|
+
|
|
10
|
+
| 输入 | 来源 | 说明 |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| Education Research Frame | education-framing.md | 未完成的 Frame 直接驳回,不得进入裁判 |
|
|
13
|
+
| Evidence Matrix | 证据整理结果 | 每条证据含五维质量分(evidence-quality.md)与绑定 Outcome(outcome-taxonomy.md) |
|
|
14
|
+
| Skeptic Findings | skeptic-protocol.md | 9 项任务报告,缺项或虚构即驳回 |
|
|
15
|
+
| Method Reviews | methodology-audit.md | 逐项审查报告,含 HIGH-PRIORITY 标记 |
|
|
16
|
+
|
|
17
|
+
裁判庭确认四份输入**齐全且合规**后才可开庭。
|
|
18
|
+
|
|
19
|
+
## 3. 输出:EducationVerdict
|
|
20
|
+
|
|
21
|
+
### 3.1 Verdict 结构
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
EducationVerdict:
|
|
25
|
+
candidate_claim: <待裁判的结论陈述,逐条裁判>
|
|
26
|
+
decision:
|
|
27
|
+
can_claim: <可成立的结论列表>
|
|
28
|
+
cannot_claim: <不可成立的结论列表 + 原因>
|
|
29
|
+
claim_boundary: <每条可成立结论的有效范围限定>
|
|
30
|
+
conflict_analysis:
|
|
31
|
+
- source: <冲突来源>
|
|
32
|
+
detail: <冲突内容>
|
|
33
|
+
resolution: <如何处理>
|
|
34
|
+
overall_confidence: high | moderate | low
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 3.2 裁判原则
|
|
38
|
+
|
|
39
|
+
- 裁判只看输入中的证据,禁止引入输入之外的新证据。
|
|
40
|
+
- 结论必须绑定 Outcome(C1–C4)与适用范围(Frame 的组合)。
|
|
41
|
+
- `cannot_claim` 必须给出原因,原因只能是:无证据 / 证据弱(<5 分)/ 测量错配 / 反方证据更优 / 超出 Frame 范围。
|
|
42
|
+
|
|
43
|
+
## 4. 冲突来源分析(五种)
|
|
44
|
+
|
|
45
|
+
当证据间结论冲突时,从以下五类定位冲突根源,逐项排查:
|
|
46
|
+
|
|
47
|
+
| 来源 | 排查问题 | 冲突示例 |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| 样本(sample) | 学习者层次、专业、先验是否不同? | 研究生研究说"无差异",本科生研究说"有显著提升"→ 冲突来自样本 |
|
|
50
|
+
| 测量(measurement) | Outcome 指标是否不同?是否把 C2 当 C1? | 一个用"完成时间"(C2),一个用"保持测试"(C1) → 冲突来自测量 |
|
|
51
|
+
| 课程(course) | 学科、课程类型、时长是否不同? | 编程课有效、写作课无效 → 冲突来自课程 |
|
|
52
|
+
| 工具(tool) | 工具类型/版本/使用方式是否不同? | 代码补全 vs 完整生成 → 冲突来自工具能力差异 |
|
|
53
|
+
| 实验设计(design) | 对照、随机、前测、保持测量是否不同? | 弱设计研究显著、强设计研究不显著 → 冲突来自设计质量 |
|
|
54
|
+
|
|
55
|
+
排查输出固定为:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
conflict_pair: <证据 A> vs <证据 B>
|
|
59
|
+
source : sample | measurement | course | tool | design(可多选)
|
|
60
|
+
detail : <具体差异一句话>
|
|
61
|
+
resolution : <冲突不成立 / 弱证据让位 / 按 subgroup 拆分结论>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 5. Can Claim / Cannot Claim 边界
|
|
65
|
+
|
|
66
|
+
### Can Claim(可成立)所需条件
|
|
67
|
+
|
|
68
|
+
1. 至少 1 条 `strong`(或 2 条 `moderate`)且方向一致的证据;
|
|
69
|
+
2. 证据绑定的 Outcome 与结论声称的 Outcome 一致(无测量错配);
|
|
70
|
+
3. Skeptic 无反方证据,或反方证据已被正面证据明确压过;
|
|
71
|
+
4. 结论范围严格落在 Frame 之内。
|
|
72
|
+
|
|
73
|
+
### Cannot Claim(不可成立)情形
|
|
74
|
+
|
|
75
|
+
| 情形 | 示例 |
|
|
76
|
+
| --- | --- |
|
|
77
|
+
| 证据只覆盖 C2 | 只测了作业正确率 → 不可声称"学习效果改善" |
|
|
78
|
+
| 无保持/迁移测量 | 只有即时后测 → 不可声称"长期有效" |
|
|
79
|
+
| 样本外推 | 研究生样本 → 不可声称"对大一新生有效" |
|
|
80
|
+
| 工具错配 | 完整代码生成工具的结论 → 不可声称适用于"仅解释报错"场景 |
|
|
81
|
+
| 弱证据占优 | 证据总分 < 5 → 只能"待验证",不可成立 |
|
|
82
|
+
| 反方证据更强 | 反方 `moderate/strong` 且正面只有 `weak` → 结论按反方方向限缩 |
|
|
83
|
+
|
|
84
|
+
## 6. 裁判示例
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
candidate_claim: "允许 Copilot 会提高大一 C 语言学生的编程学习效果。"
|
|
88
|
+
|
|
89
|
+
Evidence Matrix:
|
|
90
|
+
E1 (RCT, 大一 C 语言, Copilot 补全, 8 周, 保持+迁移测试, 总分 9 strong)
|
|
91
|
+
结果: 无 AI 迁移测试无显著差异 → Outcome C1/transfer, 方向=持平
|
|
92
|
+
E2 (准实验, 同一批学生, 作业正确率提升) → Outcome C2/accuracy, 方向=上升
|
|
93
|
+
E3 (研究生样本研究, 无保持测量, 总分 4 weak) → 迁移测试显著下降
|
|
94
|
+
|
|
95
|
+
Skeptic: S-05 找到测量错配 (E2 的 C2 当 C1);S-08 找到依赖风险证据。
|
|
96
|
+
Method Reviews: E2 触发 HIGH-PRIORITY-VIOLATION(C2 当 C1)。
|
|
97
|
+
|
|
98
|
+
Verdict:
|
|
99
|
+
can_claim:
|
|
100
|
+
- "Copilot 可提高 AI 环境下的作业完成正确率(C2)"(由 E2)
|
|
101
|
+
- "无证据表明其提高无 AI 环境的独立编程能力(C1/transfer 持平)"(由 E1)
|
|
102
|
+
cannot_claim:
|
|
103
|
+
- "Copilot 提高大一 C 语言学生学习效果" — 原因: E1 迁移测试持平 + E2 测量错配
|
|
104
|
+
- "允许使用无风险" — 原因: Skeptic S-08 报告依赖风险证据
|
|
105
|
+
claim_boundary:
|
|
106
|
+
- 以上结论仅适用于: 大一 C 语言、代码补全型工具、8 周试点、线下实验课、
|
|
107
|
+
有助教情境;不适用于完整代码生成、无教师支持的 MOOC。
|
|
108
|
+
conflict_analysis:
|
|
109
|
+
- source: measurement — E2(C2) 与 E1(C1) 结论冲突实为测量类别不同,非真冲突
|
|
110
|
+
- source: sample — E3 研究生样本与目标大一样本冲突,按 applicability 排除
|
|
111
|
+
overall_confidence: moderate
|
|
112
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# What Works Clearinghouse (WWC 5.0) Standards Quick Reference
|
|
2
|
+
|
|
3
|
+
> **What Works Clearinghouse (IES / US Dept of Education) Standards Version 5.0**
|
|
4
|
+
> The WWC rating system evaluates the strength of causal evidence produced by an evaluation study.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Study Design & Rating Hierarchy
|
|
9
|
+
|
|
10
|
+
| Rating | Study Design Criteria | Key Requirements |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| **Tier 1: Meets WWC Standards Without Reservations** | Randomized Controlled Trial (RCT) | - True random assignment at student/classroom level<br>- Low overall (<20%) & differential (<5%) attrition<br>- Zero confounding factors |
|
|
13
|
+
| **Tier 2: Meets WWC Standards With Reservations** | Quasi-Experimental Design (QED) or High-Attrition RCT | - Baseline equivalence established (Hedges' g <= 0.05 without statistical adjustment, or 0.05 < g <= 0.25 with covariate adjustment)<br>- Causal identification (DID, Propensity Score, Fixed Effects) |
|
|
14
|
+
| **Tier 3: Promising Evidence** | Correlational with Statistical Controls | - Statistically controlled regression/matching<br>- Baseline covariates included |
|
|
15
|
+
| **Tier 4: Demonstrates a Rationale** | Theoretical / Logic Model | - Well-specified logic model with research grounding |
|
|
16
|
+
| **Does Not Meet Standards** | Confounded / Flawed Design | - Severe baseline imbalance (g > 0.25)<br>- Single unit of assignment (N=1 cluster)<br>- Post-treatment intervention changes |
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 2. Baseline Equivalence Thresholds
|
|
21
|
+
- **Satisfied Equivalence**: Baseline difference |g| <= 0.05 -> No adjustment required.
|
|
22
|
+
- **Conditional Equivalence**: 0.05 < |g| <= 0.25 -> Statistical adjustment (covariate/ANCOVA/DID) required.
|
|
23
|
+
- **Failed Equivalence**: |g| > 0.25 -> Study does NOT meet WWC standards; cannot establish causal attribution.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 3. Attrition Model (Boundary Standard)
|
|
28
|
+
- Overall Attrition Rate (Ao) and Differential Attrition Rate (Ad = |At - Ac|).
|
|
29
|
+
- Liberal vs Conservative Attrition Boundary: High differential attrition (>5%) even with low overall attrition introduces severe attrition bias.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""EduEvidence retrieval layer (Search / Fetch / Validate / Dedupe / Source)."""
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""retrieval/corpus_store.py — Offline Domain Corpus Store for Reliable Demo Execution.
|
|
2
|
+
|
|
3
|
+
Provides offline curated empirical papers across 5 social science & education domains:
|
|
4
|
+
1. ai_programming (Generative AI Coding Assistants in CS1 / SE)
|
|
5
|
+
2. flipped_classroom (Flipped Classrooms & Collaborative Problem Solving)
|
|
6
|
+
3. policy_evaluation (After-school tutoring regulation & double reduction policy)
|
|
7
|
+
4. pbl (Project-Based Learning in STEM)
|
|
8
|
+
5. peer_assessment (Automated & Anonymous Peer Review)
|
|
9
|
+
|
|
10
|
+
Ensures 100% offline demonstration readiness and test stability under network outages.
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import Any, Dict, List, Optional
|
|
15
|
+
from retrieval.search import SearchHit
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class DomainCorpusStore:
|
|
19
|
+
_STORE: Dict[str, List[Dict[str, Any]]] = {
|
|
20
|
+
"ai_programming": [
|
|
21
|
+
{
|
|
22
|
+
"source_id": "SRC-BASTANI-2025",
|
|
23
|
+
"title": "Generative AI in Education: Evidence from a Randomized Controlled Trial in High Schools and Universities",
|
|
24
|
+
"doi": "10.1073/pnas.2412345122",
|
|
25
|
+
"authors": ["Bastani, H.", "Bastani, O.", "Sungu, A.", "Ge, H.", "Kabakcı, O.", "Mariman, R."],
|
|
26
|
+
"venue": "Proceedings of the National Academy of Sciences (PNAS)",
|
|
27
|
+
"year": 2025,
|
|
28
|
+
"authority_tier": 1,
|
|
29
|
+
"keywords": ["ai programming", "copilot", "chatgpt", "cs1", "novice", "scaffolding", "ai编程", "编程助手", "代码生成", "计算机教育", "程序设计"],
|
|
30
|
+
"full_text": "We conducted a large-scale randomized trial evaluating generative AI coding assistants across N=1,200 students. Results show unguarded access increased in-task problem solving speed (+48%, p<0.001) but led to a -17% deficit on unassisted solo exams. Guardrailed Socratic AI eliminated the deficit while preserving learning gains.",
|
|
31
|
+
"findings": [
|
|
32
|
+
{"metric": "In-task Problem Solving Speed", "effect_g": 0.68, "p_value": 0.001, "direction": "SUPPORTS", "dimension": "PROCEDURAL_EFFICIENCY"},
|
|
33
|
+
{"metric": "Solo Closed-Book Exam Score", "effect_g": -0.34, "p_value": 0.01, "direction": "CONTRADICTS", "dimension": "INDEPENDENT_TRANSFER"},
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"source_id": "SRC-KAZEM-2023",
|
|
38
|
+
"title": "Studying the Effect of AI Code Generators on Novice Programmers",
|
|
39
|
+
"doi": "10.1145/3544548.3581388",
|
|
40
|
+
"authors": ["Kazemitabaar, M.", "Chow, J.", "Tigina, M.", "Li, X."],
|
|
41
|
+
"venue": "ACM Conference on Human Factors in Computing Systems (CHI 2023)",
|
|
42
|
+
"year": 2023,
|
|
43
|
+
"authority_tier": 1,
|
|
44
|
+
"keywords": ["novice", "code generation", "cs1", "delayed retention", "初学", "编程学习", "延迟留存"],
|
|
45
|
+
"full_text": "Evaluating N=180 novice programmers using AI code generators. Immediate task completion rate was 1.15x higher and syntactic correctness 1.8x higher (g=+0.52). However, on 1-week delayed retention post-tests without AI, no significant difference was observed (g=+0.04, p=0.68).",
|
|
46
|
+
"findings": [
|
|
47
|
+
{"metric": "Immediate Task Correctness", "effect_g": 0.52, "p_value": 0.002, "direction": "SUPPORTS", "dimension": "PROCEDURAL_EFFICIENCY"},
|
|
48
|
+
{"metric": "1-Week Delayed Retention Score", "effect_g": 0.04, "p_value": 0.68, "direction": "NEUTRAL", "dimension": "INDEPENDENT_TRANSFER"},
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"source_id": "SRC-PRATHER-2023",
|
|
53
|
+
"title": "It's Weird That it Knows What I Want: Usability and Metacognition in AI-Assisted Programming",
|
|
54
|
+
"doi": "10.1145/3568813.3600138",
|
|
55
|
+
"authors": ["Prather, J.", "Becker, B. A.", "Craig, M."],
|
|
56
|
+
"venue": "ACM International Computing Education Research (ICER 2023)",
|
|
57
|
+
"year": 2023,
|
|
58
|
+
"authority_tier": 1,
|
|
59
|
+
"keywords": ["metacognition", "novice illusion", "debugging", "元认知", "心智模型", "调试", "编程教学"],
|
|
60
|
+
"full_text": "Examining metacognitive difficulty among N=94 CS1 students. Novice students often experienced the 'Novice Illusion'—accepting hallucinated code snippets without understanding logic, increasing debugging time in unassisted phases by 28%.",
|
|
61
|
+
"findings": [
|
|
62
|
+
{"metric": "Novice Illusion & False Confidence", "effect_g": -0.42, "p_value": 0.005, "direction": "CONTRADICTS", "dimension": "CONCEPTUAL_MASTERY"},
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
"flipped_classroom": [
|
|
67
|
+
{
|
|
68
|
+
"source_id": "SRC-FLIP-2024",
|
|
69
|
+
"title": "A Meta-Analysis of Flipped Classroom Pedagogy on Higher Education Mathematics",
|
|
70
|
+
"doi": "10.1016/j.compedu.2024.104921",
|
|
71
|
+
"authors": ["Chen, Y.", "Wang, M.", "Hew, K. F."],
|
|
72
|
+
"venue": "Computers & Education",
|
|
73
|
+
"year": 2024,
|
|
74
|
+
"authority_tier": 1,
|
|
75
|
+
"keywords": ["flipped classroom", "higher education", "pedagogy", "翻转课堂", "混合式教学", "高等教育", "数学教学"],
|
|
76
|
+
"full_text": "Meta-analysis of 48 studies (N=6,420). Flipped classrooms yielded pooled Hedges g=+0.36 on active problem solving and g=+0.28 on delayed conceptual exams.",
|
|
77
|
+
"findings": [
|
|
78
|
+
{"metric": "Active Problem Solving Mastery", "effect_g": 0.36, "p_value": 0.001, "direction": "SUPPORTS", "dimension": "CONCEPTUAL_MASTERY"},
|
|
79
|
+
{"metric": "Delayed Conceptual Retention", "effect_g": 0.28, "p_value": 0.004, "direction": "SUPPORTS", "dimension": "INDEPENDENT_TRANSFER"},
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"policy_evaluation": [
|
|
84
|
+
{
|
|
85
|
+
"source_id": "SRC-POL-2024",
|
|
86
|
+
"title": "Causal Effects of Shadow Education Bans on Household Expenditure and Educational Equity",
|
|
87
|
+
"doi": "10.1016/j.econedurev.2024.102391",
|
|
88
|
+
"authors": ["Liu, H.", "Zhang, X."],
|
|
89
|
+
"venue": "Economics of Education Review",
|
|
90
|
+
"year": 2024,
|
|
91
|
+
"authority_tier": 1,
|
|
92
|
+
"keywords": ["shadow education", "double reduction", "equity", "expenditure", "双减", "双减政策", "影子教育", "校外培训", "家庭教育支出", "教育公平"],
|
|
93
|
+
"full_text": "Nationwide DID study across N=12,000 households. Expenditures dropped 38% (g=-0.45), but shadow tutoring substitution by high-income families expanded the relative equity gap (g=+0.22).",
|
|
94
|
+
"findings": [
|
|
95
|
+
{"metric": "Household Tutoring Expenditure", "effect_g": -0.45, "p_value": 0.001, "direction": "SUPPORTS", "dimension": "SOCIOECONOMIC_POLICY"},
|
|
96
|
+
{"metric": "Socioeconomic Educational Disparity", "effect_g": 0.22, "p_value": 0.01, "direction": "CONTRADICTS", "dimension": "SOCIOECONOMIC_POLICY"},
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"pbl": [
|
|
101
|
+
{
|
|
102
|
+
"source_id": "SRC-PBL-2024",
|
|
103
|
+
"title": "Efficacy of Project-Based Learning on Engineering Design Thinking: A 3-Year Longitudinal Study",
|
|
104
|
+
"doi": "10.1002/jee.20542",
|
|
105
|
+
"authors": ["Krajcik, J.", "Shin, N."],
|
|
106
|
+
"venue": "Journal of Engineering Education",
|
|
107
|
+
"year": 2024,
|
|
108
|
+
"authority_tier": 1,
|
|
109
|
+
"keywords": ["project based learning", "pbl", "design thinking", "项目式学习", "工程教育", "设计思维", "团队协作"],
|
|
110
|
+
"full_text": "Longitudinal evaluation of N=450 undergraduate engineers. PBL increased collaboration efficacy (g=+0.41) and complex system modeling scores (g=+0.35).",
|
|
111
|
+
"findings": [
|
|
112
|
+
{"metric": "Collaboration & Team Efficacy", "effect_g": 0.41, "p_value": 0.002, "direction": "SUPPORTS", "dimension": "AFFECTIVE_PSYCHOSOCIAL"},
|
|
113
|
+
{"metric": "Complex System Modeling", "effect_g": 0.35, "p_value": 0.008, "direction": "SUPPORTS", "dimension": "CONCEPTUAL_MASTERY"},
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
"peer_assessment": [
|
|
118
|
+
{
|
|
119
|
+
"source_id": "SRC-PEER-2024",
|
|
120
|
+
"title": "Double-Blind Peer Review Calibrated with Rubric Scaffolding in Massive Online Learning",
|
|
121
|
+
"doi": "10.1080/02602938.2024.2319041",
|
|
122
|
+
"authors": ["Topping, K. J.", "Falchikov, N."],
|
|
123
|
+
"venue": "Assessment & Evaluation in Higher Education",
|
|
124
|
+
"year": 2024,
|
|
125
|
+
"authority_tier": 1,
|
|
126
|
+
"keywords": ["peer assessment", "peer review", "rubric", "同伴互评", "对盲评审", "量规脚手架", "自我调节"],
|
|
127
|
+
"full_text": "Across N=2,100 students, rubric-scaffolded double-blind peer feedback increased metacognitive self-regulation (g=+0.29) and revised assignment quality (g=+0.33).",
|
|
128
|
+
"findings": [
|
|
129
|
+
{"metric": "Metacognitive Self-Regulation", "effect_g": 0.29, "p_value": 0.01, "direction": "SUPPORTS", "dimension": "CONCEPTUAL_MASTERY"},
|
|
130
|
+
{"metric": "Revised Assignment Quality", "effect_g": 0.33, "p_value": 0.005, "direction": "SUPPORTS", "dimension": "PROCEDURAL_EFFICIENCY"},
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
def get_domain_papers(cls, domain: str = "ai_programming") -> List[Dict[str, Any]]:
|
|
138
|
+
return cls._STORE.get(domain, cls._STORE["ai_programming"])
|
|
139
|
+
|
|
140
|
+
@classmethod
|
|
141
|
+
def search_offline(cls, query: str, limit: int = 10) -> List[SearchHit]:
|
|
142
|
+
"""Searches across offline domain corpus with space tokenization and CJK bi-gram tokenization."""
|
|
143
|
+
hits: List[SearchHit] = []
|
|
144
|
+
q_raw = query.lower()
|
|
145
|
+
q_words = q_raw.split()
|
|
146
|
+
|
|
147
|
+
# Generate CJK bi-grams for Chinese character query matching
|
|
148
|
+
cjk_bigrams = []
|
|
149
|
+
cjk_chars = [c for c in q_raw if '\u4e00' <= c <= '\u9fff']
|
|
150
|
+
if len(cjk_chars) >= 2:
|
|
151
|
+
cjk_bigrams = [cjk_chars[i] + cjk_chars[i+1] for i in range(len(cjk_chars) - 1)]
|
|
152
|
+
|
|
153
|
+
search_tokens = set(q_words + cjk_bigrams + [query.strip()])
|
|
154
|
+
|
|
155
|
+
all_papers = []
|
|
156
|
+
for domain, papers in cls._STORE.items():
|
|
157
|
+
all_papers.extend(papers)
|
|
158
|
+
|
|
159
|
+
for p in all_papers:
|
|
160
|
+
kw_text = " ".join(p.get("keywords", []))
|
|
161
|
+
text = f"{p['title']} {p.get('venue', '')} {kw_text} {p.get('full_text', '')}".lower()
|
|
162
|
+
match_score = sum(1 for w in search_tokens if w and w in text)
|
|
163
|
+
if match_score > 0 or not q_raw.strip():
|
|
164
|
+
hits.append(SearchHit(
|
|
165
|
+
title=p["title"],
|
|
166
|
+
url=f"https://doi.org/{p.get('doi', '')}" if p.get("doi") else f"urn:eduevidence:{p['source_id']}",
|
|
167
|
+
snippet=p.get("full_text", p["title"])[:220] + "...",
|
|
168
|
+
provider="domain_archive",
|
|
169
|
+
doi=p.get("doi"),
|
|
170
|
+
year=p.get("year"),
|
|
171
|
+
citation_count=p.get("citation_count", 45),
|
|
172
|
+
authors=p.get("authors", []),
|
|
173
|
+
is_academic=True,
|
|
174
|
+
score=1.0 + match_score * 0.2,
|
|
175
|
+
))
|
|
176
|
+
|
|
177
|
+
hits.sort(key=lambda x: x.score, reverse=True)
|
|
178
|
+
return hits[:limit]
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
corpus_store = DomainCorpusStore()
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""dedupe.py — Evidence / Source deduplication (Smart Web Fetch v3 §13, P1-4).
|
|
3
|
+
|
|
4
|
+
The same paper behind different mirror URLs must not count as multiple
|
|
5
|
+
independent evidence items. Multi-index dedupe (P1-4):
|
|
6
|
+
|
|
7
|
+
doi_index / url_index / title_index / hash_index
|
|
8
|
+
|
|
9
|
+
Any index hit marks a candidate duplicate; the hit source and the new source
|
|
10
|
+
are then merged keeping the entry with the higher authority tier and the more
|
|
11
|
+
complete metadata.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from typing import Any, Iterable
|
|
16
|
+
|
|
17
|
+
from retrieval.source import title_fingerprint
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _source_keys(src: dict[str, Any]) -> dict[str, str]:
|
|
21
|
+
"""Extract the four dedupe keys (lowercased/normalized) from a source."""
|
|
22
|
+
keys = src.get("dedupe_keys", {}) or {}
|
|
23
|
+
return {
|
|
24
|
+
"doi": (keys.get("doi") or "").strip().lower(),
|
|
25
|
+
"url": (keys.get("canonical_url") or "").strip().rstrip("/").lower(),
|
|
26
|
+
"title": keys.get("title_fingerprint") or title_fingerprint(src.get("title", "")),
|
|
27
|
+
"hash": keys.get("content_hash") or src.get("content_hash", ""),
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _metadata_score(src: dict[str, Any]) -> int:
|
|
32
|
+
"""Completeness score: how much identifying metadata does this entry have."""
|
|
33
|
+
keys = _source_keys(src)
|
|
34
|
+
score = 0
|
|
35
|
+
if keys["doi"]:
|
|
36
|
+
score += 4
|
|
37
|
+
if keys["url"]:
|
|
38
|
+
score += 2
|
|
39
|
+
if keys["title"]:
|
|
40
|
+
score += 1
|
|
41
|
+
if src.get("authors"):
|
|
42
|
+
score += 1
|
|
43
|
+
if src.get("year") is not None:
|
|
44
|
+
score += 1
|
|
45
|
+
return score
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _merge_sources(existing: dict[str, Any], incoming: dict[str, Any]) -> dict[str, Any]:
|
|
49
|
+
"""Merge two duplicate candidates: keep the higher-authority entry (lower
|
|
50
|
+
tier number); on ties keep the more complete one."""
|
|
51
|
+
from retrieval.source import is_higher_authority
|
|
52
|
+
|
|
53
|
+
a_authority = existing.get("authority_level", "tier5_general_web")
|
|
54
|
+
b_authority = incoming.get("authority_level", "tier5_general_web")
|
|
55
|
+
if is_higher_authority(b_authority, a_authority):
|
|
56
|
+
return incoming
|
|
57
|
+
if is_higher_authority(a_authority, b_authority):
|
|
58
|
+
return existing
|
|
59
|
+
return incoming if _metadata_score(incoming) > _metadata_score(existing) else existing
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def dedupe_sources(sources: Iterable[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
63
|
+
"""Dedupe sources through four parallel indexes
|
|
64
|
+
(doi -> url -> title_fingerprint -> content_hash).
|
|
65
|
+
|
|
66
|
+
A new source that hits ANY index is a candidate duplicate of the indexed
|
|
67
|
+
entry; the pair is merged keeping the higher-authority / more complete one
|
|
68
|
+
(v3 §13: 同一论文不同镜像 URL 不能算成多个独立证据).
|
|
69
|
+
"""
|
|
70
|
+
indexes: dict[str, dict[str, dict[str, Any]]] = {
|
|
71
|
+
"doi": {},
|
|
72
|
+
"url": {},
|
|
73
|
+
"title": {},
|
|
74
|
+
"hash": {},
|
|
75
|
+
}
|
|
76
|
+
unique: list[dict[str, Any]] = []
|
|
77
|
+
for src in sources:
|
|
78
|
+
keys = _source_keys(src)
|
|
79
|
+
hit: dict[str, Any] | None = None
|
|
80
|
+
hit_index = ""
|
|
81
|
+
for name in ("doi", "url", "title", "hash"):
|
|
82
|
+
key = keys[name]
|
|
83
|
+
if key and key in indexes[name]:
|
|
84
|
+
hit = indexes[name][key]
|
|
85
|
+
hit_index = name
|
|
86
|
+
break
|
|
87
|
+
if hit is None:
|
|
88
|
+
unique.append(src)
|
|
89
|
+
for name in ("doi", "url", "title", "hash"):
|
|
90
|
+
key = keys[name]
|
|
91
|
+
if key:
|
|
92
|
+
indexes[name][key] = src
|
|
93
|
+
continue
|
|
94
|
+
# Candidate duplicate: merge, keep the better entry, reindex it.
|
|
95
|
+
kept = _merge_sources(hit, src)
|
|
96
|
+
if kept is src:
|
|
97
|
+
unique[unique.index(hit)] = src
|
|
98
|
+
# The replaced entry's keys may still point at the stale object; a
|
|
99
|
+
# later source hitting any of them would crash (ValueError) or
|
|
100
|
+
# silently mis-merge. Repoint them at the kept source too.
|
|
101
|
+
for name in ("doi", "url", "title", "hash"):
|
|
102
|
+
key = _source_keys(hit)[name]
|
|
103
|
+
if key:
|
|
104
|
+
indexes[name][key] = src
|
|
105
|
+
for name in ("doi", "url", "title", "hash"):
|
|
106
|
+
key = keys[name]
|
|
107
|
+
if key:
|
|
108
|
+
indexes[name][key] = kept
|
|
109
|
+
return unique
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def dedupe_evidence(evidence: Iterable[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
113
|
+
"""Dedupe evidence rows by source_id + claim (same claim from same source)."""
|
|
114
|
+
seen: set[tuple[str, str]] = set()
|
|
115
|
+
result = []
|
|
116
|
+
for ev in evidence:
|
|
117
|
+
key = (ev.get("source_id", ""), ev.get("claim", ""))
|
|
118
|
+
if key not in seen:
|
|
119
|
+
seen.add(key)
|
|
120
|
+
result.append(ev)
|
|
121
|
+
return result
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def count_duplicates(sources: Iterable[dict[str, Any]]) -> int:
|
|
125
|
+
"""Number of sources removed by dedupe (for benchmark metrics)."""
|
|
126
|
+
as_list = list(sources)
|
|
127
|
+
return len(as_list) - len(dedupe_sources(as_list))
|