eduevidence 5.2.0 → 6.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.
Files changed (386) hide show
  1. package/CONTRIBUTING.md +105 -0
  2. package/README.md +142 -75
  3. package/README.zh-CN.md +73 -30
  4. package/SKILL.md +397 -131
  5. package/agents/openai.yaml +4 -0
  6. package/assets/readme/controlled-execution.svg +34 -0
  7. package/assets/readme/landing-tour.gif +0 -0
  8. package/assets/readme/logo.png +0 -0
  9. package/assets/readme/research-workflow.svg +56 -0
  10. package/assets/readme/studio-graph.png +0 -0
  11. package/assets/readme/studio-overview.png +0 -0
  12. package/assets/readme/studio-reports.png +0 -0
  13. package/assets/readme/studio-tour.gif +0 -0
  14. package/autoevolve/config.yaml +17 -0
  15. package/autoevolve/program.md +25 -0
  16. package/autoevolve/protected.manifest.yaml +34 -0
  17. package/benchmarks/adversarial/cases.jsonl +7 -0
  18. package/benchmarks/evidence-library.json +5268 -0
  19. package/benchmarks/partitions.json +8 -0
  20. package/bin/eduevidence.js +2 -1
  21. package/docs/architecture.md +496 -0
  22. package/docs/autoresearch-evolution-plan.md +2903 -0
  23. package/docs/autoresearch-implementation-status.md +101 -0
  24. package/docs/demo-storyboard.md +20 -0
  25. package/docs/demo-workplace-ai.md +92 -0
  26. package/docs/demo.md +32 -0
  27. package/docs/install-guide.md +150 -0
  28. package/docs/orchestration-role-model.md +1254 -0
  29. package/docs/release-closeout/README.md +17 -0
  30. package/docs/release-closeout/frontend-acceptance.md +23 -0
  31. package/docs/release-closeout/issues.md +19 -0
  32. package/docs/release-closeout/verification.md +28 -0
  33. package/docs/release-contract.md +108 -0
  34. package/docs/research-studio-guide.zh-CN.md +166 -0
  35. package/docs/sciverse-api.md +125 -0
  36. package/eduevidence_cli.py +29 -13
  37. package/engine/_resources.py +13 -0
  38. package/engine/autoevolve/__init__.py +3 -0
  39. package/engine/autoevolve/agent_view.py +167 -0
  40. package/engine/autoevolve/core.py +357 -0
  41. package/engine/autoevolve/events.py +11 -0
  42. package/engine/autoevolve/git_workspace.py +77 -0
  43. package/engine/autoevolve/projection.py +23 -0
  44. package/engine/autoevolve/runner.py +413 -0
  45. package/engine/autoevolve/trust.py +146 -0
  46. package/engine/autoresearch/__init__.py +6 -0
  47. package/engine/autoresearch/commit.py +132 -0
  48. package/engine/autoresearch/contracts.py +126 -0
  49. package/engine/autoresearch/controller.py +207 -0
  50. package/engine/autoresearch/events.py +12 -0
  51. package/engine/autoresearch/gap_priority.py +168 -0
  52. package/engine/autoresearch/projection.py +30 -0
  53. package/engine/autoresearch/research_memory.py +59 -0
  54. package/engine/autoresearch/saturation.py +91 -0
  55. package/engine/briefs.py +2 -1
  56. package/engine/capabilities.py +1 -0
  57. package/engine/contracts.py +3 -1
  58. package/engine/decision_policy.py +96 -0
  59. package/engine/evidence_graph.py +14 -10
  60. package/engine/evidencecore.py +7 -5
  61. package/engine/gaps.py +132 -73
  62. package/engine/ids.py +2 -0
  63. package/engine/judge_pack.py +65 -0
  64. package/engine/library.py +6 -2
  65. package/engine/library_builtin.py +3 -1
  66. package/engine/living.py +36 -5
  67. package/engine/meta_synthesis.py +3 -1
  68. package/engine/migration.py +88 -3
  69. package/engine/orchestration.py +460 -0
  70. package/engine/paths.py +2 -0
  71. package/engine/pilot.py +36 -33
  72. package/engine/project.py +2 -2
  73. package/engine/research_service.py +113 -0
  74. package/engine/studio_read_model.py +400 -0
  75. package/engine/taxonomy.py +211 -0
  76. package/engine/tribunal.py +44 -33
  77. package/engine/update.py +1 -0
  78. package/engine/versions.py +1 -1
  79. package/engine/worker_result.py +109 -0
  80. package/engine/workflows.py +70 -0
  81. package/examples/ai-coding-assistant-evidence/EduEvidence_Report.html +2934 -0
  82. package/examples/ai-coding-assistant-evidence/artifact_manifest.json +15 -0
  83. package/examples/ai-coding-assistant-evidence/citation_check.json +79 -0
  84. package/examples/ai-coding-assistant-evidence/claims.jsonl +12 -0
  85. package/examples/ai-coding-assistant-evidence/evaluation.json +35 -0
  86. package/examples/ai-coding-assistant-evidence/evidence.jsonl +12 -0
  87. package/examples/ai-coding-assistant-evidence/final_verdict.json +107 -0
  88. package/examples/ai-coding-assistant-evidence/frame.json +48 -0
  89. package/examples/ai-coding-assistant-evidence/gate_report.json +101 -0
  90. package/examples/ai-coding-assistant-evidence/intervention.json +51 -0
  91. package/examples/ai-coding-assistant-evidence/methodology.json +36 -0
  92. package/examples/ai-coding-assistant-evidence/raw_verdict.json +86 -0
  93. package/examples/ai-coding-assistant-evidence/report_spec.json +230 -0
  94. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_academic.html +2934 -0
  95. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_claude.html +2934 -0
  96. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_datalab-dark.html +2934 -0
  97. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_datalab.html +2934 -0
  98. package/examples/ai-coding-assistant-evidence/reports-5themes/EduEvidence_Report_presentation.html +2934 -0
  99. package/examples/ai-coding-assistant-evidence/reports-5themes/report_academic.html +2934 -0
  100. package/examples/ai-coding-assistant-evidence/reports-5themes/report_claude.html +2934 -0
  101. package/examples/ai-coding-assistant-evidence/reports-5themes/report_datalab-dark.html +2934 -0
  102. package/examples/ai-coding-assistant-evidence/reports-5themes/report_datalab.html +2934 -0
  103. package/examples/ai-coding-assistant-evidence/reports-5themes/report_presentation.html +2934 -0
  104. package/examples/ai-coding-assistant-evidence/result.json +1457 -0
  105. package/examples/ai-coding-assistant-evidence/result.zh.json +1457 -0
  106. package/examples/ai-coding-assistant-evidence/skeptic.json +72 -0
  107. package/examples/ai-coding-assistant-evidence/sources.jsonl +8 -0
  108. package/examples/ai-coding-assistant-evidence/verdict.json +107 -0
  109. package/examples/spaced-retrieval-practice/applicability.json +14 -0
  110. package/examples/spaced-retrieval-practice/artifact_manifest.json +15 -0
  111. package/examples/spaced-retrieval-practice/claims.jsonl +3 -0
  112. package/examples/spaced-retrieval-practice/evidence.jsonl +6 -0
  113. package/examples/spaced-retrieval-practice/final_verdict.json +93 -0
  114. package/examples/spaced-retrieval-practice/frame.json +58 -0
  115. package/examples/spaced-retrieval-practice/gate_report.json +101 -0
  116. package/examples/spaced-retrieval-practice/methodology.json +78 -0
  117. package/examples/spaced-retrieval-practice/report_spec.json +212 -0
  118. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_academic.html +2728 -0
  119. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_claude.html +2728 -0
  120. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_datalab-dark.html +2728 -0
  121. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_datalab.html +2728 -0
  122. package/examples/spaced-retrieval-practice/reports-5themes/EduEvidence_Report_presentation.html +2728 -0
  123. package/examples/spaced-retrieval-practice/reports-5themes/report_academic.html +2728 -0
  124. package/examples/spaced-retrieval-practice/reports-5themes/report_claude.html +2728 -0
  125. package/examples/spaced-retrieval-practice/reports-5themes/report_datalab-dark.html +2728 -0
  126. package/examples/spaced-retrieval-practice/reports-5themes/report_datalab.html +2728 -0
  127. package/examples/spaced-retrieval-practice/reports-5themes/report_presentation.html +2728 -0
  128. package/examples/spaced-retrieval-practice/result.json +942 -0
  129. package/examples/spaced-retrieval-practice/result.zh.json +942 -0
  130. package/examples/spaced-retrieval-practice/skeptic.json +70 -0
  131. package/examples/spaced-retrieval-practice/sources.jsonl +7 -0
  132. package/examples/spaced-retrieval-practice/verdict.json +93 -0
  133. package/examples/workplace-ai-assistant/artifact_manifest.json +15 -0
  134. package/examples/workplace-ai-assistant/claims.jsonl +4 -0
  135. package/examples/workplace-ai-assistant/evaluation.json +19 -0
  136. package/examples/workplace-ai-assistant/evidence.jsonl +4 -0
  137. package/examples/workplace-ai-assistant/evidence_graph.json +444 -0
  138. package/examples/workplace-ai-assistant/final_verdict.json +78 -0
  139. package/examples/workplace-ai-assistant/frame.json +41 -0
  140. package/examples/workplace-ai-assistant/gate_report.json +101 -0
  141. package/examples/workplace-ai-assistant/intervention.json +27 -0
  142. package/examples/workplace-ai-assistant/legacy-link-check.json +16 -0
  143. package/examples/workplace-ai-assistant/methodology.json +60 -0
  144. package/examples/workplace-ai-assistant/report_spec.json +224 -0
  145. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_academic.html +2814 -0
  146. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_claude.html +2814 -0
  147. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_datalab-dark.html +2814 -0
  148. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_datalab.html +2814 -0
  149. package/examples/workplace-ai-assistant/reports-5themes/EduEvidence_Report_presentation.html +2814 -0
  150. package/examples/workplace-ai-assistant/reports-5themes/report_academic.html +2814 -0
  151. package/examples/workplace-ai-assistant/reports-5themes/report_claude.html +2814 -0
  152. package/examples/workplace-ai-assistant/reports-5themes/report_datalab-dark.html +2814 -0
  153. package/examples/workplace-ai-assistant/reports-5themes/report_datalab.html +2814 -0
  154. package/examples/workplace-ai-assistant/reports-5themes/report_presentation.html +2814 -0
  155. package/examples/workplace-ai-assistant/result.json +615 -0
  156. package/examples/workplace-ai-assistant/result.zh.json +615 -0
  157. package/examples/workplace-ai-assistant/search_log.json +19 -0
  158. package/examples/workplace-ai-assistant/skeptic.json +72 -0
  159. package/examples/workplace-ai-assistant/sources.jsonl +3 -0
  160. package/examples/workplace-ai-assistant/validation_result.json +9 -0
  161. package/examples/workplace-ai-assistant/verdict.json +78 -0
  162. package/install.sh +7 -7
  163. package/integrations/agent_mcp.py +2 -2
  164. package/integrations/orchestration_dispatch.py +146 -0
  165. package/package.json +46 -3
  166. package/pyproject.toml +14 -22
  167. package/references/autoresearch.md +30 -0
  168. package/references/evaluation-policy.md +24 -0
  169. package/references/orchestration.md +22 -0
  170. package/references/report-copy-style.md +67 -0
  171. package/references/retrieval-compliance.md +75 -0
  172. package/references/retrieval-protocol.md +20 -0
  173. package/references/scientific-invariants.md +19 -0
  174. package/retrieval/audit.py +178 -0
  175. package/retrieval/fetch.py +96 -0
  176. package/retrieval/sciverse.py +398 -0
  177. package/retrieval/search.py +47 -7
  178. package/schemas/applicability.schema.json +94 -0
  179. package/schemas/chart-spec.schema.json +10 -3
  180. package/schemas/evidence.schema.json +316 -43
  181. package/schemas/fetch-result.schema.json +2 -1
  182. package/schemas/intervention.schema.json +106 -21
  183. package/schemas/report-result.schema.json +12 -4
  184. package/schemas/report-spec.schema.json +98 -100
  185. package/schemas/skeptic.schema.json +86 -0
  186. package/schemas/source.schema.json +21 -2
  187. package/schemas/v2/finding.schema.json +5 -1
  188. package/schemas/v2/methodology-audit.schema.json +5 -1
  189. package/schemas/v2/outcome.schema.json +28 -5
  190. package/schemas/v2/project.schema.json +2 -2
  191. package/schemas/v2/run.schema.json +1 -1
  192. package/schemas/v2/study.schema.json +5 -1
  193. package/schemas/vNext/autoevolve-session.schema.json +34 -0
  194. package/schemas/vNext/eval-snapshot.schema.json +77 -0
  195. package/schemas/vNext/execution-plan.schema.json +50 -0
  196. package/schemas/vNext/gap-priority.schema.json +54 -0
  197. package/schemas/vNext/negative-search-record.schema.json +68 -0
  198. package/schemas/vNext/research-iteration.schema.json +87 -0
  199. package/schemas/vNext/research-strategy.schema.json +62 -0
  200. package/schemas/vNext/skill-experiment.schema.json +90 -0
  201. package/schemas/vNext/task-spec.schema.json +156 -0
  202. package/schemas/vNext/worker-result.schema.json +60 -0
  203. package/schemas/verdict.schema.json +164 -28
  204. package/scripts/benchmark_judge.py +2 -2
  205. package/scripts/benchmark_v3.py +26 -43
  206. package/scripts/build_esl_artifacts.py +4 -4
  207. package/scripts/build_evidence_library.py +2 -2
  208. package/scripts/build_gh_pages.py +98 -0
  209. package/scripts/build_readme_diagrams.py +72 -0
  210. package/scripts/build_report_variants.py +101 -0
  211. package/scripts/build_result.py +74 -9
  212. package/scripts/check_autoresearch_invariants.py +95 -0
  213. package/scripts/check_package_parity.py +85 -0
  214. package/scripts/check_protocol_alignment.py +375 -0
  215. package/scripts/check_versioned_schemas.py +254 -0
  216. package/scripts/claim_audit.py +13 -8
  217. package/scripts/compute_confidence.py +10 -0
  218. package/scripts/daily_evolve.py +30 -0
  219. package/scripts/dashboard_server.py +130 -101
  220. package/scripts/did_regression.py +17 -32
  221. package/scripts/enrich_projects_human_and_lieflat.py +1 -1
  222. package/scripts/evidence_score.py +5 -2
  223. package/scripts/generate_metrics.py +4 -3
  224. package/scripts/generate_new_projects.py +5 -5
  225. package/scripts/orchestrator.py +286 -36
  226. package/scripts/pre_verdict_gate.py +224 -26
  227. package/scripts/quickstart.py +18 -2
  228. package/scripts/rebake_all_5themes.py +1 -2
  229. package/scripts/research_auto_cli.py +475 -0
  230. package/scripts/run_workspace.py +24 -8
  231. package/scripts/search_provenance.py +64 -0
  232. package/scripts/serve_web.py +9 -10
  233. package/scripts/skill_lint.py +1 -1
  234. package/scripts/skill_payload.py +81 -0
  235. package/scripts/test_adversarial_empirical.py +26 -19
  236. package/scripts/validate_schema.py +46 -2
  237. package/scripts/vnext_cli.py +133 -0
  238. package/setup.py +12 -0
  239. package/skill/agents/evaluation-designer.md +20 -4
  240. package/skill/agents/evidence-analyst.md +19 -3
  241. package/skill/agents/evidence-judge.md +50 -2
  242. package/skill/agents/evidence-retriever.md +20 -3
  243. package/skill/agents/intervention-designer.md +20 -4
  244. package/skill/agents/method-reviewer.md +18 -2
  245. package/skill/agents/{education-planner.md → research-planner.md} +19 -3
  246. package/skill/agents/skeptic.md +18 -2
  247. package/skill/roles/registry.yaml +45 -0
  248. package/skill/sub-skills/aihot-trend-analysis/SKILL.md +28 -9
  249. package/skill/sub-skills/contradiction-analysis/SKILL.md +31 -11
  250. package/skill/sub-skills/data-analysis/SKILL.md +34 -15
  251. package/skill/sub-skills/ethics-review/SKILL.md +33 -10
  252. package/skill/sub-skills/evidence-extraction/SKILL.md +29 -11
  253. package/skill/sub-skills/evidence-review/SKILL.md +31 -12
  254. package/skill/sub-skills/gap-analysis/SKILL.md +31 -9
  255. package/skill/sub-skills/literature-review/SKILL.md +35 -14
  256. package/skill/sub-skills/methodology-audit/SKILL.md +29 -12
  257. package/skill/sub-skills/report-generation/SKILL.md +40 -6
  258. package/skill/sub-skills/research-planning/SKILL.md +41 -14
  259. package/skill/sub-skills/study-design/SKILL.md +30 -9
  260. package/skill/task-briefs/adjudicate.md +32 -7
  261. package/skill/task-briefs/applicability.md +38 -0
  262. package/skill/task-briefs/audit.md +32 -7
  263. package/skill/task-briefs/challenge.md +34 -5
  264. package/skill/task-briefs/evaluate.md +30 -5
  265. package/skill/task-briefs/extract.md +31 -8
  266. package/skill/task-briefs/frame.md +39 -10
  267. package/skill/task-briefs/intervene.md +32 -6
  268. package/skill/task-briefs/present.md +32 -8
  269. package/skill/task-briefs/projection.md +37 -0
  270. package/skill/task-briefs/retrieve.md +36 -6
  271. package/skill/workflows/decision-and-pilot.md +85 -0
  272. package/skill/workflows/evaluate-and-update.md +93 -0
  273. package/skill/workflows/evidence-review.md +117 -0
  274. package/visualization/eduevidence-report/assets/base.css +2 -2
  275. package/visualization/eduevidence-report/assets/reader.css +752 -0
  276. package/visualization/eduevidence-report/assets/reader.js +132 -0
  277. package/visualization/eduevidence-report/references/chart-selection-catalog.md +109 -0
  278. package/visualization/eduevidence-report/references/lieflat-composition.md +3 -1
  279. package/visualization/eduevidence-report/scripts/build_figures.py +25 -3
  280. package/visualization/eduevidence-report/scripts/build_infographics.py +5 -1
  281. package/visualization/eduevidence-report/scripts/build_report.py +561 -121
  282. package/visualization/eduevidence-report/scripts/charts_data.py +2 -0
  283. package/visualization/eduevidence-report/scripts/lieflat_engine.py +371 -136
  284. package/visualization/eduevidence-report/scripts/zh_labels.py +80 -1
  285. package/visualization/eduevidence-report/themes/academic.css +1 -1
  286. package/visualization/eduevidence-report/themes/claude.css +1 -1
  287. package/visualization/eduevidence-report/themes/datalab-dark.css +2 -2
  288. package/visualization/eduevidence-report/themes/datalab.css +2 -2
  289. package/visualization/eduevidence-report/themes/presentation.css +2 -2
  290. package/web/README.md +18 -0
  291. package/web/architecture.html +14885 -0
  292. package/web/index.html +53 -0
  293. package/web/studio/THIRD_PARTY_LICENSES.txt +146 -0
  294. package/web/studio/assets/index-B8tkF44Q.css +1 -0
  295. package/web/studio/assets/index-CQ6Keoyc.js +230 -0
  296. package/web/studio/config.json +1 -0
  297. package/web/studio/index.html +14 -0
  298. package/engine/__pycache__/__init__.cpython-312.pyc +0 -0
  299. package/engine/__pycache__/analysis.cpython-312.pyc +0 -0
  300. package/engine/__pycache__/bias.cpython-312.pyc +0 -0
  301. package/engine/__pycache__/briefs.cpython-312.pyc +0 -0
  302. package/engine/__pycache__/capabilities.cpython-312.pyc +0 -0
  303. package/engine/__pycache__/citation_check.cpython-312.pyc +0 -0
  304. package/engine/__pycache__/contracts.cpython-312.pyc +0 -0
  305. package/engine/__pycache__/datasets.cpython-312.pyc +0 -0
  306. package/engine/__pycache__/events.cpython-312.pyc +0 -0
  307. package/engine/__pycache__/evidence_graph.cpython-312.pyc +0 -0
  308. package/engine/__pycache__/evidence_review.cpython-312.pyc +0 -0
  309. package/engine/__pycache__/evidencecore.cpython-312.pyc +0 -0
  310. package/engine/__pycache__/gap_lens.cpython-312.pyc +0 -0
  311. package/engine/__pycache__/gaps.cpython-312.pyc +0 -0
  312. package/engine/__pycache__/graph_store.cpython-312.pyc +0 -0
  313. package/engine/__pycache__/graph_validate.cpython-312.pyc +0 -0
  314. package/engine/__pycache__/ids.cpython-312.pyc +0 -0
  315. package/engine/__pycache__/library.cpython-312.pyc +0 -0
  316. package/engine/__pycache__/library_builtin.cpython-312.pyc +0 -0
  317. package/engine/__pycache__/living.cpython-312.pyc +0 -0
  318. package/engine/__pycache__/log.cpython-312.pyc +0 -0
  319. package/engine/__pycache__/meta_analysis.cpython-312.pyc +0 -0
  320. package/engine/__pycache__/meta_synthesis.cpython-312.pyc +0 -0
  321. package/engine/__pycache__/migration.cpython-312.pyc +0 -0
  322. package/engine/__pycache__/mode_router.cpython-312.pyc +0 -0
  323. package/engine/__pycache__/paths.cpython-312.pyc +0 -0
  324. package/engine/__pycache__/pilot.cpython-312.pyc +0 -0
  325. package/engine/__pycache__/planner.cpython-312.pyc +0 -0
  326. package/engine/__pycache__/project.cpython-312.pyc +0 -0
  327. package/engine/__pycache__/projections.cpython-312.pyc +0 -0
  328. package/engine/__pycache__/robustness.cpython-312.pyc +0 -0
  329. package/engine/__pycache__/run.cpython-312.pyc +0 -0
  330. package/engine/__pycache__/semantics.cpython-312.pyc +0 -0
  331. package/engine/__pycache__/study_design.cpython-312.pyc +0 -0
  332. package/engine/__pycache__/synthesis.cpython-312.pyc +0 -0
  333. package/engine/__pycache__/tribunal.cpython-312.pyc +0 -0
  334. package/engine/__pycache__/update.cpython-312.pyc +0 -0
  335. package/engine/__pycache__/versions.cpython-312.pyc +0 -0
  336. package/integrations/__pycache__/__init__.cpython-312.pyc +0 -0
  337. package/integrations/__pycache__/agent_mcp.cpython-312.pyc +0 -0
  338. package/integrations/__pycache__/smart_web_fetch.cpython-312.pyc +0 -0
  339. package/retrieval/__pycache__/__init__.cpython-312.pyc +0 -0
  340. package/retrieval/__pycache__/corpus_store.cpython-312.pyc +0 -0
  341. package/retrieval/__pycache__/dedupe.cpython-312.pyc +0 -0
  342. package/retrieval/__pycache__/failures.cpython-312.pyc +0 -0
  343. package/retrieval/__pycache__/fetch.cpython-312.pyc +0 -0
  344. package/retrieval/__pycache__/search.cpython-312.pyc +0 -0
  345. package/retrieval/__pycache__/source.cpython-312.pyc +0 -0
  346. package/retrieval/__pycache__/validate.cpython-312.pyc +0 -0
  347. package/scripts/__pycache__/__init__.cpython-312.pyc +0 -0
  348. package/scripts/__pycache__/benchmark.cpython-312.pyc +0 -0
  349. package/scripts/__pycache__/benchmark_evaluator.cpython-312.pyc +0 -0
  350. package/scripts/__pycache__/benchmark_judge.cpython-312.pyc +0 -0
  351. package/scripts/__pycache__/benchmark_routing.cpython-312.pyc +0 -0
  352. package/scripts/__pycache__/benchmark_v2.cpython-312.pyc +0 -0
  353. package/scripts/__pycache__/benchmark_v3.cpython-312.pyc +0 -0
  354. package/scripts/__pycache__/build_result.cpython-312.pyc +0 -0
  355. package/scripts/__pycache__/claim_audit.cpython-312.pyc +0 -0
  356. package/scripts/__pycache__/complexity_gate.cpython-312.pyc +0 -0
  357. package/scripts/__pycache__/compute_confidence.cpython-312.pyc +0 -0
  358. package/scripts/__pycache__/dashboard_server.cpython-312.pyc +0 -0
  359. package/scripts/__pycache__/did_regression.cpython-312.pyc +0 -0
  360. package/scripts/__pycache__/effect_calculator.cpython-312.pyc +0 -0
  361. package/scripts/__pycache__/evidence_matrix.cpython-312.pyc +0 -0
  362. package/scripts/__pycache__/evidence_score.cpython-312.pyc +0 -0
  363. package/scripts/__pycache__/evidence_semantics.cpython-312.pyc +0 -0
  364. package/scripts/__pycache__/fetch_benchmark.cpython-312.pyc +0 -0
  365. package/scripts/__pycache__/lint_report_layout.cpython-312.pyc +0 -0
  366. package/scripts/__pycache__/orchestrator.cpython-312.pyc +0 -0
  367. package/scripts/__pycache__/pre_verdict_gate.cpython-312.pyc +0 -0
  368. package/scripts/__pycache__/recompute_demo_quality.cpython-312.pyc +0 -0
  369. package/scripts/__pycache__/render_report.cpython-312.pyc +0 -0
  370. package/scripts/__pycache__/render_report_html.cpython-312.pyc +0 -0
  371. package/scripts/__pycache__/run_workspace.cpython-312.pyc +0 -0
  372. package/scripts/__pycache__/skill_lint.cpython-312.pyc +0 -0
  373. package/scripts/__pycache__/startup_probe.cpython-312.pyc +0 -0
  374. package/scripts/__pycache__/sync_killer_demo_report.cpython-312.pyc +0 -0
  375. package/scripts/__pycache__/test_adversarial_empirical.cpython-312-pytest-9.0.2.pyc +0 -0
  376. package/scripts/__pycache__/test_adversarial_empirical.cpython-312-pytest-9.1.1.pyc +0 -0
  377. package/scripts/__pycache__/validate_schema.cpython-312.pyc +0 -0
  378. package/visualization/eduevidence-report/scripts/__pycache__/adapter_contract.cpython-312.pyc +0 -0
  379. package/visualization/eduevidence-report/scripts/__pycache__/build_artifact_manifest.cpython-312.pyc +0 -0
  380. package/visualization/eduevidence-report/scripts/__pycache__/build_charts.cpython-312.pyc +0 -0
  381. package/visualization/eduevidence-report/scripts/__pycache__/build_figures.cpython-312.pyc +0 -0
  382. package/visualization/eduevidence-report/scripts/__pycache__/build_infographics.cpython-312.pyc +0 -0
  383. package/visualization/eduevidence-report/scripts/__pycache__/build_report.cpython-312.pyc +0 -0
  384. package/visualization/eduevidence-report/scripts/__pycache__/charts_data.cpython-312.pyc +0 -0
  385. package/visualization/eduevidence-report/scripts/__pycache__/lieflat_engine.cpython-312.pyc +0 -0
  386. package/visualization/eduevidence-report/scripts/__pycache__/zh_labels.cpython-312.pyc +0 -0
