eduevidence 6.0.0 → 6.3.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.
Files changed (267) hide show
  1. package/CHANGELOG.md +395 -0
  2. package/CONTRIBUTING.md +105 -0
  3. package/README.md +113 -49
  4. package/README.zh-CN.md +39 -12
  5. package/SKILL.md +15 -5
  6. package/assets/readme/landing-tour.gif +0 -0
  7. package/assets/readme/studio-tour.gif +0 -0
  8. package/benchmarks/evidence-library.json +277 -1
  9. package/bin/eduevidence.js +2 -1
  10. package/docs/architecture.md +325 -46
  11. package/docs/demo-workplace-ai.md +1 -1
  12. package/docs/install-guide.md +1 -1
  13. package/docs/j-ev-experimental.md +250 -0
  14. package/docs/orchestration-role-model.md +1 -1
  15. package/docs/release-closeout/README.md +1 -1
  16. package/docs/reproducibility.md +138 -0
  17. package/docs/sciverse-api.md +125 -0
  18. package/domains/_neutral/copy/few_shots.json +21 -0
  19. package/domains/_neutral/copy/framing_lexicon.json +19 -0
  20. package/domains/_neutral/copy/module_labels.json +5 -0
  21. package/domains/_neutral/copy/module_labels_footer.json +102 -0
  22. package/domains/_neutral/copy/module_labels_modules.json +204 -0
  23. package/domains/_neutral/copy/module_labels_nav.json +126 -0
  24. package/domains/_neutral/copy/module_labels_summary.json +98 -0
  25. package/domains/_neutral/copy/module_labels_tables.json +164 -0
  26. package/domains/_neutral/copy/module_labels_v2.json +90 -0
  27. package/domains/_neutral/copy/risk_constructs.json +20 -0
  28. package/domains/_neutral/copy/section_titles.json +66 -0
  29. package/domains/_neutral/copy/terminology.json +11 -0
  30. package/domains/check_copy_packs.py +103 -0
  31. package/domains/education/copy/few_shots.json +22 -0
  32. package/domains/education/copy/framing_enums.json +167 -0
  33. package/domains/education/copy/framing_lexicon.json +166 -0
  34. package/domains/education/copy/module_labels.json +169 -0
  35. package/domains/education/copy/risk_constructs.json +48 -0
  36. package/domains/education/copy/section_titles.json +186 -0
  37. package/domains/education/copy/terminology.json +70 -0
  38. package/domains/education/manifest.json +1 -1
  39. package/domains/education/outcome_taxonomy.json +2 -2
  40. package/domains/manifest.json +1 -1
  41. package/domains/policy/copy/few_shots.json +22 -0
  42. package/domains/policy/copy/framing_enums.json +94 -0
  43. package/domains/policy/copy/framing_lexicon.json +174 -0
  44. package/domains/policy/copy/module_labels.json +168 -0
  45. package/domains/policy/copy/risk_constructs.json +33 -0
  46. package/domains/policy/copy/section_titles.json +186 -0
  47. package/domains/policy/copy/terminology.json +64 -0
  48. package/eduevidence_cli.py +10 -0
  49. package/engine/capabilities.py +57 -5
  50. package/engine/decision_policy.py +167 -0
  51. package/engine/evidence_graph.py +14 -10
  52. package/engine/gaps.py +42 -22
  53. package/engine/ids.py +2 -0
  54. package/engine/library.py +6 -2
  55. package/engine/library_builtin.py +7 -4
  56. package/engine/living.py +34 -4
  57. package/engine/migration.py +88 -3
  58. package/engine/orchestration.py +5 -5
  59. package/engine/paths.py +2 -0
  60. package/engine/pilot.py +34 -32
  61. package/engine/taxonomy.py +211 -0
  62. package/engine/tribunal.py +49 -43
  63. package/engine/versions.py +1 -1
  64. package/examples/ai-coding-assistant-evidence/EduEvidence_Report.html +1361 -147
  65. package/examples/ai-coding-assistant-evidence/artifact_manifest.json +3 -3
  66. package/examples/ai-coding-assistant-evidence/citation_check.json +1 -1
  67. package/examples/ai-coding-assistant-evidence/final_verdict.json +107 -0
  68. package/examples/ai-coding-assistant-evidence/gate_report.json +101 -0
  69. package/examples/ai-coding-assistant-evidence/report_spec.json +23 -12
  70. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_academic.html +448 -128
  71. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_claude.html +448 -128
  72. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_datalab-dark.html +448 -128
  73. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_datalab.html +448 -128
  74. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_presentation.html +448 -128
  75. package/examples/ai-coding-assistant-evidence/reports-5themes/report_academic.html +1360 -146
  76. package/examples/ai-coding-assistant-evidence/reports-5themes/report_claude.html +1360 -146
  77. package/examples/ai-coding-assistant-evidence/reports-5themes/report_datalab-dark.html +1360 -146
  78. package/examples/ai-coding-assistant-evidence/reports-5themes/report_datalab.html +1360 -146
  79. package/examples/ai-coding-assistant-evidence/reports-5themes/report_presentation.html +1360 -146
  80. package/examples/ai-coding-assistant-evidence/result.json +13 -9
  81. package/examples/ai-coding-assistant-evidence/result.zh.json +45 -41
  82. package/examples/ai-coding-assistant-evidence/skeptic.json +72 -0
  83. package/examples/ai-coding-assistant-evidence/verdict.json +6 -2
  84. package/examples/spaced-retrieval-practice/EduEvidence_Report.html +2728 -0
  85. package/examples/spaced-retrieval-practice/applicability.json +14 -0
  86. package/examples/spaced-retrieval-practice/artifact_manifest.json +15 -0
  87. package/examples/spaced-retrieval-practice/claims.jsonl +3 -0
  88. package/examples/spaced-retrieval-practice/evidence.jsonl +6 -0
  89. package/examples/spaced-retrieval-practice/final_verdict.json +93 -0
  90. package/examples/spaced-retrieval-practice/frame.json +58 -0
  91. package/examples/spaced-retrieval-practice/gate_report.json +101 -0
  92. package/examples/spaced-retrieval-practice/methodology.json +78 -0
  93. package/examples/spaced-retrieval-practice/report.html +2522 -0
  94. package/examples/spaced-retrieval-practice/report_spec.json +212 -0
  95. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_academic.html +2728 -0
  96. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_claude.html +2728 -0
  97. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_datalab-dark.html +2728 -0
  98. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_datalab.html +2728 -0
  99. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_presentation.html +2728 -0
  100. package/examples/spaced-retrieval-practice/reports-5themes/report_academic.html +2728 -0
  101. package/examples/spaced-retrieval-practice/reports-5themes/report_claude.html +2728 -0
  102. package/examples/spaced-retrieval-practice/reports-5themes/report_datalab-dark.html +2728 -0
  103. package/examples/spaced-retrieval-practice/reports-5themes/report_datalab.html +2728 -0
  104. package/examples/spaced-retrieval-practice/reports-5themes/report_presentation.html +2728 -0
  105. package/examples/spaced-retrieval-practice/result.json +942 -0
  106. package/examples/spaced-retrieval-practice/result.zh.json +942 -0
  107. package/examples/spaced-retrieval-practice/skeptic.json +70 -0
  108. package/examples/spaced-retrieval-practice/sources.jsonl +7 -0
  109. package/examples/spaced-retrieval-practice/verdict.json +93 -0
  110. package/examples/workplace-ai-assistant/EduEvidence_Report.html +2814 -0
  111. package/examples/workplace-ai-assistant/artifact_manifest.json +15 -0
  112. package/examples/workplace-ai-assistant/claims.jsonl +4 -4
  113. package/examples/workplace-ai-assistant/evidence.jsonl +4 -4
  114. package/examples/workplace-ai-assistant/evidence_graph.json +15 -15
  115. package/examples/workplace-ai-assistant/final_verdict.json +78 -0
  116. package/examples/workplace-ai-assistant/gate_report.json +101 -0
  117. package/examples/workplace-ai-assistant/report_spec.json +209 -40
  118. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_academic.html +449 -119
  119. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_claude.html +449 -119
  120. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_datalab-dark.html +449 -119
  121. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_datalab.html +449 -119
  122. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_presentation.html +449 -119
  123. package/examples/workplace-ai-assistant/reports-5themes/report_academic.html +2814 -0
  124. package/examples/workplace-ai-assistant/reports-5themes/report_claude.html +2814 -0
  125. package/examples/workplace-ai-assistant/reports-5themes/report_datalab-dark.html +2814 -0
  126. package/examples/workplace-ai-assistant/reports-5themes/report_datalab.html +2814 -0
  127. package/examples/workplace-ai-assistant/reports-5themes/report_presentation.html +2814 -0
  128. package/examples/workplace-ai-assistant/result.json +82 -20
  129. package/examples/workplace-ai-assistant/result.zh.json +82 -20
  130. package/examples/workplace-ai-assistant/skeptic.json +72 -0
  131. package/examples/workplace-ai-assistant/verdict.json +36 -10
  132. package/integrations/agent_mcp.py +2 -2
  133. package/integrations/jev/__init__.py +115 -0
  134. package/integrations/jev/approval.py +212 -0
  135. package/integrations/jev/cli.py +84 -0
  136. package/integrations/jev/config.py +112 -0
  137. package/integrations/jev/gateway.py +128 -0
  138. package/integrations/jev/modes.py +38 -0
  139. package/integrations/jev/tools_classify.py +88 -0
  140. package/integrations/jev/tools_extract.py +111 -0
  141. package/integrations/jev/tools_rerank.py +71 -0
  142. package/integrations/jev/tools_screen.py +87 -0
  143. package/integrations/jev/tools_verify.py +95 -0
  144. package/integrations/jev_mcp.py +22 -0
  145. package/integrations/semantic_decide.py +286 -0
  146. package/integrations/semdecide_cli.py +55 -0
  147. package/package.json +19 -2
  148. package/pyproject.toml +4 -3
  149. package/references/report-copy-style.md +107 -0
  150. package/references/retrieval-compliance.md +75 -0
  151. package/references/retrieval-protocol.md +20 -0
  152. package/retrieval/audit.py +27 -3
  153. package/retrieval/fetch.py +96 -0
  154. package/retrieval/sciverse.py +398 -0
  155. package/retrieval/search.py +47 -7
  156. package/schemas/applicability.schema.json +94 -0
  157. package/schemas/chart-spec.schema.json +10 -3
  158. package/schemas/evidence.schema.json +316 -43
  159. package/schemas/fetch-result.schema.json +2 -1
  160. package/schemas/report-result.schema.json +3 -3
  161. package/schemas/report-spec.schema.json +98 -100
  162. package/schemas/skeptic.schema.json +86 -0
  163. package/schemas/source.schema.json +21 -2
  164. package/schemas/v2/decision-snapshot.schema.json +20 -9
  165. package/schemas/v2/finding.schema.json +5 -1
  166. package/schemas/v2/intake.schema.json +191 -0
  167. package/schemas/v2/methodology-audit.schema.json +5 -1
  168. package/schemas/v2/outcome.schema.json +28 -5
  169. package/schemas/v2/study.schema.json +5 -1
  170. package/schemas/vNext/autoevolve-session.schema.json +34 -1
  171. package/schemas/vNext/eval-snapshot.schema.json +77 -1
  172. package/schemas/vNext/execution-plan.schema.json +50 -1
  173. package/schemas/vNext/gap-priority.schema.json +54 -1
  174. package/schemas/vNext/negative-search-record.schema.json +68 -1
  175. package/schemas/vNext/research-iteration.schema.json +87 -1
  176. package/schemas/vNext/research-strategy.schema.json +62 -1
  177. package/schemas/vNext/skill-experiment.schema.json +90 -1
  178. package/schemas/vNext/task-spec.schema.json +156 -1
  179. package/schemas/vNext/worker-result.schema.json +60 -1
  180. package/schemas/verdict.schema.json +164 -28
  181. package/scripts/build_evidence_library.py +15 -5
  182. package/scripts/build_report_variants.py +18 -2
  183. package/scripts/build_result.py +74 -9
  184. package/scripts/check_package_parity.py +85 -0
  185. package/scripts/check_protocol_alignment.py +375 -0
  186. package/scripts/check_versioned_schemas.py +254 -0
  187. package/scripts/claim_audit.py +13 -8
  188. package/scripts/compute_confidence.py +10 -0
  189. package/scripts/dashboard_server.py +13 -2
  190. package/scripts/did_regression.py +12 -2
  191. package/scripts/evidence_score.py +5 -2
  192. package/scripts/intake/__init__.py +31 -0
  193. package/scripts/intake/__main__.py +18 -0
  194. package/scripts/intake/background.py +78 -0
  195. package/scripts/intake/browser.py +79 -0
  196. package/scripts/intake/cli.py +57 -0
  197. package/scripts/intake/constants.py +57 -0
  198. package/scripts/intake/depth.py +53 -0
  199. package/scripts/intake/enhancements.py +106 -0
  200. package/scripts/intake/hooks.py +90 -0
  201. package/scripts/intake/prefs.py +76 -0
  202. package/scripts/intake/prompts.py +85 -0
  203. package/scripts/intake/session.py +152 -0
  204. package/scripts/lint_file_layers.py +126 -0
  205. package/scripts/orchestrator.py +187 -40
  206. package/scripts/pre_verdict_gate.py +241 -29
  207. package/scripts/quickstart.py +18 -2
  208. package/scripts/run_workspace.py +7 -1
  209. package/scripts/skill_lint.py +11 -1
  210. package/scripts/skill_payload.py +6 -3
  211. package/scripts/test_adversarial_empirical.py +96 -25
  212. package/scripts/validate_schema.py +31 -1
  213. package/skill/agents/evaluation-designer.md +20 -4
  214. package/skill/agents/evidence-analyst.md +19 -3
  215. package/skill/agents/evidence-judge.md +98 -8
  216. package/skill/agents/evidence-retriever.md +20 -3
  217. package/skill/agents/intervention-designer.md +20 -4
  218. package/skill/agents/method-reviewer.md +18 -2
  219. package/skill/agents/{education-planner.md → research-planner.md} +19 -3
  220. package/skill/agents/skeptic.md +18 -2
  221. package/skill/roles/registry.yaml +11 -11
  222. package/skill/sub-skills/aihot-trend-analysis/SKILL.md +28 -9
  223. package/skill/sub-skills/contradiction-analysis/SKILL.md +31 -11
  224. package/skill/sub-skills/data-analysis/SKILL.md +34 -15
  225. package/skill/sub-skills/ethics-review/SKILL.md +33 -10
  226. package/skill/sub-skills/evidence-extraction/SKILL.md +29 -11
  227. package/skill/sub-skills/evidence-review/SKILL.md +31 -12
  228. package/skill/sub-skills/gap-analysis/SKILL.md +31 -9
  229. package/skill/sub-skills/literature-review/SKILL.md +35 -14
  230. package/skill/sub-skills/methodology-audit/SKILL.md +29 -12
  231. package/skill/sub-skills/report-generation/SKILL.md +28 -0
  232. package/skill/sub-skills/research-planning/SKILL.md +41 -14
  233. package/skill/sub-skills/study-design/SKILL.md +30 -9
  234. package/skill/task-briefs/adjudicate.md +32 -7
  235. package/skill/task-briefs/applicability.md +37 -2
  236. package/skill/task-briefs/audit.md +32 -7
  237. package/skill/task-briefs/challenge.md +34 -5
  238. package/skill/task-briefs/evaluate.md +30 -5
  239. package/skill/task-briefs/extract.md +31 -8
  240. package/skill/task-briefs/frame.md +39 -10
  241. package/skill/task-briefs/intervene.md +32 -6
  242. package/skill/task-briefs/present.md +32 -8
  243. package/skill/task-briefs/projection.md +36 -2
  244. package/skill/task-briefs/retrieve.md +36 -6
  245. package/skill/workflows/decision-and-pilot.md +76 -1
  246. package/skill/workflows/evaluate-and-update.md +83 -0
  247. package/skill/workflows/evidence-review.md +104 -0
  248. package/skill/workflows/experimental-jev.md +170 -0
  249. package/skill/workflows/intake.md +120 -0
  250. package/visualization/eduevidence-report/scripts/build_figures.py +25 -3
  251. package/visualization/eduevidence-report/scripts/build_infographics.py +37 -15
  252. package/visualization/eduevidence-report/scripts/build_report.py +435 -575
  253. package/visualization/eduevidence-report/scripts/charts_data.py +2 -0
  254. package/visualization/eduevidence-report/scripts/lieflat_engine.py +349 -38
  255. package/visualization/eduevidence-report/scripts/report_copy_pack.py +296 -0
  256. package/visualization/eduevidence-report/scripts/report_copy_policy_guard.py +47 -0
  257. package/visualization/eduevidence-report/scripts/zh_labels.py +141 -1
  258. package/web/architecture.html +14885 -0
  259. package/web/studio/assets/index-B8tkF44Q.css +1 -0
  260. package/web/studio/index.html +2 -2
  261. package/scripts/build_esl_artifacts.py +0 -1921
  262. package/scripts/build_killer_demo.py +0 -295
  263. package/scripts/enrich_projects_human_and_lieflat.py +0 -315
  264. package/scripts/generate_new_projects.py +0 -686
  265. package/scripts/sync_killer_demo_report.py +0 -270
  266. package/web/studio/assets/index-CzXocaGv.css +0 -1
  267. /package/web/studio/assets/{index-pa7jD7n4.js → index-CQ6Keoyc.js} +0 -0