@@ -0,0 +1,81 @@
1
+ """Shared, explicit runtime allowlist for flat Skills, npm installs and wheels."""
2
+ from __future__ import annotations
3
+
4
+ from pathlib import Path
5
+ import shutil
6
+ import sys
7
+
8
+ TREES = (
9
+ "agents", "engine", "domains", "skill", "references", "schemas", "scripts",
10
+ "retrieval", "integrations", "visualization/eduevidence-report", "web/studio",
11
+ "assets/readme",
12
+ )
13
+ FILES = (
14
+ "SKILL.md", "eduevidence_cli.py", "install.sh", "pyproject.toml", "setup.py",
15
+ "LICENSE", "CHANGELOG.md", "README.md", "README.zh-CN.md", "web/index.html",
16
+ "CONTRIBUTING.md", "web/architecture.html",
17
+ "benchmarks/evidence-library.json", "benchmarks/partitions.json",
18
+ "benchmarks/adversarial/cases.jsonl",
19
+ )
20
+ DOCS = (
21
+ "architecture.md", "demo.md", "demo-storyboard.md", "install-guide.md",
22
+ "reproducibility.md", "release-contract.md", "autoresearch-evolution-plan.md",
23
+ "orchestration-role-model.md", "autoresearch-implementation-status.md",
24
+ "research-studio-guide.zh-CN.md", "demo-workplace-ai.md",
25
+ "sciverse-api.md",
26
+ "release-closeout/README.md", "release-closeout/issues.md",
27
+ "release-closeout/frontend-acceptance.md", "release-closeout/verification.md",
28
+ )
29
+ EXAMPLES = (
30
+ "ai-coding-assistant-evidence", "spaced-retrieval-practice",
31
+ "workplace-ai-assistant",
32
+ )
33
+ EXAMPLE_FILES = (
34
+ "result.json", "result.zh.json", "evidence_graph.json", "report_spec.json",
35
+ "EduEvidence_Report.html", "verdict.json", "evidence.jsonl", "sources.jsonl",
36
+ "frame.json", "methodology.json", "intervention.json", "evaluation.json",
37
+ )
38
+ RETIRED_DEMO_SCRIPTS = {
39
+ "scripts/build_esl_artifacts.py", "scripts/generate_new_projects.py",
40
+ "scripts/enrich_projects_human_and_lieflat.py", "scripts/build_killer_demo.py",
41
+ "scripts/sync_killer_demo_report.py",
42
+ }
43
+
44
+
45
+ def payload_files(root: Path):
46
+ """Yield safe relative files; no symlinks, private state or generated caches."""
47
+ paths = set(FILES)
48
+ paths.update(f"docs/{name}" for name in DOCS)
49
+ for tree in TREES:
50
+ paths.update(p.relative_to(root).as_posix() for p in (root / tree).rglob("*") if p.is_file())
51
+ # Ship configuration, never historical results or private Autoevolve sessions.
52
+ paths.update(f"autoevolve/{name}" for name in ("program.md", "config.yaml", "protected.manifest.yaml"))
53
+ for example in EXAMPLES:
54
+ paths.update(f"examples/{example}/{name}" for name in EXAMPLE_FILES)
55
+ paths.update(p.relative_to(root).as_posix() for p in (root / "examples" / example / "reports-5themes").glob("*.html"))
56
+ for relative in sorted(paths):
57
+ if relative in RETIRED_DEMO_SCRIPTS:
58
+ continue
59
+ path = root / relative
60
+ parts = Path(relative).parts
61
+ if any(p.startswith(".") or p in {"__pycache__", "node_modules", "runs", "venv", "test-results"} for p in parts):
62
+ continue
63
+ if path.suffix in {".pyc", ".pyo", ".log"} or any((root.joinpath(*parts[:i])).is_symlink() for i in range(1, len(parts) + 1)):
64
+ continue
65
+ if path.is_file():
66
+ yield relative
67
+
68
+
69
+ def copy_payload(root: Path, destination: Path) -> None:
70
+ required = ("SKILL.md", "agents/openai.yaml", "web/studio/index.html", "eduevidence_cli.py")
71
+ for name in required:
72
+ if not (root / name).is_file():
73
+ raise FileNotFoundError(f"Incomplete Skill runtime: {name}")
74
+ for relative in payload_files(root):
75
+ output = destination / relative
76
+ output.parent.mkdir(parents=True, exist_ok=True)
77
+ shutil.copy2(root / relative, output)
78
+
79
+
80
+ if __name__ == "__main__":
81
+ copy_payload(Path(sys.argv[1]).resolve(), Path(sys.argv[2]).resolve())
@@ -87,9 +87,8 @@ def test_eventbus_concurrency():
87
87
  t.join()
88
88
 
89
89
  print(f"[*] Concurrent subscribe/unsubscribe completed. Race errors caught: {len(race_errors)}")
90
- if race_errors:
91
- for err in race_errors[:5]:
92
- print(f" - [BUG FOUND] {err}")
90
+ assert not race_errors, (
91
+ f"EventBus raised under concurrent subscribe/unsubscribe: {race_errors[:3]}")
93
92
 
94
93
  # 2. Test Subscribe Non-Atomic Check (Duplicate Subscriber Appending)
95
94
  bus._subscribers.clear()
@@ -105,8 +104,9 @@ def test_eventbus_concurrency():
105
104
  t.join()
106
105
 
107
106
  print(f"[*] Subscribed same callback across 10 threads. Total registered subscribers: {len(bus._subscribers)} (Expected: 1)")
108
- if len(bus._subscribers) > 1:
109
- print(f" - [BUG FOUND] Race condition in subscribe: duplicate callbacks registered ({len(bus._subscribers)})")
107
+ assert len(bus._subscribers) == 1, (
108
+ f"subscribe() is not atomic: {len(bus._subscribers)} copies of one callback "
109
+ "registered from 10 threads")
110
110
 
111
111
  # 3. Concurrent Publish & Unbounded Memory Leak
112
112
  bus.clear()