@@ -1,270 +0,0 @@
1
- """scripts/sync_killer_demo_report.py — Synchronizes the 50-study SSOT EvidenceGraph into result.json and renders EduEvidence_Report.html."""
2
- from __future__ import annotations
3
-
4
- import json
5
- import subprocess
6
- import sys
7
- from pathlib import Path
8
-
9
- ROOT = Path(__file__).resolve().parent.parent
10
- if str(ROOT) not in sys.path:
11
- sys.path.insert(0, str(ROOT))
12
-
13
- from engine.evidence_graph import EvidenceGraph
14
-
15
- def sync_report():
16
- target_dir = ROOT / "examples" / "ai-coding-assistant-50"
17
- target_dir.mkdir(parents=True, exist_ok=True)
18
- graph_file = target_dir / "evidence_graph.json"
19
- result_en_file = target_dir / "result.json"
20
- result_zh_file = target_dir / "result.zh.json"
21
-
22
- if not graph_file.exists():
23
- # Fallback to build_killer_demo
24
- from scripts.build_killer_demo import export_all
25
- export_all()
26
-
27
- graph = EvidenceGraph.from_json(graph_file.read_text(encoding="utf-8"))
28
-
29
- orig_en = ROOT / "examples" / "ai-coding-assistant" / "result.json"
30
- orig_zh = ROOT / "examples" / "ai-coding-assistant" / "result.zh.json"
31
- en_data = json.loads(result_en_file.read_text(encoding="utf-8")) if result_en_file.exists() else (json.loads(orig_en.read_text(encoding="utf-8")) if orig_en.exists() else {})
32
- zh_data = json.loads(result_zh_file.read_text(encoding="utf-8")) if result_zh_file.exists() else (json.loads(orig_zh.read_text(encoding="utf-8")) if orig_zh.exists() else {})
33
-
34
- # 1. Update Sources
35
- sources_en = []
36
- sources_zh = []
37
- for p in graph.papers.values():
38
- s_item = {
39
- "source_id": p.paper_id,
40
- "title": p.title,
41
- "authors": p.authors,
42
- "year": p.year,
43
- "venue": p.venue,
44
- "doi": p.doi,
45
- "canonical_url": p.url or f"https://doi.org/{p.doi}",
46
- "authority_level": f"tier{p.authority_tier}_peer_reviewed",
47
- "source_location": p.url or f"https://doi.org/{p.doi}",
48
- }
49
- sources_en.append(s_item)
50
- sources_zh.append(s_item)
51
-
52
- en_data["sources"] = sources_en
53
- zh_data["sources"] = sources_zh
54
-
55
- # 2. Update Evidence array
56
- ev_list_en = []
57
- ev_list_zh = []
58
-
59
- for ev in graph.evidence.values():
60
- paper = graph.papers.get(ev.paper_id)
61
- val = ev.effect_size.get("value", 0.0)
62
-
63
- # Canonical outcome mapping matching existing outcome taxonomy tokens
64
- if ev.outcome_dimension == "PROCEDURAL_EFFICIENCY":
65
- otype = "completion_time"
66
- otype_zh = "completion_time"
67
- elif ev.outcome_dimension == "INDEPENDENT_TRANSFER":
68
- otype = "independent_problem_solving"
69
- otype_zh = "independent_problem_solving"
70
- elif ev.outcome_dimension == "CONCEPTUAL_MASTERY":
71
- otype = "code_quality"
72
- otype_zh = "code_quality"
73
- else:
74
- otype = "ai_dependency"
75
- otype_zh = "ai_dependency"
76
-
77
- ev_en_item = {
78
- "evidence_id": ev.evidence_id,
79
- "source_id": ev.paper_id,
80
- "title": paper.title if paper else ev.paper_id,
81
- "study_label": f"{paper.authors[0] if paper and paper.authors else ev.paper_id} ({paper.year if paper else 2024})",
82
- "year": paper.year if paper else 2024,
83
- "outcome_type": otype,
84
- "outcome_dimension": ev.outcome_dimension,
85
- "outcome_metric": ev.outcome_metric,
86
- "effect_direction": "positive" if val > 0.10 else ("negative" if val < -0.05 else "null"),
87
- "relation_to_claim": "support" if ev.direction == "SUPPORTS" else ("contradict" if ev.direction == "CONTRADICTS" else "neutral"),
88
- "effect_size": ev.effect_size,
89
- "sample_size": ev.sample_size,
90
- "study_design": ev.study_design,
91
- "quality_score": int(ev.confidence_score * 10),
92
- "wwc_rating": ev.wwc_rating,
93
- "url": paper.url if paper else f"https://doi.org/{ev.paper_id}",
94
- "key_quote": ev.key_quote,
95
- }
96
-
97
- ev_zh_item = dict(ev_en_item)
98
- ev_zh_item["outcome_type"] = otype
99
- ev_zh_item["outcome_metric"] = ev.outcome_metric
100
-
101
- ev_list_en.append(ev_en_item)
102
- ev_list_zh.append(ev_zh_item)
103
-
104
- en_data["evidence"] = ev_list_en
105
- zh_data["evidence"] = ev_list_zh
106
-
107
- # Compute outcomes array dynamically from evidence to pass integrity gate
108
- outcome_buckets: dict[str, dict] = {}
109
- for ev in ev_list_en:
110
- ot = ev["outcome_type"]
111
- if ot not in outcome_buckets:
112
- outcome_buckets[ot] = {
113
- "outcome_type": ot,
114
- "positive_count": 0,
115
- "negative_count": 0,
116
- "null_count": 0,
117
- "evidence_ids": [],
118
- }
119
- edir = ev["effect_direction"]
120
- if edir == "positive":
121
- outcome_buckets[ot]["positive_count"] += 1
122
- elif edir == "negative":
123
- outcome_buckets[ot]["negative_count"] += 1
124
- else:
125
- outcome_buckets[ot]["null_count"] += 1
126
- outcome_buckets[ot]["evidence_ids"].append(ev["evidence_id"])
127
-
128
- en_data["outcomes"] = list(outcome_buckets.values())
129
- zh_data["outcomes"] = list(outcome_buckets.values())
130
-
131
- # 3. Update Claims
132
- claims_en = []
133
- claims_zh = []
134
- for c in graph.claims.values():
135
- c_item_en = {
136
- "claim_id": c.claim_id,
137
- "statement": c.statement,
138
- "status": "supported" if c.status == "SUPPORTED" else ("contradicted" if c.status == "CONTRADICTED" else "uncertain"),
139
- "evidence_ids": c.evidence_ids,
140
- "bias_warning": c.bias_warning,
141
- "pooled_effect_g": c.pooled_effect_g,
142
- }
143
- c_item_zh = dict(c_item_en)
144
- claims_en.append(c_item_en)
145
- claims_zh.append(c_item_zh)
146
-
147
- en_data["claims"] = claims_en
148
- zh_data["claims"] = claims_zh
149
-
150
- # 4. Update Decision with plain-language structured takeaways
151
- en_data["decision"] = {
152
- "verdict": "PILOT",
153
- "recommended_action": "PILOT",
154
- "confidence_score": 0.89,
155
- "confidence": "High",
156
- "strongest_support": "In-task programming completion time is shortened by 35%-50% with significant velocity gain (pooled g = +0.61, p < 0.001) in guided environments.",
157
- "key_uncertainty": "Delayed unassisted solo exams and transfer performance decline significantly (pooled g = -0.28, p = 0.012) once scaffolding is removed.",
158
- "main_risk": "Scaffolding Dependency Trap: Over-reliance on code completion degrades novice debugging, boundary testing, and fundamental computational thinking.",
159
- "next_action": "Execute restricted classroom pilot: ① Enforce Socratic guidance instead of direct code generation; ② Implement 4-phase scaffolding fading; ③ Anchor summative grading in unassisted closed-book exams.",
160
- "what_can_be_claimed": [
161
- "In-task programming completion time is shortened by 35%-50% with significant velocity gain (pooled g = +0.61, p < 0.001) in guided environments."
162
- ],
163
- "uncertain_claims": [
164
- "Delayed unassisted solo exams and transfer performance decline significantly (pooled g = -0.28, p = 0.012) once scaffolding is removed."
165
- ],
166
- "rationale": graph.decision.rationale,
167
- "applicability_boundary": graph.decision.applicability_boundary,
168
- "stop_conditions": graph.decision.stop_conditions,
169
- }
170
- zh_data["decision"] = {
171
- "verdict": "PILOT",
172
- "recommended_action": "PILOT",
173
- "confidence_score": 0.89,
174
- "confidence": "High",
175
- "strongest_support": "即时编程任务编写耗时缩短 35%~50%,代码完成速度显著提升(综合效应量 g = +0.61, p < 0.001),在当堂受控实验中展现明显效率增益。",
176
- "key_uncertainty": "撤除 AI 后的独立闭卷期末考试与概念迁移表现显著下滑(综合效应量 g = -0.28, p = 0.012),学生存在‘看似学会、实则不会’的认知盲区。",
177
- "main_risk": "认知脚手架依赖陷阱(Scaffolding Dependency Trap):过度依赖实时代码补全导致学生自主调试排错、边界测试与底层计算思维出现退化。",
178
- "next_action": "建议开展限制性教学试点:① 采用苏格拉底式概念引导,严禁直接给答案;② 实行 4 阶段脚手架渐进剥离;③ 坚持以无 AI 闭卷机试与独立随访作为最终考核标准。",
179
- "what_can_be_claimed": [
180
- "即时编程任务编写耗时缩短 35%~50%,代码完成速度显著提升(综合效应量 g = +0.61, p < 0.001),在当堂受控实验中展现明显效率增益。"
181
- ],
182
- "uncertain_claims": [
183
- "撤除 AI 后的独立闭卷期末考试与概念迁移表现显著下滑(综合效应量 g = -0.28, p = 0.012),学生存在‘看似学会、实则不会’的认知盲区。"
184
- ],
185
- "rationale": graph.decision.rationale,
186
- "applicability_boundary": graph.decision.applicability_boundary,
187
- "stop_conditions": graph.decision.stop_conditions,
188
- }
189
-
190
- # Add Forest plot data
191
- en_data["forest_plot_data"] = graph.get_forest_plot_data()[:12]
192
- zh_data["forest_plot_data"] = graph.get_forest_plot_data()[:12]
193
-
194
- # W6: outcome_mapping 从 evidence 确定性重算(消灭 stale 计数,与证据方向一致)
195
- from collections import OrderedDict
196
-
197
- def _dir_of(ev):
198
- d = (ev.get("relation_to_claim") or ev.get("direction")
199
- or ev.get("effect_direction") or "").lower()
200
- if d in ("support", "supports", "positive", "pos"):
201
- return "support"
202
- if d in ("contradict", "contradicts", "negative", "neg"):
203
- return "contradict"
204
- return "neutral"
205
-
206
- def rebuild_outcome_mapping(evidence_list, declared):
207
- agg = OrderedDict()
208
- for ev in evidence_list:
209
- ot = ev.get("outcome_type") or ev.get("outcome") or "other"
210
- bucket = agg.setdefault(ot, {"support": 0, "contradict": 0,
211
- "neutral": 0, "evidence_ids": []})
212
- bucket[_dir_of(ev)] += 1
213
- eid = ev.get("evidence_id")
214
- if eid and eid not in bucket["evidence_ids"]:
215
- bucket["evidence_ids"].append(eid)
216
- entries = []
217
- for ot, b in agg.items():
218
- status = ("supported" if b["support"] and not b["contradict"] else
219
- "contradicted" if b["contradict"] and not b["support"] else
220
- "mixed" if b["support"] and b["contradict"] else "no_evidence")
221
- entries.append({
222
- "outcome_type": ot,
223
- "declared_in_frame": ot in declared,
224
- "status": status,
225
- "support_count": b["support"],
226
- "contradict_count": b["contradict"],
227
- "neutral_count": b["neutral"],
228
- "evidence_ids": b["evidence_ids"],
229
- })
230
- return {"generated_by": "sync_killer_demo_report.rebuild_outcome_mapping",
231
- "entries": entries}
232
-
233
- frame_outcomes = set()
234
- for k in ("primary", "secondary"):
235
- for o in (((en_data.get("research_frame") or {}).get("outcomes") or {}).get(k) or []):
236
- frame_outcomes.add(o)
237
- om_en = rebuild_outcome_mapping(ev_list_en, frame_outcomes)
238
- om_zh = rebuild_outcome_mapping(ev_list_zh, frame_outcomes)
239
- en_data["outcome_mapping"] = om_en
240
- zh_data["outcome_mapping"] = om_zh
241
-
242
- # Write updated result files
243
- result_en_file.write_text(json.dumps(en_data, indent=2, ensure_ascii=False), encoding="utf-8")
244
- result_zh_file.write_text(json.dumps(zh_data, indent=2, ensure_ascii=False), encoding="utf-8")
245
- print(f"[+] Synced {len(ev_list_en)} evidence nodes & {len(claims_en)} claims to result.json; "
246
- f"outcome_mapping rebuilt ({len(om_en['entries'])} entries)")
247
-
248
- # Render publication figures
249
- cmd_fig = [
250
- sys.executable,
251
- str(ROOT / "visualization" / "eduevidence-report" / "scripts" / "build_figures.py"),
252
- "--result", str(result_en_file),
253
- "--out-dir", str(target_dir / "figures"),
254
- ]
255
- subprocess.run(cmd_fig, check=True)
256
-
257
- # Render single-file bilingual HTML report
258
- cmd_rep = [
259
- sys.executable,
260
- str(ROOT / "visualization" / "eduevidence-report" / "scripts" / "build_report.py"),
261
- "--result", str(result_en_file),
262
- "--result-zh", str(result_zh_file),
263
- "--out", str(target_dir / "EduEvidence_Report.html"),
264
- ]
265
- subprocess.run(cmd_rep, check=True)
266
- print(f"[+] Rendered single-file HTML report: {target_dir / 'EduEvidence_Report.html'}")
267
-
268
-
269
- if __name__ == "__main__":
270
- sync_report()
@@ -1 +0,0 @@
1
- @layer reset,base,components,responsive;@layer reset{*,*:before,*:after{box-sizing:border-box}body{margin:0}button,input,select{font:inherit}button,a,input,select{touch-action:manipulation}button{cursor:pointer}button:disabled{cursor:not-allowed}svg{flex-shrink:0}a{color:inherit;text-decoration:none}h1,h2,h3,p{margin-top:0}button{color:inherit}table{border-collapse:collapse}dialog:not([open]){display:none}[hidden]{display:none!important}}@layer base{:root{color-scheme:light;--canvas: #faf9f6;--surface: #fff;--surface-alt: #f5f3ef;--rail: #f0eee9;--ambient-ink: 112, 86, 66;--ambient-glow: 174, 112, 71;--ink: #282722;--muted: #69665f;--faint: #a19c91;--line: #e5e2da;--line-strong: #d5d0c5;--accent: #a85539;--accent-soft: #f4e7df;--success: #2c7255;--success-soft: #e8f2eb;--warn: #886022;--warn-soft: #f6edde;--danger: #a34442;--danger-soft: #f6e8e6;--shadow: 0 3px 15px #33301f04;--font: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Noto Sans CJK SC", sans-serif;--editorial: Georgia, "Songti SC", "STSong", serif;--mono: ui-monospace, "SF Mono", Consolas, monospace;font-family:var(--font);font-size:14px;color:var(--ink);background:var(--canvas)}:root[data-appearance=dark]{color-scheme:dark;--canvas: #191b1c;--surface: #222526;--surface-alt: #292c2c;--rail: #151718;--ambient-ink: 205, 185, 162;--ambient-glow: 209, 161, 126;--ink: #e9e6df;--muted: #b3b0a7;--faint: #83837d;--line: #353837;--line-strong: #4c504c;--accent: #e3a188;--accent-soft: #392d28;--success: #a1cfb5;--success-soft: #253930;--warn: #e2c18c;--warn-soft: #3a3327;--danger: #ecaaa3;--danger-soft: #412c2b;--shadow: none}body{line-height:1.6;-webkit-font-smoothing:antialiased}button,input,select{font-size:13px}button{border:0;background:none}button:disabled{opacity:.5}input,select{min-width:0;color:var(--ink);background:var(--surface);border:1px solid var(--line);border-radius:7px;min-height:36px;padding:7px 11px}input::placeholder{color:var(--muted)}select{max-width:100%}p{overflow-wrap:anywhere}h1,h2,h3{line-height:1.4;font-weight:560}h2{font-size:18px}h3{font-size:15px}code,kbd{font-family:var(--mono);font-size:11px;overflow-wrap:anywhere}pre{white-space:pre-wrap;overflow-wrap:anywhere;font-family:var(--mono);font-size:11px;line-height:1.8}summary{cursor:pointer}a,button{transition:background-color .16s,color .16s,border-color .16s}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,summary:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--accent);outline-offset:4px}::selection{background:var(--accent-soft)}.muted{color:var(--muted)}.prose{line-height:1.85;white-space:pre-line;max-width:78ch}.eyebrow{font-size:10px;font-weight:650;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);margin-bottom:13px}.sep{color:var(--faint);padding:0 6px}.count-label{font-family:var(--mono);font-size:11px;color:var(--muted);white-space:nowrap}.chart-note{font-size:12px;color:var(--muted);margin:15px 0 0}.button{display:inline-flex;align-items:center;justify-content:center;gap:9px;min-height:40px;border:1px solid var(--line-strong);background:var(--surface);border-radius:7px;padding:8px 16px;font-size:12px;font-weight:550}.button:hover{background:var(--surface-alt)}.button.primary{background:var(--ink);border-color:var(--ink);color:var(--canvas)}.button.primary:hover{opacity:.86}.small-button{min-height:34px;padding:6px 11px;font-size:11px}.icon-button{display:inline-flex;align-items:center;justify-content:center;min-width:34px;min-height:34px;border-radius:6px;color:var(--muted)}.icon-button:hover{background:var(--surface-alt);color:var(--ink)}.text-link{display:inline-flex;align-items:center;gap:7px;color:var(--accent);font-size:12px;font-weight:560}.text-link:hover{text-decoration:underline}.row-badges{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.row-badges .muted{font-size:12px}.badge{font-size:11px;display:inline-flex;align-items:center;gap:5px;line-height:1.4;padding:4px 7px;border-radius:4px;color:var(--muted);background:var(--surface-alt);white-space:nowrap}.badge-dot{width:4px;height:4px;border-radius:50%;background:currentColor}.badge.pilot,.badge.uncertain,.badge.stale,.badge.retest{color:var(--warn);background:var(--warn-soft)}.badge.adopt,.badge.support,.badge.supported,.badge.completed,.badge.keep,.badge.active{color:var(--success);background:var(--success-soft)}.badge.reject,.badge.contradict,.badge.failed,.badge.invalid,.badge.retracted{color:var(--danger);background:var(--danger-soft)}.badge.quiet{background:transparent;border:1px solid var(--line);color:var(--muted)}}@layer components{.app-shell{min-height:100vh}.sidebar{isolation:isolate;position:fixed;inset:0 auto 0 0;width:230px;background:var(--rail);border-right:1px solid var(--line);padding:30px 17px 18px;display:flex;flex-direction:column;z-index:30}.brand{display:flex;gap:10px;align-items:center;padding:0 10px 27px}.brand-mark{position:relative;display:grid;place-items:center;width:32px;height:34px;background:var(--accent);color:#fff;border-radius:9px 9px 9px 2px;font-family:var(--editorial);font-size:29px;line-height:1}.brand-mark span{position:absolute;right:4px;top:5px;width:4px;height:4px;border-radius:50%;background:#f4d0aa}.brand strong{font-size:15px;letter-spacing:-.035em}.brand div>span{display:block;font-size:8px;letter-spacing:.16em;color:var(--muted);margin-top:1px}.sidebar-search{display:flex;align-items:center;gap:7px;color:var(--muted);border:1px solid var(--line-strong);border-radius:7px;background:var(--canvas);min-height:35px;padding:5px 9px;font-size:11px;text-align:left}.sidebar-search span{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.sidebar-search kbd{font-size:8px;padding:1px 3px;border:1px solid var(--line);border-radius:3px;white-space:nowrap}.nav-label{padding:24px 12px 8px;font-size:10px;color:var(--muted);margin:0}.sidebar nav{display:grid;gap:3px}.sidebar nav>a{position:relative;isolation:isolate;min-height:42px;display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:7px;font-size:12px;color:var(--muted);transition:color .18s ease}.sidebar nav>a:before{content:"";position:absolute;top:3px;right:42px;bottom:3px;left:0;z-index:-1;border-radius:inherit;background:var(--surface);transition:right .38s cubic-bezier(.22,1,.36,1),top .38s cubic-bezier(.22,1,.36,1),bottom .38s cubic-bezier(.22,1,.36,1),box-shadow .22s ease}.sidebar nav>a:hover:before{right:34px}.sidebar nav>a:hover{color:var(--ink)}.sidebar nav>a[aria-current=page]{color:var(--ink)}.sidebar nav>a[aria-current=page]:before{top:0;bottom:0;right:0;box-shadow:var(--shadow)}.sidebar nav>a[aria-current=page]>svg{color:var(--accent)}.active-dot{width:4px;height:4px;border-radius:50%;background:var(--accent);margin-left:auto}.sidebar-bottom{margin-top:auto;padding:22px 11px 0}.read-only-label{display:flex;gap:7px;align-items:center;font-size:11px;color:var(--muted)}.sidebar-bottom p{color:var(--muted);font-size:10px;line-height:1.8;margin:10px 0 25px}.sidebar-version{display:flex;justify-content:space-between;color:var(--muted);font-size:10px;padding-top:12px;border-top:1px solid var(--line)}.main-shell{position:relative;isolation:isolate;margin-left:230px;min-width:0}.ambient-field,.ambient-glow{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;pointer-events:none;overflow:hidden}.ambient-field canvas{display:block;width:100%;height:100%}.ambient-glow{position:fixed;opacity:0;contain:strict}.ambient-glow i{position:absolute;left:-110px;top:-110px;width:220px;height:220px;border-radius:50%;background:radial-gradient(circle,rgba(var(--ambient-glow),.065),transparent 72%)}.ambient-glow i:nth-child(2){left:-220px;top:-220px;width:440px;height:440px;background:radial-gradient(circle,rgba(var(--ambient-glow),.035),transparent 72%)}.ambient-glow i:nth-child(3){left:-340px;top:-340px;width:680px;height:680px;background:radial-gradient(circle,rgba(var(--ambient-glow),.025),transparent 72%)}.topbar{position:sticky;top:0;z-index:20;height:62px;display:flex;justify-content:space-between;align-items:center;padding:0 38px;background:var(--canvas);border-bottom:1px solid var(--line)}.breadcrumb{display:flex;align-items:center;gap:12px;font-size:11px;color:var(--muted)}.breadcrumb strong{color:var(--ink);font-weight:500}.topbar-actions{display:flex;align-items:center;gap:8px}.connection{display:flex;gap:6px;align-items:center;color:var(--muted);font-size:10px;margin-right:12px}.connection>span{width:5px;height:5px;background:var(--success);border-radius:50%}.language-button{font-size:11px;color:var(--muted);border-left:1px solid var(--line);padding-left:13px}.main-content{max-width:1600px;margin:auto;padding:46px clamp(24px,3.5vw,62px) 60px;min-height:calc(100vh - 114px);outline:none}.app-footer{border-top:1px solid var(--line);margin:0 38px;padding:17px 0 22px;color:var(--muted);display:flex;justify-content:space-between;font-size:9px}.app-footer span{display:flex;align-items:center;gap:6px}.page-heading{display:flex;gap:20px;justify-content:space-between;align-items:flex-end;margin-bottom:34px}.page-heading h1{font-family:var(--editorial);font-weight:450;font-size:clamp(27px,2.7vw,40px);line-height:1.35;letter-spacing:-.025em;margin:0 0 11px}.page-lead{font-size:13px;color:var(--muted);margin:0;max-width:75ch}.stats-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border:1px solid var(--line);border-radius:10px;background:var(--surface);margin-bottom:30px}.stat{padding:20px 25px;display:flex;flex-direction:column}.stats-grid>.stat+.stat{border-left:1px solid var(--line)}.stat>span{font-size:11px;color:var(--muted);margin-bottom:7px}.stat>strong{font-size:27px;font-weight:450;letter-spacing:-.04em;line-height:1.25;font-variant-numeric:tabular-nums}.stat>small{font-size:10px;color:var(--muted)}.feature-grid{display:grid;grid-template-columns:minmax(0,2.1fr) minmax(240px,1fr);gap:22px;margin-bottom:44px}.feature-case{position:relative;border:1px solid var(--line);border-radius:10px;padding:27px 30px 26px;background:var(--surface);overflow:hidden}.feature-case>.eyebrow{display:flex;align-items:center;justify-content:space-between;color:var(--accent)}.feature-case>h2{font-family:var(--editorial);font-size:clamp(20px,1.8vw,27px);font-weight:500;line-height:1.55;max-width:34em;margin:0 0 17px}.mini-trace{height:126px;display:flex;align-items:center;max-width:530px;color:var(--muted);padding:20px 8px;margin:12px 0}.trace-column{display:flex;flex-direction:column;gap:10px;flex-shrink:0}.trace-column span{font:9px var(--mono);display:grid;place-items:center;width:22px;height:22px;border:1px solid var(--line-strong);border-radius:4px;background:var(--canvas)}.mini-trace svg:not(.lucide){min-width:10px;flex:1;height:90px;overflow:visible}.mini-trace path{fill:none;stroke:var(--line-strong);stroke-width:1.1}.trace-center{display:grid;place-items:center;flex-shrink:0;width:60px;height:60px;border-radius:15px;border:1px solid var(--line-strong);background:var(--canvas);outline:6px solid var(--surface);color:var(--accent)}.trace-outcome{font-size:10px;letter-spacing:.07em;flex-shrink:0;max-width:130px;padding:10px 14px;background:var(--warn-soft);border:1px solid var(--line);border-radius:5px;color:var(--warn)}.principle-card{display:flex;flex-direction:column;align-items:flex-start;border-radius:10px;border:1px solid var(--line);padding:30px;background:var(--surface-alt)}.principle-card>svg{color:var(--accent);margin-bottom:25px}.principle-card .eyebrow{font-size:9px;margin-bottom:11px}.principle-card h2{font-family:var(--editorial);font-size:25px;font-weight:400;line-height:1.55;margin:0 0 13px}.principle-card>p:not(.eyebrow){color:var(--muted);font-size:12px;line-height:1.9}.principle-card .text-link{margin:6px 0 25px}.principle-caption{margin-top:auto;font-family:var(--editorial);font-size:13px;color:var(--muted);font-style:italic;line-height:1.7}.section-heading{display:flex;justify-content:space-between;align-items:center;gap:14px;margin:0 0 18px}.section-heading h2{margin:0;font-size:16px;font-weight:580}.section-heading .eyebrow{margin-bottom:6px}.library-toolbar{display:flex;gap:14px;align-items:center;margin:0 0 20px;flex-wrap:wrap}.segmented{display:inline-flex;padding:3px;border:1px solid var(--line);border-radius:7px;background:var(--surface-alt)}.segmented button{font-size:11px;padding:6px 12px;border-radius:4px;white-space:nowrap;color:var(--muted)}.segmented button[aria-pressed=true]{background:var(--surface);box-shadow:0 1px 3px #00000009;color:var(--ink)}.search-field{display:flex;align-items:center;gap:8px;border:1px solid var(--line);border-radius:6px;background:var(--surface);padding:0 10px;min-height:36px;min-width:160px;flex:1;color:var(--muted)}.search-field input{border:0;padding:7px 0;background:transparent;width:100%;outline:none}.search-field:focus-within{outline:2px solid var(--accent);outline-offset:2px}.search-field input:focus-visible{outline:none}.library-toolbar>select{font-size:11px}.project-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.project-card{border:1px solid var(--line);border-radius:9px;background:var(--surface);padding:22px 24px 15px;box-shadow:var(--shadow);display:flex;flex-direction:column}.project-card:hover{border-color:var(--line-strong)}.project-card-top{display:flex;align-items:center;gap:10px;justify-content:space-between;margin-bottom:15px}.project-symbol{width:29px;height:29px;background:var(--surface-alt);border:1px solid var(--line);border-radius:7px;display:grid;place-items:center;color:var(--muted)}.origin-label{font-size:9px;color:var(--muted);padding:3px 6px;border:1px solid var(--line);border-radius:4px}.project-title{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex:1;margin:0 0 18px}.project-title h3{font-size:14px;line-height:1.7;margin:0;font-weight:560}.project-title>svg{margin-top:5px;color:var(--faint)}.project-title:hover h3{color:var(--accent)}.project-card-footer{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;border-top:1px solid var(--line);padding-top:14px;margin-top:19px;font-size:10px;color:var(--muted)}.project-card-footer time{font-size:9px}.back-link{display:inline-flex;gap:7px;align-items:center;font-size:11px;color:var(--muted);margin-bottom:24px}.back-link:hover{color:var(--accent)}.project-heading h1{font-family:var(--editorial);font-size:clamp(24px,2.4vw,34px);font-weight:400;line-height:1.5;margin:15px 0 13px;max-width:43em}.project-heading .eyebrow{margin:0}.project-heading>p{font-size:10px}.project-tabs{display:flex;align-items:center;gap:25px;overflow:auto;border-bottom:1px solid var(--line);margin:27px 0;scrollbar-width:thin}.project-tabs a{position:relative;white-space:nowrap;font-size:12px;padding:13px 0;color:var(--muted);border-bottom:2px solid transparent}.project-tabs a[aria-current=page]{color:var(--accent);border-bottom-color:var(--accent)}.decision-surface{display:grid;grid-template-columns:minmax(0,1fr) 230px;border:1px solid var(--line);border-radius:10px;background:var(--surface);margin-bottom:25px}.decision-main{padding:30px 32px}.decision-main h2{font-family:var(--editorial);font-size:33px;font-weight:400;margin:0 0 13px;color:var(--accent)}.decision-main>.prose{font-size:13px;margin-top:20px}.decision-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));background:var(--surface-alt);border-left:1px solid var(--line);border-radius:0 10px 10px 0;align-content:center}.decision-facts .stat{padding:20px}.decision-facts .stat>strong{font-size:24px}.decision-facts .stat>span{font-size:10px}.takeaway-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:23px}.takeaway{padding:24px;border:1px solid var(--line);border-top:2px solid var(--success);border-radius:7px;background:var(--surface)}.takeaway.uncertain{border-top-color:var(--warn)}.takeaway ol{padding-left:18px;margin-bottom:0;font-size:12px;line-height:1.9}.takeaway li+li{margin-top:12px}.takeaway li::marker{color:var(--muted);font-size:10px}.takeaway details{font-size:12px;color:var(--muted);margin-top:14px}.section{margin-top:30px;min-width:0}.boundary-box{background:var(--surface);padding:22px 25px;border:1px solid var(--line);border-radius:8px}.definition{margin:0;min-width:0}.definition>div{display:grid;grid-template-columns:minmax(90px,.6fr) minmax(0,2fr);gap:20px;border-bottom:1px solid var(--line);padding:12px 0}.definition>div:last-child{border:0}.definition dt{font-size:11px;color:var(--muted);overflow-wrap:anywhere}.definition dd{font-size:12px;white-space:pre-line;margin:0;overflow-wrap:anywhere;line-height:1.85}.overview-bottom{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:24px}.empty{text-align:center;color:var(--muted);border:1px dashed var(--line-strong);border-radius:8px;padding:40px 25px;background:var(--surface)}.empty>svg{color:var(--faint);margin-bottom:12px}.empty h3{font-size:13px;color:var(--ink);margin-bottom:8px}.empty p{font-size:12px;line-height:1.8;max-width:45em;margin:0 auto}.empty .button{margin-top:16px}.error-state{padding:45px;text-align:center;background:var(--surface);border:1px solid var(--line);border-radius:9px}.error-state>svg{color:var(--danger)}.error-state p{color:var(--muted);font-size:12px}.loading{padding:60px;text-align:center;color:var(--muted);font-size:13px}.loader{display:block;border:2px solid var(--line);border-top-color:var(--accent);border-radius:50%;width:22px;height:22px;margin:0 auto 15px;animation:spin .8s linear infinite}.spinning{animation:spin 1s linear infinite}.skeleton{height:15px;background:var(--surface-alt);max-width:500px;border-radius:6px;margin:25px auto 0}.skeleton.short{width:60%;margin-top:12px}.diagnostic{border:1px solid var(--line-strong);background:var(--warn-soft);border-radius:7px;padding:12px 16px;margin-bottom:23px;font-size:12px}.diagnostic summary{display:flex;gap:8px;align-items:center}.diagnostic summary>span{margin-left:auto}.diagnostic li{padding:5px 0}.filter-bar{display:flex;gap:14px;align-items:center;flex-wrap:wrap;margin:0 0 17px}.filter-bar label:not(.search-field){display:flex;align-items:center;gap:9px;font-size:10px;color:var(--muted)}.filter-bar select{font-size:11px;max-width:270px}.table-scroll{overflow:auto;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.evidence-table{width:100%;font-size:12px;min-width:820px}.evidence-table th{text-align:left;font-size:10px;font-weight:500;color:var(--muted);background:var(--surface-alt);padding:12px 17px;border-bottom:1px solid var(--line)}.evidence-table td{padding:15px 17px;vertical-align:top;border-bottom:1px solid var(--line);font-size:11px;max-width:380px}.evidence-table tr:last-child td{border:0}.evidence-table tbody tr:hover{background:var(--surface-alt)}.evidence-title{text-align:left;display:flex;flex-direction:column;padding:0;gap:6px}.evidence-title>code{color:var(--accent);font-size:10px}.evidence-title>strong{font-size:12px;font-weight:500;line-height:1.7}.evidence-title>small{font-size:10px;color:var(--muted)}.numeric-cell{font-family:var(--mono)}.sources-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.source-item{display:flex;align-items:flex-start;gap:12px;padding:23px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.source-item>svg{color:var(--accent);margin-top:5px}.source-item h3{font-size:12px;line-height:1.8;margin:8px 0 12px}.source-item code{font-size:9px;color:var(--muted)}.source-meta{display:flex;gap:10px;flex-wrap:wrap;font-size:9px;color:var(--muted);margin-bottom:13px;overflow-wrap:anywhere}.forest-svg{display:block;min-width:730px;width:100%;padding:18px 0}.zero-line{stroke:var(--faint);stroke-dasharray:3 3;stroke-width:1}.ci-line{stroke:var(--accent);stroke-width:1.5}.effect-dot{fill:var(--accent)}.forest-label{font:11px var(--mono);fill:var(--muted)}.graph-panel{border:1px solid var(--line);background:var(--surface);border-radius:9px;overflow:hidden}.graph-toolbar{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid var(--line)}.graph-toolbar>p{font-size:11px;color:var(--muted);margin:0}.button-group{display:flex}.graph-scroll{overflow:auto}.graph-scroll>svg{display:block;width:100%;color:var(--muted)}.graph-label{font:11px var(--font);fill:var(--muted)}.graph-edge{stroke:var(--line-strong);stroke-width:1.4}.graph-edge.support{stroke:var(--success)}.graph-edge.contradict{stroke:var(--danger);stroke-dasharray:4 3}.graph-node{cursor:pointer}.graph-node:focus{outline:none}.graph-node .graph-focus-ring{display:none}.graph-node:focus-visible .graph-focus-ring{display:block;fill:none;stroke:var(--accent);stroke-width:1.5;stroke-dasharray:3 2}.graph-flow{stroke:var(--accent);stroke-width:2;stroke-dasharray:16 84;stroke-linecap:round;opacity:.65;pointer-events:none;animation:relationship-flow 3.5s linear infinite}.graph-panel.compact{position:relative}.compact-flow-toggle{position:absolute;top:5px;right:5px;z-index:1;background:var(--surface)}.graph-flow.support{stroke:var(--success)}.graph-flow.contradict{stroke:var(--danger)}@keyframes relationship-flow{0%{stroke-dashoffset:100}to{stroke-dashoffset:0}}@media(prefers-reduced-motion:reduce){.graph-flow{display:none;animation:none}}@media print{.ambient-field,.ambient-glow,.graph-flow{display:none}}.graph-node rect{fill:var(--surface-alt);stroke:var(--line-strong);stroke-width:1}.graph-node.finding rect{fill:var(--accent-soft);stroke:var(--accent)}.graph-node.claim rect{fill:var(--success-soft);stroke:var(--success)}.graph-node.selected rect{stroke-width:3}.node-letter{fill:var(--ink);font:9px var(--mono)}.node-id{fill:var(--muted);font:8px var(--mono)}.graph-panel>.chart-note{padding:0 16px 16px}.graph-node-index{padding:12px 16px;display:flex;gap:5px;flex-wrap:wrap;border-top:1px solid var(--line)}.graph-node-index button{font:9px var(--mono);border:1px solid var(--line);padding:3px 5px;border-radius:3px;color:var(--muted)}.graph-node-index button.active{background:var(--accent-soft);color:var(--accent)}.graph-workspace{display:grid;grid-template-columns:minmax(0,1fr) 230px;gap:20px;align-items:start}.graph-inspector{background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:20px;position:sticky;top:80px}.graph-inspector>h3{font-size:12px;line-height:1.8;margin-top:13px}.graph-inspector>p:not(.eyebrow){font-size:11px}.graph-inspector>p>code{display:block;font-size:9px}.graph-inspector>p>small{display:block;color:var(--muted)}.run-row{background:var(--surface);border:1px solid var(--line);border-radius:8px;margin-bottom:10px}.run-row>summary{display:flex;align-items:center;gap:13px;padding:17px 19px}.run-row summary>div{flex:1;min-width:0}.run-row strong{display:block;font-size:12px;font-weight:550}.run-row small{display:block;font-size:9px;color:var(--muted);overflow-wrap:anywhere}.run-icon{color:var(--muted)}.run-body{border-top:1px solid var(--line);padding:16px 22px}.stage-track{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:18px}.stage-track>div{display:flex;flex-direction:column;align-items:flex-start;gap:5px;font-size:10px;background:var(--surface-alt);padding:10px;border-radius:5px}.event-list{list-style:none;margin:0;padding:5px 0}.event-list>li{display:grid;grid-template-columns:12px minmax(0,1fr);gap:16px;position:relative;padding:0 0 24px}.event-list>li:before{content:"";position:absolute;top:15px;bottom:0;left:3px;border-left:1px solid var(--line)}.event-dot{width:7px;height:7px;background:var(--accent);border-radius:50%;margin-top:7px}.event-header{display:flex;justify-content:space-between;gap:12px}.event-header strong{font-size:12px;font-weight:550}.event-header time{font-size:9px;color:var(--muted)}.raw-record{font-size:11px;margin-top:12px}.raw-record summary{color:var(--muted)}.raw-record pre{background:var(--surface-alt);padding:14px;border-radius:5px;max-height:350px;overflow:auto}.artifact-list>div{display:flex;align-items:flex-start;gap:12px;padding:18px 0;border-bottom:1px solid var(--line)}.artifact-list strong{display:block;font-size:12px}.artifact-list code{display:block;font-size:9px;color:var(--muted)}.artifact-list .raw-record{margin-left:auto}.revision-list>div{display:flex;gap:15px;align-items:center;padding:20px;background:var(--surface);border:1px solid var(--line);border-radius:8px;margin-bottom:10px}.revision-list strong{font-size:14px;font-weight:550;flex:1}.revision-list svg{color:var(--accent)}.snapshot{border:1px solid var(--line);border-radius:8px;background:var(--surface);padding:20px;margin-bottom:12px}.snapshot summary{display:flex;gap:15px;align-items:center;justify-content:space-between}.snapshot>p{font-size:11px;margin:15px 0}.theme-gallery{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:13px;margin:24px 0}.theme-card{border:1px solid var(--line);border-radius:8px;padding:8px 8px 13px;background:var(--surface);text-align:left;min-width:0}.theme-card.selected{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.theme-card>strong{display:block;font-size:11px;font-weight:580;margin:10px 5px 3px;overflow-wrap:anywhere}.theme-card>span{display:block;font-size:9px;line-height:1.7;margin:0 5px;color:var(--muted)}.theme-miniature{aspect-ratio:1.35;padding:14px;background:#f7f4ed;border:1px solid #e3dacf;border-radius:4px;--mini-ink: #94654c;--mini-muted: #d8cdbf}.theme-academic .theme-miniature{background:#fff;--mini-ink: #234b57;--mini-muted: #c9ced0;border-radius:0}.theme-datalab .theme-miniature{background:#eef2f8;--mini-ink: #2563eb;--mini-muted: #c5d1e2}.theme-datalab-dark .theme-miniature{background:#151c2a;--mini-ink: #7b9fff;--mini-muted: #354461;border-color:#333f58}.theme-presentation .theme-miniature{background:#161b23;--mini-ink: #e8a87c;--mini-muted: #45403e;border-color:#393e43}.mini-kicker{font-size:5px;letter-spacing:.13em;color:var(--mini-ink);margin-bottom:11px}.mini-heading{height:5px;width:88%;background:var(--mini-ink);opacity:.8;margin-bottom:5px;border-radius:1px}.mini-heading.small{width:55%}.mini-rule{border-top:1px solid var(--mini-muted);margin:11px 0}.mini-decision{position:relative;border:1px solid var(--mini-muted);padding:8px;margin-bottom:9px}.mini-decision span{display:block;width:38%;height:5px;background:var(--mini-ink);margin-bottom:5px}.mini-decision div,.mini-lines i{display:block;width:90%;height:2px;background:var(--mini-muted);margin-top:3px}.mini-lines{display:grid;grid-template-columns:repeat(3,1fr);gap:4px}.theme-academic .mini-decision{border-width:1px 0}.theme-presentation .mini-decision{padding:12px 8px;border-radius:3px}.theme-datalab .mini-lines i,.theme-datalab-dark .mini-lines i{height:9px}.reader{border:1px solid var(--line);border-radius:9px;overflow:hidden;background:var(--surface)}.reader-toolbar{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:12px 17px;border-bottom:1px solid var(--line);background:var(--surface)}.reader-toolbar>span{display:flex;align-items:center;gap:8px;font-size:11px}.reader-toolbar>div{display:flex;gap:7px}.reader iframe{display:block;width:100%;height:78vh;min-height:550px;border:0;background:var(--canvas)}.reader-loading{padding:100px 25px;text-align:center;font-size:12px;color:var(--muted)}.project-select{display:flex;align-items:center;gap:20px;color:var(--muted);font-size:12px}.project-select select{max-width:760px;flex:1}.policy-strip{display:flex;align-items:center;gap:16px;border:1px solid var(--line);background:var(--surface-alt);padding:23px;border-radius:8px;margin-bottom:24px;font-size:13px}.policy-strip>.badge{margin-left:auto}.experiment-list{display:grid;gap:15px}.flow-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}.flow-grid>article{padding:30px;background:var(--surface);border:1px solid var(--line);border-radius:9px}.flow-number{font:italic 36px var(--editorial);color:var(--accent);display:block;margin-bottom:26px}.flow-grid h2{font-family:var(--editorial);font-size:22px;font-weight:450}.flow-grid p{font-size:12px;color:var(--muted);line-height:1.9;margin:0}.protocol-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:9px;overflow:hidden}.protocol-grid>div{display:grid;grid-template-columns:30px 1fr;gap:5px 12px;background:var(--surface);padding:24px}.protocol-grid code{color:var(--accent);grid-row:span 2}.protocol-grid strong{font-weight:500;font-size:13px}.protocol-grid span{font-size:10px;color:var(--muted)}.principles{margin-top:28px;padding:28px;background:var(--surface-alt);border-radius:9px;border:1px solid var(--line)}.principles p{display:flex;align-items:center;gap:13px;font-size:12px;margin-bottom:16px}.principles p:last-child{margin:0}.principles svg{color:var(--accent)}.inspector{position:fixed;inset:0 0 0 auto;margin:0;max-height:100dvh;height:100dvh;width:min(540px,100%);max-width:100vw;background:var(--surface);color:var(--ink);border:0;border-left:1px solid var(--line);padding:27px 32px;box-shadow:-10px 0 50px #00000010;overflow:auto}.inspector::backdrop,.command-palette::backdrop{background:#17181565;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.inspector-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:28px}.inspector-top .eyebrow{margin:0}.entity-id{color:var(--accent)}.inspector h2{font-family:var(--editorial);font-size:24px;line-height:1.6;font-weight:400;margin:15px 0 20px}.inspector>.prose{margin-top:22px;font-size:13px}.source-callout{display:flex;gap:12px;background:var(--surface-alt);padding:20px;border-radius:7px;margin:22px 0}.source-callout h3{font-size:12px;line-height:1.8}.source-callout>svg{color:var(--accent);margin-top:3px}.command-palette{width:min(640px,92vw);background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:12px;padding:0;margin:14vh auto auto;max-height:68vh;overflow:hidden;box-shadow:0 30px 100px #00000024}.command-input{display:flex;align-items:center;gap:10px;padding:14px 18px;border-bottom:1px solid var(--line)}.command-input input{border:0;flex:1}.command-results{padding:10px;max-height:55vh;overflow:auto}.command-results>button{display:flex;align-items:center;gap:13px;width:100%;text-align:left;padding:14px 12px;font-size:12px;line-height:1.8;border-radius:7px}.command-results>button>span{flex:1}.command-results>button:hover{background:var(--surface-alt)}.command-results>button>svg{color:var(--muted)}.skip-link{position:fixed;left:250px;top:-100px;padding:10px 20px;background:var(--surface);z-index:100;border:1px solid var(--accent);border-radius:5px}.skip-link:focus{top:10px}.mobile-menu,.sidebar-shade{display:none}@keyframes spin{to{transform:rotate(360deg)}}}@layer responsive{@media(min-width:1700px){.project-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(max-width:1200px){.sidebar{width:205px;padding-left:12px;padding-right:12px}.main-shell{margin-left:205px}.main-content{padding:32px 28px 50px}.topbar{padding:0 28px}.feature-grid{grid-template-columns:minmax(0,1.8fr) minmax(210px,1fr)}.feature-case{padding:23px}.principle-card{padding:24px}.principle-card h2{font-size:22px}.graph-workspace{grid-template-columns:minmax(0,1fr)}.graph-inspector{position:static}.decision-surface{grid-template-columns:minmax(0,1fr) 180px}.decision-facts .stat{padding:15px}.theme-gallery{gap:8px}.theme-miniature{padding:10px}.theme-card>span{font-size:8px}.overview-bottom{grid-template-columns:minmax(0,1fr)}}@media(max-width:900px){.feature-grid{grid-template-columns:minmax(0,1fr)}.principle-card{display:none}.project-grid,.sources-grid,.takeaway-grid,.flow-grid{grid-template-columns:minmax(0,1fr)}.flow-grid>article{display:grid;grid-template-columns:48px 1fr;gap:10px 20px}.flow-number{grid-row:span 2;margin:0}.flow-grid h2{margin:0}.theme-gallery{grid-template-columns:repeat(3,minmax(0,1fr))}.theme-miniature{aspect-ratio:1.7}.reader-toolbar{align-items:flex-start;flex-direction:column}.reader-toolbar>div{flex-wrap:wrap}.filter-bar{align-items:stretch}.filter-bar .search-field{flex-basis:100%}.stat{padding:17px}.protocol-grid>div{padding:17px}}@media(max-width:680px){.sidebar{width:240px;transform:translate(-100%);visibility:hidden;z-index:50}.sidebar.is-open{visibility:visible;transform:none}.sidebar-shade{display:block;position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;z-index:40}.main-shell{margin-left:0}.topbar{height:56px;padding:0 14px}.mobile-menu{display:inline-flex}.breadcrumb{gap:7px;font-size:10px}.topbar-actions{gap:3px}.connection{display:none}.language-button{padding:0 8px;font-size:10px}.main-content{padding:28px 19px 40px}.page-heading{margin-bottom:24px}.page-heading h1{font-size:28px;line-height:1.5}.page-lead{font-size:12px}.eyebrow{font-size:9px}.stats-grid{grid-template-columns:repeat(2,minmax(0,1fr));margin-bottom:20px}.stats-grid>.stat:nth-child(3){border-left:0;border-top:1px solid var(--line)}.stats-grid>.stat:nth-child(4){border-top:1px solid var(--line)}.stat{padding:16px 19px}.stat>strong{font-size:26px}.stat>span{font-size:10px}.feature-grid{margin-bottom:30px}.feature-case{padding:23px 20px}.feature-case>h2{font-size:22px;line-height:1.65}.mini-trace{height:110px;padding-left:0;padding-right:0}.trace-center{height:44px;width:44px;border-radius:12px}.trace-outcome{padding:8px;font-size:9px;max-width:90px}.library-toolbar{gap:10px}.library-toolbar>.segmented{width:100%}.segmented button{flex:1;padding:6px 9px}.project-card{padding:21px 20px 15px}.project-title h3{font-size:14px}.project-card-footer{font-size:9px}.project-heading h1{font-size:24px}.project-tabs{gap:21px;margin:23px 0}.project-tabs a{font-size:11px}.project-heading>p{font-size:9px}.decision-surface{grid-template-columns:minmax(0,1fr)}.decision-main{padding:25px 22px}.decision-main h2{font-size:29px}.decision-facts{grid-template-columns:repeat(4,minmax(0,1fr));border:0;border-top:1px solid var(--line);border-radius:0 0 10px 10px}.decision-facts .stat{padding:15px 10px;text-align:center}.decision-facts .stat>span{font-size:9px}.decision-facts .stat>strong{font-size:22px}.takeaway{padding:23px 21px}.takeaway-grid{gap:16px}.boundary-box{padding:18px}.definition>div{grid-template-columns:minmax(75px,.6fr) minmax(0,1.8fr);gap:13px}.definition dt{font-size:10px}.definition dd{font-size:11px}.filter-bar label:not(.search-field){flex:1;flex-direction:column;align-items:stretch;gap:5px}.filter-bar select{max-width:100%;width:100%}.theme-gallery{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.theme-card:last-child{grid-column:auto}.theme-miniature{aspect-ratio:1.4;padding:13px}.theme-card>span{font-size:9px}.project-select{flex-direction:column;align-items:stretch;gap:8px}.project-select select{width:100%;font-size:12px}.reader-toolbar{padding:12px}.reader-toolbar .button{font-size:10px;padding:6px 8px}.reader iframe{min-height:500px;height:75vh}.run-row>summary{padding:15px 12px;gap:9px}.run-row strong{font-size:11px}.run-row small{font-size:8px}.run-body{padding:15px}.stage-track{grid-template-columns:repeat(2,minmax(0,1fr))}.graph-toolbar{gap:10px;padding:10px}.graph-toolbar>p{font-size:10px}.graph-node-index{max-height:130px;overflow:auto}.protocol-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.flow-grid>article{padding:24px 20px}.policy-strip{padding:18px;flex-wrap:wrap}.policy-strip>span:not(.badge){font-size:11px}.policy-strip>.badge{margin:0}.principles{padding:22px 19px}.principles p{align-items:flex-start;font-size:11px}.principles svg{margin-top:3px}.inspector{padding:23px}.inspector h2{font-size:23px}.app-footer{margin:0 19px;font-size:8px}.skip-link{left:15px}.error-state{padding:30px 20px}.loading{padding:45px 20px}.empty{padding:30px 20px}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media print{.sidebar,.topbar,.app-footer,.project-tabs,.icon-button{display:none!important}.main-shell{margin:0}.main-content{padding:0}.project-card,.takeaway,.decision-surface{break-inside:avoid}:root{color-scheme:light;--canvas: #fff;--surface: #fff;--ink: #111;--muted: #555;--line: #bbb;--surface-alt: #f6f6f6}}}