@@ -156,21 +156,23 @@ def test_did_regression_adversarial():
156
156
  results = {}
157
157
 
158
158
  # Case 2.1: Column Name Parsing Collision
159
+ # Enough rows for a DID fit (n - 4 > 0): this case is about COLUMN MAPPING,
160
+ # not about saturation, so a 4-row fixture would test the wrong thing.
159
161
  with tempfile.NamedTemporaryFile("w", suffix=".csv", delete=False) as f:
160
162
  writer = csv.writer(f)
161
163
  writer.writerow(["student_id", "treatment_group", "post_test_score", "time_period"])
162
- writer.writerow([1, 1, 85.0, 1])
163
- writer.writerow([2, 1, 70.0, 0])
164
- writer.writerow([3, 0, 80.0, 1])
165
- writer.writerow([4, 0, 75.0, 0])
164
+ for i in range(1, 13):
165
+ treat = 1 if i % 2 else 0
166
+ post = 1 if i % 3 else 0
167
+ writer.writerow([i, treat, 60.0 + 4 * treat + 3 * post + 2 * treat * post, post])
166
168
  col_test_path = f.name
167
169
 
168
170
  res_col = run_did_analysis(col_test_path)
169
171
  os.remove(col_test_path)
170
172
  print(f"[*] Case 2.1: Column name collision ('treatment_group', 'post_test_score', 'time_period'):")
171
173
  print(f" Result: {res_col}")
172
- if res_col.get("status") == "error":
173
- print(f" - [BUG FOUND] Column mapper failed to parse outcome column due to 'post' keyword priority collision!")
174
+ assert res_col.get("status") != "error", (
175
+ "DID column mapper failed to parse the outcome column (keyword collision)")
174
176
  results["column_mapping_bug"] = res_col
175
177
 
176
178
  # Case 2.2: Perfect Multicollinearity / Singular Design Matrix
@@ -187,8 +189,10 @@ def test_did_regression_adversarial():
187
189
  os.remove(collinear_path)
188
190
  print(f"\n[*] Case 2.2: Singular Matrix / Perfect Multicollinearity:")
189
191
  print(f" Result: {json.dumps(res_coll, indent=2)}")
190
- if res_coll.get("status") == "success" and res_coll.get("standard_error") == 1.0:
191
- print(f" - [BUG FOUND] Matrix inversion failed on singular matrix, but returned fake standard_error=1.0 and fake p_value={res_coll.get('p_value')} instead of reporting collinearity/singular error!")
192
+ assert not (res_coll.get("status") == "success"
193
+ and res_coll.get("standard_error") == 1.0), (
194
+ "singular design matrix produced a fabricated standard error of 1.0 "
195
+ "instead of reporting collinearity")
192
196
  results["singular_matrix_fallback"] = res_coll
193
197
 
194
198
  # Case 2.3: Zero Variance in Outcome
@@ -228,8 +232,9 @@ def test_did_regression_adversarial():
228
232
  # Case 2.5: WWC Baseline Equivalence Rating for QED
229
233
  print(f"\n[*] Case 2.5: WWC 5.0 Baseline Rating Check for QED:")
230
234
  print(f" When baseline_equivalence_g = {res_sat.get('baseline_equivalence_g')}, WWC rating reported is: '{res_sat.get('wwc_baseline_rating')}'")
231
- if res_sat.get("wwc_baseline_rating") == "Meets Standards Without Reservations":
232
- print(f" - [BUG FOUND] Methodological violation: Quasi-Experimental Designs (QED/DID) can NEVER meet WWC standards without reservations; maximum possible rating is 'Meets Standards With Reservations'!")
235
+ assert res_sat.get("wwc_baseline_rating") != "Meets Standards Without Reservations", (
236
+ "methodological violation: a quasi-experimental design was rated as meeting "
237
+ "WWC standards without reservations")
233
238
  results["wwc_rating_bug"] = res_sat.get("wwc_baseline_rating")
234
239
 
235
240
  # Case 2.6: Small Sample Normal Z-Test vs Student t-distribution
@@ -307,8 +312,8 @@ def test_evidence_graph_adversarial():
307
312
  print(f"[*] Meta-synthesis with NaN effect and negative weight:")
308
313
  print(f" - Pooled g: {proc_syn.get('pooled_g')}")
309
314
  print(f" - Q statistic: {proc_syn.get('q_statistic')}")
310
- if math.isnan(proc_syn.get("pooled_g", 0.0)):
311
- print(f" - [BUG FOUND] NaN effect size propagated directly into meta_synthesis without input validation!")
315
+ assert not math.isnan(proc_syn.get("pooled_g", 0.0)), (
316
+ "NaN effect size propagated into meta-synthesis without validation")
312
317
 
313
318
  return {
314
319
  "json_roundtrip": len(reloaded.edges),
@@ -495,8 +500,10 @@ def test_dashboard_server_adversarial():
495
500
  except Exception as e:
496
501
  leakage_results[tf] = False
497
502
 
498
- if any(leakage_results.values()):
499
- print(f" - [SECURITY DEFECT] StudioHandler exposes arbitrary local project source files through unauthenticated HTTP GET via super().do_GET() fallback!")
503
+ leaked = [path for path, ok in leakage_results.items() if ok]
504
+ assert not leaked, (
505
+ "StudioHandler served local source files over unauthenticated GET: "
506
+ f"{leaked}")
500
507
  results["file_leakage"] = leakage_results
501
508
 
502
509
  # 3. Concurrency Stress Test (30 Concurrent HTTP Clients)
@@ -3,7 +3,8 @@
3
3
 
4
4
  Zero-dependency JSON Schema (draft-07 subset) validator covering the constructs
5
5
  used by schemas/*.schema.json: $id, title, description, type, properties,
6
- required, enum, minimum, maximum, minLength, additionalProperties, $ref
6
+ required, enum, minimum, maximum, minLength, additionalProperties, $ref,
7
+ anyOf / oneOf / allOf
7
8
  (local #/definitions and relative-file references), const, format (uri,
8
9
  date-time), pattern.
9
10
 
@@ -121,9 +122,52 @@ class Validator:
121
122
  """Validate `value` against `schema` (draft-07 subset). Raises SchemaError."""
122
123
  if "$ref" in schema:
123
124
  # draft-07: $ref replaces sibling keywords entirely
124
- self.validate(value, self._resolve_ref(schema["$ref"], path), path)
125
+ ref = schema["$ref"]
126
+ if not ref.startswith("#") and self.base_dir is not None:
127
+ filename, _, fragment = ref.partition("#")
128
+ target = self.base_dir / filename
129
+ if not target.is_file():
130
+ raise SchemaError(f"{path}: unresolvable $ref {ref!r}")
131
+ cache_key = str(target.resolve())
132
+ if cache_key not in self._ref_cache:
133
+ self._ref_cache[cache_key] = json.loads(target.read_text(encoding="utf-8"))
134
+ document = self._ref_cache[cache_key]
135
+ validator = Validator(document, base_dir=target.parent)
136
+ referenced = validator._resolve_ref("#" + fragment, path) if fragment else document
137
+ validator.validate(value, referenced, path)
138
+ else:
139
+ self.validate(value, self._resolve_ref(ref, path), path)
125
140
  return
126
141
 
142
+ # Combinators (draft-07 subset): anyOf / oneOf / allOf. Without
143
+ # these a schema can express a real alternative shape and be
144
+ # silently ignored - which is how report-spec (two accepted
145
+ # shapes) and visual-layout (oneOf) became dead weight.
146
+ for key in ("anyOf", "oneOf", "allOf"):
147
+ subschemas = schema.get(key)
148
+ if not isinstance(subschemas, list) or not subschemas:
149
+ continue
150
+ matched = 0
151
+ first_error = None
152
+ for sub in subschemas:
153
+ try:
154
+ self.validate(value, sub, path)
155
+ matched += 1
156
+ except SchemaError as exc:
157
+ if first_error is None:
158
+ first_error = exc
159
+ if key == "allOf" and matched != len(subschemas):
160
+ raise first_error or SchemaError(
161
+ f"{path}: allOf not satisfied")
162
+ if key in ("anyOf", "oneOf") and matched == 0:
163
+ detail = f" (first: {first_error})" if first_error else ""
164
+ raise SchemaError(
165
+ f"{path}: matches none of the {key} alternatives" + detail)
166
+ if key == "oneOf" and matched > 1:
167
+ raise SchemaError(
168
+ f"{path}: matches {matched} oneOf alternatives "
169
+ "(exactly one required)")
170
+
127
171
  if "type" in schema:
128
172
  types = schema["type"]
129
173
  if isinstance(types, str):
@@ -0,0 +1,133 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import json
5
+ from pathlib import Path
6
+
7
+ try:
8
+ from research_auto_cli import research_auto
9
+ except ImportError: # imported as scripts.vnext_cli in tests/package contexts
10
+ from scripts.research_auto_cli import research_auto
11
+
12
+
13
+ def _read_json(path, default=None):
14
+ if not path:
15
+ return default
16
+ return json.loads(Path(path).read_text(encoding="utf-8"))
17
+
18
+
19
+ def evolve(argv):
20
+ parser = argparse.ArgumentParser(prog="eduevidence evolve")
21
+ sub = parser.add_subparsers(dest="action", required=True)
22
+ for name in ("init", "status", "report", "best"):
23
+ cmd = sub.add_parser(name)
24
+ cmd.add_argument("--root", default=".")
25
+ cmd = sub.add_parser("baseline")
26
+ cmd.add_argument("--root", default=".")
27
+ cmd.add_argument("--eval", required=True)
28
+ cmd = sub.add_parser("run")
29
+ cmd.add_argument("--root", default=".")
30
+ cmd.add_argument("--experiment", required=True)
31
+ cmd.add_argument("--baseline-eval", required=True)
32
+ cmd.add_argument("--candidate-eval", required=True)
33
+ cmd = sub.add_parser("prepare-pr")
34
+ cmd.add_argument("--root", default=".")
35
+ args = parser.parse_args(argv)
36
+ repo = Path(args.root).resolve()
37
+ root = repo / "autoevolve"
38
+ root.mkdir(parents=True, exist_ok=True)
39
+ from engine.autoevolve import (
40
+ DailyProfile,
41
+ EvalSnapshot,
42
+ ExperimentLog,
43
+ PlateauTracker,
44
+ ProtectedManifest,
45
+ SkillExperiment,
46
+ promote,
47
+ )
48
+ if args.action == "init":
49
+ DailyProfile().validate()
50
+ (root / "runs").mkdir(exist_ok=True)
51
+ if not (root / "best.json").exists():
52
+ (root / "best.json").write_text('{"best_experiment_id": null}\n', encoding="utf-8")
53
+ ExperimentLog(root)
54
+ print(root)
55
+ return 0
56
+ if args.action in {"status", "report"}:
57
+ rows = (
58
+ (root / "results.tsv").read_text(encoding="utf-8").splitlines()[1:]
59
+ if (root / "results.tsv").exists()
60
+ else []
61
+ )
62
+ best = _read_json(root / "best.json", {}) or {}
63
+ statuses = [row.split("\t")[-2] for row in rows if "\t" in row]
64
+ print(
65
+ json.dumps(
66
+ {
67
+ "experiments": len(rows),
68
+ "best": best,
69
+ "plateau": PlateauTracker().plateau(statuses),
70
+ },
71
+ indent=2,
72
+ )
73
+ )
74
+ return 0
75
+ if args.action == "best":
76
+ print(json.dumps(_read_json(root / "best.json", {}), indent=2))
77
+ return 0
78
+ if args.action == "baseline":
79
+ data = _read_json(args.eval)
80
+ (root / "baseline.json").write_text(
81
+ json.dumps(data, indent=2) + "\n", encoding="utf-8"
82
+ )
83
+ print(data.get("eval_id", "baseline"))
84
+ return 0
85
+ if args.action == "run":
86
+ experiment = SkillExperiment(**_read_json(args.experiment))
87
+ baseline = EvalSnapshot(**_read_json(args.baseline_eval))
88
+ candidate = EvalSnapshot(**_read_json(args.candidate_eval))
89
+ manifest = ProtectedManifest.from_repo(repo)
90
+ ok, bad = manifest.validate_changes(experiment.changed_files)
91
+ scope_ok, scope_bad = manifest.validate_mutation_scope(
92
+ experiment.changed_files,
93
+ mutation_tiers=experiment.mutation_scope,
94
+ allow_controlled="controlled" in experiment.mutation_scope,
95
+ )
96
+ if not ok:
97
+ status, reason = "INVALID", "protected mutation: " + ",".join(bad)
98
+ elif not scope_ok:
99
+ status, reason = "INVALID", "mutation outside approved tier: " + ",".join(scope_bad)
100
+ else:
101
+ status, reason = promote(baseline, candidate)
102
+ experiment.status = status
103
+ experiment.promotion_reason = reason
104
+ ExperimentLog(root).append(experiment, candidate=candidate, description=reason)
105
+ if status == "KEEP":
106
+ (root / "best.json").write_text(
107
+ json.dumps(
108
+ {
109
+ "best_experiment_id": experiment.experiment_id,
110
+ "candidate_commit": experiment.candidate_commit,
111
+ "eval_id": candidate.eval_id,
112
+ },
113
+ indent=2,
114
+ )
115
+ + "\n",
116
+ encoding="utf-8",
117
+ )
118
+ print(json.dumps({"status": status, "reason": reason}, indent=2))
119
+ return 0
120
+ if args.action == "prepare-pr":
121
+ best = _read_json(root / "best.json", {}) or {}
122
+ print(
123
+ json.dumps(
124
+ {
125
+ "promotion": "branch_only",
126
+ "best": best,
127
+ "note": "Human approval is required to open/merge the final PR.",
128
+ },
129
+ indent=2,
130
+ )
131
+ )
132
+ return 0
133
+ return 2
package/setup.py ADDED
@@ -0,0 +1,12 @@
1
+ """Include the same runtime resources as the flat Skill in installed wheels."""
2
+ from pathlib import Path
3
+ import runpy
4
+ from setuptools import setup
5
+
6
+ root = Path(__file__).resolve().parent
7
+ payload_files = runpy.run_path(str(root / "scripts" / "skill_payload.py"))["payload_files"]
8
+ groups = {}
9
+ for relative in payload_files(root):
10
+ destination = str(Path("share/eduevidence") / Path(relative).parent)
11
+ groups.setdefault(destination, []).append(relative)
12
+ setup(data_files=sorted(groups.items()))
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  name: evaluation-designer
3
3
  description: EduEvidence 效果评价设计者。为任何 PILOT/ADOPT 建议附 EvaluationPlan:基线/后测/保持/迁移 + 过程/学习/风险指标 + 成功阈值与停止条件;区分任务表现与学习效果。
4
- default_cli: claude
5
- default_model: claude-sonnet-4-6
4
+ role_id: evaluation-designer
5
+ capabilities: evaluation_design, data_validation, data_analysis
6
+ output_contracts: evaluation.json (schemas/evaluation.schema.json)
7
+ recommended_reasoning: high # capability hint only — no model or CLI name is bound here
6
8
  default_permission: read
7
9
  default_summary_chars: 800
8
10
  default_context_mode: compact
@@ -54,7 +56,7 @@ critical_path: false
54
56
  - `groups` 是对象,必须含 `treatment` 与 `comparison` 两个字段;
55
57
  - `process_metrics` / `learning_metrics` / `risk_metrics` / `stop_conditions` 必须都是**数组**,禁止逗号拼接字符串;
56
58
  - `retention_test` / `transfer_test` 是字符串或 `null`——没有延迟/迁移测试时必须显式写 `null`,禁止缺失字段;
57
- - `risk_metrics` 必须覆盖 AI 教学风险(如 `ai_dependency`、`academic_integrity_risk`、`false_confidence`,红线要求),缺失即不合格;
59
+ - `risk_metrics` 必须覆盖该干预的相关风险(教育场景如 `ai_dependency`、`academic_integrity_risk`、`false_confidence`;其他领域用其自身风险构念),缺失即不合格;
58
60
  - `analysis_plan` 必须写明统计方法(如基线调整 ANCOVA),且任务表现与学习指标分开报告;
59
61
  - `learning_metrics` 不得只含 self-report(红线),至少一项客观/行为指标。
60
62
 
@@ -63,7 +65,7 @@ critical_path: false
63
65
  - 只测任务完成速度的评价方案 → 不合格,必须补学习/保持/迁移指标;
64
66
  - 迁移测试必须是**无 AI 环境**的新任务;
65
67
  - 不许把 self-report 当作唯一的学习指标;
66
- - 风险指标缺失 → 不合格(AI 教学试点必须测 AI 依赖与学术诚信风险)。
68
+ - 风险指标缺失 → 不合格(任何 AI 相关试点都必须测依赖与诚信/合规风险)。
67
69
 
68
70
  ## 输出格式
69
71
 
@@ -72,3 +74,17 @@ critical_path: false
72
74
  ## 卡住升级
73
75
 
74
76
  干预方案缺失回传 `NEEDS_CONTEXT`;课堂现实约束不明回传 `NEEDS_USER_CONTEXT`。
77
+
78
+ ## 独立性与交叉评审
79
+
80
+ - 阈值在数据到达前固定;事后调整属协议偏离,必须记录而非吸收。
81
+ - 与分析阶段的独立性:评价设计者不参与对结果的解释,避免"自己设计自己解释"。
82
+ - 与宿主的模型选择解耦:本文件只声明能力要求(`recommended_reasoning: high`、量化偏好),具体 CLI/模型由用户确认的模型映射决定。
83
+
84
+ ## 失败模式与回退
85
+
86
+ | 失败 | 处理 |
87
+ |---|---|
88
+ | 无法设置对照 | 改为单组前后测并显式标注设计局限。 |
89
+ | 样本量不足 | 报告功效局限;不得把不显著当作"无效果"。 |
90
+ | 阈值事后变更 | 记录为协议偏离并降级结论强度。 |
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  name: evidence-analyst
3
3
  description: EduEvidence 证据分析者。把候选 Source 抽取为 Claim-Level Evidence Object(绑定 Outcome、direction、quality_dimensions),执行 Outcome Separation;只结构化,不裁决。
4
- default_cli: claude
5
- default_model: claude-sonnet-4-6
4
+ role_id: evidence-analyst
5
+ capabilities: study_extraction, finding_extraction, claim_linking
6
+ output_contracts: evidence.jsonl (schemas/evidence.schema.json)
7
+ recommended_reasoning: medium+ # capability hint only — no model or CLI name is bound here
6
8
  default_permission: read
7
9
  default_summary_chars: 1200
8
10
  default_context_mode: full
@@ -81,7 +83,7 @@ critical_path: true
81
83
 
82
84
  - `relation_to_claim`:该证据支持/反驳某条 claim(Claim Audit 只依据此字段);
83
85
  - `effect_direction`:研究观察到的效应方向(Outcome 可视化/聚合只依据此字段);
84
- - `decision_relation`:对最终教学决策的意义(Consistency/Tribunal 依据此字段);
86
+ - `decision_relation`:对最终决策的意义(Consistency/Tribunal 依据此字段);
85
87
  - 旧字段 `direction` 已废弃(deprecated),优先使用 `relation_to_claim`,不要再新写。
86
88
 
87
89
  **类型/格式硬约束(FIX-2 实测违规项,逐条禁止)**:
@@ -104,3 +106,17 @@ critical_path: true
104
106
  ## 卡住升级
105
107
 
106
108
  原文不可得回传 `NEEDS_CONTEXT: <缺哪篇原文>`;原文声称与抽取冲突回传 BLOCKED 并说明。
109
+
110
+ ## 独立性与交叉评审
111
+
112
+ - 抽取只结构化、不裁决;`relation_to_claim` 的最终归属由 Evidence Judge 在裁决阶段复核。
113
+ - 与宿主的模型选择解耦:本文件只声明能力要求(`recommended_reasoning: medium+`、结构化输出强),具体 CLI/模型由用户确认的模型映射决定。
114
+
115
+ ## 失败模式与回退
116
+
117
+ | 失败 | 处理 |
118
+ |---|---|
119
+ | 强制字段缺失 | 该对象标 `UNSUPPORTED`,不得带缺陷进入合成。 |
120
+ | 原文不可得 | `NEEDS_CONTEXT: <缺哪篇原文>`;禁止从摘要或记忆补全。 |
121
+ | 原文与结论冲突 | 回传 BLOCKED 并说明冲突点,交审计阶段处理。 |
122
+ | 统计量未报告 | 保持缺失,禁止由显著性反推。 |
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  name: evidence-judge
3
3
  description: EduEvidence 证据裁决者。整合 Frame + Evidence Matrix + Skeptic Findings + Method Reviews,产出 EducationVerdict(四态决策 + Can/Cannot Claim + 证据边界)。
4
- default_cli: claude
5
- default_model: claude-opus-4-6
4
+ role_id: evidence-judge
5
+ capabilities: evidence_synthesis, tribunal, applicability_analysis, knowledge_gap_detection
6
+ output_contracts: final_verdict.json (schemas/verdict.schema.json), applicability.json
7
+ recommended_reasoning: highest # capability hint only — no model or CLI name is bound here
6
8
  default_permission: read
7
9
  default_summary_chars: 1000
8
10
  default_context_mode: full
@@ -61,10 +63,42 @@ critical_path: true
61
63
  "missing_evidence": ["..."],
62
64
  "recommended_action": "adopt|pilot|reject|insufficient_evidence",
63
65
  "decision_rationale": "...",
66
+ "strongest_support": "...",
67
+ "key_uncertainty": "...",
68
+ "main_risk": "...",
69
+ "next_action": "...",
64
70
  "exceeds_evidence_boundary": ["..."]
65
71
  }
66
72
  ```
67
73
 
74
+ ## 读者向决策叙事(四件套 · 硬要求)
75
+
76
+ 以下四个字段是**成品文案**,不是字段摘录:必须由你一次写成完整句子,
77
+ 渲染器只负责呈现,缺字段就显示「未产出」。规范见 `references/report-copy-style.md`。
78
+
79
+ | 字段 | 内容 | 字数上限(中文) |
80
+ |---|---|---|
81
+ | `strongest_support` | 证据支持的最强结论,一句话说清 | ≤60 字 |
82
+ | `key_uncertainty` | 与决策相关的最大不确定性或反证 | ≤70 字 |
83
+ | `main_risk` | 采取行动的主要风险 | ≤60 字 |
84
+ | `next_action` | 建议的下一步 | ≤80 字 |
85
+
86
+ 写作要求:
87
+
88
+ - 每条都是可独立阅读的完整句子;读者不需要看别的字段就能理解。
89
+ - 面向非本领域决策者;先结论、后依据;一句话一个意思。
90
+ - 禁止出现内部字段名、存储标识、证据 ID 列表(`E-001、E-006`);引用研究用「作者-年份 + 人话描述」。
91
+ - 缺失信息如实写「尚无直接证据」,不要用模糊措辞掩盖。
92
+ - en / zh 两版各自成篇,语义对齐而非逐字直译。
93
+
94
+ 反例(渲染器拼装出来的读感,禁止):
95
+
96
+ ```text
97
+ ❌ 下一步:当前结果未提供此项信息。
98
+ ❌ 最强支持结论:AI 编程助手在训练期提升新手任务表现。(从 what_can_be_claimed[0] 截取)
99
+ ✅ 下一步:开展分阶段 CS1 试点——给提示而非答案、每周实验课使用,并以无 AI 迁移考试作为可叫停的验收条件。
100
+ ```
101
+
68
102
  ## 输出契约(必须遵守)
69
103
 
70
104
  你的产物 `final_verdict.json` 必须通过 `schemas/verdict.schema.json` 校验(stage `adjudicate` 的 schema-gate,首次生成即必须合规)。schema 顶层 `additionalProperties: false`,未列出的字段一律放入 `extensions`。
@@ -109,3 +143,17 @@ critical_path: true
109
143
  - **禁止**在理由与主张列表里堆证据 ID(E-xxx / EV-xxx)、来源码(PAP-xxx)或 schema 键(overall_risk=、CONCERN 等);引用研究用"作者-年份 + 人话描述"(如"带护栏组独立考试未见下滑");
110
144
  - `what_can_be_claimed / what_cannot_be_claimed / missing_evidence / exceeds_evidence_boundary` 同样人话化;统计数字可保留,但用自然表达("效应量 +0.61,差异显著");
111
145
  - 无截断残留(null、…)、无中英夹生;en/zh 两个语版分写,语义对齐而非机翻。
146
+
147
+ ## 独立性与交叉评审
148
+
149
+ - 裁决以证据矩阵、反证与审计三路输入为准,不以任一单路由结论为准;交叉审核输出须符合 `schemas/cross-model-review.schema.json`。
150
+ - 与宿主的模型选择解耦:本文件只声明能力要求(`recommended_reasoning: highest`、结构化输出强),具体 CLI/模型由用户确认的模型映射决定。
151
+
152
+ ## 失败模式与回退
153
+
154
+ | 失败 | 处理 |
155
+ |---|---|
156
+ | `PRE_VERDICT_FAILED` | 修复前置产物后重跑闸门,不得跳过。 |
157
+ | `GATE_CRITICAL_FAILURE` | 封顶置信度,强制降级为 PILOT 或 INSUFFICIENT EVIDENCE。 |
158
+ | `CONFLICT_UNRESOLVED` | 保持不确定,不强行裁决。 |
159
+ | 证据只支持任务表现 | 不得产出学习效果类结论。 |
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  name: evidence-retriever
3
3
  description: EduEvidence 证据检索者。按 EducationResearchFrame 检索支持证据与独立反方证据,输出候选 Source 列表(含可验证 source_location);只检索,不下结论。
4
- default_cli: omp
5
- default_model: fast-low-cost
4
+ role_id: evidence-retriever
5
+ capabilities: literature_search, counter_evidence_search, source_fetch, source_validation
6
+ output_contracts: sources.jsonl (schemas/source.schema.json), fetch/
7
+ recommended_reasoning: high # capability hint only — no model or CLI name is bound here
6
8
  default_permission: read
7
9
  default_summary_chars: 1000
8
10
  default_context_mode: compact
@@ -13,7 +15,7 @@ critical_path: false
13
15
 
14
16
  ## 职责
15
17
 
16
- 1. 按 Frame 的 learner/intervention/comparison/outcomes/scope 构造检索式;
18
+ 1. 按 Frame 的 population/intervention/comparison/outcomes/scope 构造检索式(字段词汇随领域而定);
17
19
  2. **双路检索**:一路找支持证据,一路独立找反方证据(null result / negative result / contradictory evidence / AI dependency / reduced transfer);
18
20
  3. 优先 RCT / quasi-experimental / meta-analysis,标注 study_type;
19
21
  4. 每条来源必须有可验证 `source_location`(DOI / URL / 数据库标识)——没有位置=无效来源;
@@ -78,3 +80,18 @@ critical_path: false
78
80
  ## 卡住升级
79
81
 
80
82
  检索工具不可用回传 `TOOL_FAILURE: <工具 + 现象>`;检索结果为零且无法扩大范围回传 `INSUFFICIENT_SOURCES`。
83
+
84
+ ## 独立性与交叉评审
85
+
86
+ - 反方检索必须独立构造检索式,不复用支持证据的查询;其结果由 Skeptic 独立复核,不由本角色判定"是否充分"。
87
+ - 与宿主的模型选择解耦:本文件只声明能力要求(`recommended_reasoning: high`、`tool_use: strong`、成本低),具体 CLI/模型由用户确认的模型映射决定。
88
+
89
+ ## 失败模式与回退
90
+
91
+ | 失败 | 处理 |
92
+ |---|---|
93
+ | `TOOL_FAILURE` | 记录工具与现象,切换等价通道后重试;不得凭记忆补来源。 |
94
+ | `SEARCH_NO_RESULT` | 放宽词族、切换 provider,或落 negative-search record;不静默降低标准。 |
95
+ | `FETCH_FAILED` | 走 provider 降级链;链尽则弃用该来源。 |
96
+ | `SOURCE_INVALID` / `SOURCE_DUPLICATE` | 弃用 / 合并(保留最高权威等级)。 |
97
+ | `INSUFFICIENT_SOURCES` | 如实上报,不用低权威来源凑数。 |
@@ -1,15 +1,17 @@
1
1
  ---
2
2
  name: intervention-designer
3
- description: EduEvidence 教学干预设计者。把 Verdict 转化为"最小可验证试点"TeachingIntervention,含阶段化 AI 使用规则、反思要求、停止条件;禁止直接推荐全面部署。
4
- default_cli: claude
5
- default_model: claude-sonnet-4-6
3
+ description: EduEvidence 干预设计者。把 Verdict 转化为"最小可验证试点":阶段化使用规则、护栏、停止条件与证据对齐;禁止直接推荐全面部署。干预对象随领域而定(教学 / 政策 / 组织流程)。
4
+ role_id: intervention-designer
5
+ capabilities: study_design, measurement_design, intervention_design
6
+ output_contracts: intervention.json (schemas/intervention.schema.json)
7
+ recommended_reasoning: high # capability hint only — no model or CLI name is bound here
6
8
  default_permission: read
7
9
  default_summary_chars: 800
8
10
  default_context_mode: compact
9
11
  critical_path: false
10
12
  ---
11
13
 
12
- 你是 EduEvidence 的 **Intervention Designer**。你的产出必须是从证据长出来的试点方案,而不是凭空的教学创意。
14
+ 你是 EduEvidence 的 **Intervention Designer**。你的产出必须是从证据长出来的试点方案,而不是凭空的创意。
13
15
 
14
16
  ## 职责
15
17
 
@@ -80,3 +82,17 @@ critical_path: false
80
82
  ## 卡住升级
81
83
 
82
84
  Verdict 缺失回传 `NEEDS_CONTEXT`;用户课堂约束不明回传 `NEEDS_USER_CONTEXT: <缺什么>`。
85
+
86
+ ## 独立性与交叉评审
87
+
88
+ - 设计必须引用显式 KnowledgeGap ID;是否存在合格缺口由 Gap Analysis 与 StudyDesign 门判定,不由本角色自证。
89
+ - 涉及学生数据与对照分组时,先过 `skill/sub-skills/ethics-review/SKILL.md`。
90
+ - 与宿主的模型选择解耦:本文件只声明能力要求(`recommended_reasoning: high`),具体 CLI/模型由用户确认的模型映射决定。
91
+
92
+ ## 失败模式与回退
93
+
94
+ | 失败 | 处理 |
95
+ |---|---|
96
+ | 无 KnowledgeGap | 不设计研究,改为报告"还需要什么证据"。 |
97
+ | 伦理审查未通过 | 阻断试点,先修正设计。 |
98
+ | 人群越出适用边界 | 缩小试点人群至支持范围内。 |