eduevidence 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +506 -0
- package/README.zh-CN.md +434 -0
- package/SKILL.md +195 -0
- package/bin/eduevidence.js +127 -0
- package/domains/education/manifest.json +183 -0
- package/domains/education/outcome_taxonomy.json +127 -0
- package/domains/manifest.json +26 -0
- package/domains/policy/frame.schema.json +234 -0
- package/domains/policy/manifest.json +10 -0
- package/domains/policy/methodology_checklist.json +109 -0
- package/domains/policy/outcome_taxonomy.json +53 -0
- package/domains/policy/references/causal-identification.md +45 -0
- package/domains/policy/references/cost-evidence.md +44 -0
- package/domains/policy/references/equity.md +42 -0
- package/domains/policy/references/evidence-hierarchy.md +41 -0
- package/domains/policy/references/implementation-evidence.md +47 -0
- package/eduevidence_cli.py +26 -0
- package/engine/__init__.py +11 -0
- package/engine/__pycache__/__init__.cpython-312.pyc +0 -0
- package/engine/__pycache__/analysis.cpython-312.pyc +0 -0
- package/engine/__pycache__/bias.cpython-312.pyc +0 -0
- package/engine/__pycache__/briefs.cpython-312.pyc +0 -0
- package/engine/__pycache__/capabilities.cpython-312.pyc +0 -0
- package/engine/__pycache__/citation_check.cpython-312.pyc +0 -0
- package/engine/__pycache__/contracts.cpython-312.pyc +0 -0
- package/engine/__pycache__/datasets.cpython-312.pyc +0 -0
- package/engine/__pycache__/events.cpython-312.pyc +0 -0
- package/engine/__pycache__/evidence_graph.cpython-312.pyc +0 -0
- package/engine/__pycache__/evidence_review.cpython-312.pyc +0 -0
- package/engine/__pycache__/evidencecore.cpython-312.pyc +0 -0
- package/engine/__pycache__/gap_lens.cpython-312.pyc +0 -0
- package/engine/__pycache__/gaps.cpython-312.pyc +0 -0
- package/engine/__pycache__/graph_store.cpython-312.pyc +0 -0
- package/engine/__pycache__/graph_validate.cpython-312.pyc +0 -0
- package/engine/__pycache__/ids.cpython-312.pyc +0 -0
- package/engine/__pycache__/library.cpython-312.pyc +0 -0
- package/engine/__pycache__/library_builtin.cpython-312.pyc +0 -0
- package/engine/__pycache__/living.cpython-312.pyc +0 -0
- package/engine/__pycache__/log.cpython-312.pyc +0 -0
- package/engine/__pycache__/meta_analysis.cpython-312.pyc +0 -0
- package/engine/__pycache__/meta_synthesis.cpython-312.pyc +0 -0
- package/engine/__pycache__/migration.cpython-312.pyc +0 -0
- package/engine/__pycache__/mode_router.cpython-312.pyc +0 -0
- package/engine/__pycache__/paths.cpython-312.pyc +0 -0
- package/engine/__pycache__/pilot.cpython-312.pyc +0 -0
- package/engine/__pycache__/planner.cpython-312.pyc +0 -0
- package/engine/__pycache__/project.cpython-312.pyc +0 -0
- package/engine/__pycache__/projections.cpython-312.pyc +0 -0
- package/engine/__pycache__/robustness.cpython-312.pyc +0 -0
- package/engine/__pycache__/run.cpython-312.pyc +0 -0
- package/engine/__pycache__/semantics.cpython-312.pyc +0 -0
- package/engine/__pycache__/study_design.cpython-312.pyc +0 -0
- package/engine/__pycache__/synthesis.cpython-312.pyc +0 -0
- package/engine/__pycache__/tribunal.cpython-312.pyc +0 -0
- package/engine/__pycache__/update.cpython-312.pyc +0 -0
- package/engine/__pycache__/versions.cpython-312.pyc +0 -0
- package/engine/analysis.py +308 -0
- package/engine/bias.py +178 -0
- package/engine/briefs.py +106 -0
- package/engine/capabilities.py +99 -0
- package/engine/citation_check.py +192 -0
- package/engine/contracts.py +117 -0
- package/engine/datasets.py +165 -0
- package/engine/events.py +67 -0
- package/engine/evidence_graph.py +571 -0
- package/engine/evidence_review.py +88 -0
- package/engine/evidencecore.py +182 -0
- package/engine/gap_lens.py +132 -0
- package/engine/gaps.py +169 -0
- package/engine/graph_store.py +335 -0
- package/engine/graph_validate.py +87 -0
- package/engine/ids.py +77 -0
- package/engine/library.py +268 -0
- package/engine/library_builtin.py +301 -0
- package/engine/living.py +671 -0
- package/engine/log.py +39 -0
- package/engine/meta_analysis.py +333 -0
- package/engine/meta_synthesis.py +111 -0
- package/engine/migration.py +397 -0
- package/engine/mode_router.py +72 -0
- package/engine/paths.py +15 -0
- package/engine/pilot.py +368 -0
- package/engine/planner.py +126 -0
- package/engine/project.py +118 -0
- package/engine/projections.py +240 -0
- package/engine/robustness.py +109 -0
- package/engine/run.py +85 -0
- package/engine/semantics.py +135 -0
- package/engine/study_design.py +87 -0
- package/engine/synthesis.py +187 -0
- package/engine/tribunal.py +408 -0
- package/engine/update.py +113 -0
- package/engine/versions.py +12 -0
- package/install.sh +510 -0
- package/integrations/__init__.py +1 -0
- package/integrations/__pycache__/__init__.cpython-312.pyc +0 -0
- package/integrations/__pycache__/agent_mcp.cpython-312.pyc +0 -0
- package/integrations/__pycache__/smart_web_fetch.cpython-312.pyc +0 -0
- package/integrations/agent_mcp.py +856 -0
- package/integrations/smart_web_fetch.py +59 -0
- package/package.json +50 -0
- package/pyproject.toml +55 -0
- package/references/applicability-policy.md +88 -0
- package/references/education-framing.md +132 -0
- package/references/effect_size_formulas.md +35 -0
- package/references/evaluation-design.md +111 -0
- package/references/evidence-quality.md +79 -0
- package/references/grade_framework.md +29 -0
- package/references/intervention-design.md +98 -0
- package/references/methodology-audit.md +103 -0
- package/references/outcome-taxonomy.md +106 -0
- package/references/retrieval-protocol.md +142 -0
- package/references/skeptic-protocol.md +93 -0
- package/references/social_science_pitfalls.md +48 -0
- package/references/source-validity.md +140 -0
- package/references/tribunal-policy.md +112 -0
- package/references/wwc_standards.md +29 -0
- package/retrieval/__init__.py +1 -0
- package/retrieval/__pycache__/__init__.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/corpus_store.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/dedupe.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/failures.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/fetch.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/search.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/source.cpython-312.pyc +0 -0
- package/retrieval/__pycache__/validate.cpython-312.pyc +0 -0
- package/retrieval/corpus_store.py +181 -0
- package/retrieval/dedupe.py +127 -0
- package/retrieval/failures.py +90 -0
- package/retrieval/fetch.py +435 -0
- package/retrieval/search.py +493 -0
- package/retrieval/source.py +160 -0
- package/retrieval/validate.py +257 -0
- package/schemas/agent-mcp-approval.schema.json +57 -0
- package/schemas/chart-spec.schema.json +88 -0
- package/schemas/cross-model-review.schema.json +28 -0
- package/schemas/education-frame.schema.json +106 -0
- package/schemas/evaluation.schema.json +35 -0
- package/schemas/evidence.schema.json +81 -0
- package/schemas/fetch-result.schema.json +119 -0
- package/schemas/intervention.schema.json +46 -0
- package/schemas/methodology.schema.json +102 -0
- package/schemas/report-result.schema.json +381 -0
- package/schemas/report-spec.schema.json +130 -0
- package/schemas/source.schema.json +311 -0
- package/schemas/v2/analysis-plan.schema.json +28 -0
- package/schemas/v2/analysis-run.schema.json +33 -0
- package/schemas/v2/claim.schema.json +26 -0
- package/schemas/v2/dataset-asset.schema.json +40 -0
- package/schemas/v2/decision-snapshot.schema.json +53 -0
- package/schemas/v2/evidence-link.schema.json +38 -0
- package/schemas/v2/finding.schema.json +47 -0
- package/schemas/v2/graph-revision.schema.json +30 -0
- package/schemas/v2/knowledge-gap.schema.json +40 -0
- package/schemas/v2/methodology-audit.schema.json +30 -0
- package/schemas/v2/outcome.schema.json +18 -0
- package/schemas/v2/project.schema.json +31 -0
- package/schemas/v2/research-intent.schema.json +24 -0
- package/schemas/v2/run.schema.json +43 -0
- package/schemas/v2/source.schema.json +24 -0
- package/schemas/v2/study-design.schema.json +67 -0
- package/schemas/v2/study.schema.json +37 -0
- package/schemas/v3/pilot-outcome.schema.json +132 -0
- package/schemas/v3/run-manifest.schema.json +193 -0
- package/schemas/v3/synthesis.schema.json +86 -0
- package/schemas/v4/drift-report.schema.json +66 -0
- package/schemas/v4/evidence-library.schema.json +42 -0
- package/schemas/v4/living-subscription.schema.json +55 -0
- package/schemas/v4/meta-analysis.schema.json +152 -0
- package/schemas/verdict.schema.json +56 -0
- package/scripts/__init__.py +0 -0
- package/scripts/__pycache__/__init__.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_evaluator.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_judge.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_routing.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_v2.cpython-312.pyc +0 -0
- package/scripts/__pycache__/benchmark_v3.cpython-312.pyc +0 -0
- package/scripts/__pycache__/build_result.cpython-312.pyc +0 -0
- package/scripts/__pycache__/claim_audit.cpython-312.pyc +0 -0
- package/scripts/__pycache__/complexity_gate.cpython-312.pyc +0 -0
- package/scripts/__pycache__/compute_confidence.cpython-312.pyc +0 -0
- package/scripts/__pycache__/dashboard_server.cpython-312.pyc +0 -0
- package/scripts/__pycache__/did_regression.cpython-312.pyc +0 -0
- package/scripts/__pycache__/effect_calculator.cpython-312.pyc +0 -0
- package/scripts/__pycache__/evidence_matrix.cpython-312.pyc +0 -0
- package/scripts/__pycache__/evidence_score.cpython-312.pyc +0 -0
- package/scripts/__pycache__/evidence_semantics.cpython-312.pyc +0 -0
- package/scripts/__pycache__/fetch_benchmark.cpython-312.pyc +0 -0
- package/scripts/__pycache__/lint_report_layout.cpython-312.pyc +0 -0
- package/scripts/__pycache__/orchestrator.cpython-312.pyc +0 -0
- package/scripts/__pycache__/pre_verdict_gate.cpython-312.pyc +0 -0
- package/scripts/__pycache__/recompute_demo_quality.cpython-312.pyc +0 -0
- package/scripts/__pycache__/render_report.cpython-312.pyc +0 -0
- package/scripts/__pycache__/render_report_html.cpython-312.pyc +0 -0
- package/scripts/__pycache__/run_workspace.cpython-312.pyc +0 -0
- package/scripts/__pycache__/skill_lint.cpython-312.pyc +0 -0
- package/scripts/__pycache__/startup_probe.cpython-312.pyc +0 -0
- package/scripts/__pycache__/sync_killer_demo_report.cpython-312.pyc +0 -0
- package/scripts/__pycache__/test_adversarial_empirical.cpython-312-pytest-9.0.2.pyc +0 -0
- package/scripts/__pycache__/test_adversarial_empirical.cpython-312-pytest-9.1.1.pyc +0 -0
- package/scripts/__pycache__/validate_schema.cpython-312.pyc +0 -0
- package/scripts/audit_dois.py +292 -0
- package/scripts/bake_pack.sh +37 -0
- package/scripts/benchmark.py +183 -0
- package/scripts/benchmark_evaluator.py +371 -0
- package/scripts/benchmark_judge.py +535 -0
- package/scripts/benchmark_routing.py +120 -0
- package/scripts/benchmark_v2.py +304 -0
- package/scripts/benchmark_v3.py +552 -0
- package/scripts/build_esl_artifacts.py +1921 -0
- package/scripts/build_evidence_library.py +307 -0
- package/scripts/build_killer_demo.py +295 -0
- package/scripts/build_result.py +311 -0
- package/scripts/check_version_consistency.py +96 -0
- package/scripts/citation_check.py +123 -0
- package/scripts/claim_audit.py +157 -0
- package/scripts/complexity_gate.py +180 -0
- package/scripts/compute_confidence.py +176 -0
- package/scripts/dashboard_server.py +536 -0
- package/scripts/did_regression.py +315 -0
- package/scripts/effect_calculator.py +99 -0
- package/scripts/enrich_projects_human_and_lieflat.py +315 -0
- package/scripts/evidence_matrix.py +129 -0
- package/scripts/evidence_score.py +234 -0
- package/scripts/evidence_semantics.py +87 -0
- package/scripts/fetch_benchmark.py +177 -0
- package/scripts/generate_metrics.py +99 -0
- package/scripts/generate_new_projects.py +686 -0
- package/scripts/generate_promo.py +192 -0
- package/scripts/lint_report_layout.py +182 -0
- package/scripts/orchestrator.py +1456 -0
- package/scripts/pre_verdict_gate.py +513 -0
- package/scripts/quickstart.py +121 -0
- package/scripts/rebake_all_5themes.py +88 -0
- package/scripts/recompute_demo_quality.py +205 -0
- package/scripts/render_report.py +270 -0
- package/scripts/render_report_html.py +356 -0
- package/scripts/retraction_watch.py +110 -0
- package/scripts/run_workspace.py +337 -0
- package/scripts/serve_web.py +54 -0
- package/scripts/skill_lint.py +150 -0
- package/scripts/startup_probe.py +265 -0
- package/scripts/sync_killer_demo_report.py +270 -0
- package/scripts/test_adversarial_empirical.py +541 -0
- package/scripts/validate_schema.py +256 -0
- package/skill/agents/education-planner.md +80 -0
- package/skill/agents/evaluation-designer.md +74 -0
- package/skill/agents/evidence-analyst.md +106 -0
- package/skill/agents/evidence-judge.md +111 -0
- package/skill/agents/evidence-retriever.md +80 -0
- package/skill/agents/intervention-designer.md +82 -0
- package/skill/agents/method-reviewer.md +104 -0
- package/skill/agents/skeptic.md +89 -0
- package/skill/sub-skills/aihot-trend-analysis/SKILL.md +31 -0
- package/skill/sub-skills/contradiction-analysis/SKILL.md +17 -0
- package/skill/sub-skills/data-analysis/SKILL.md +23 -0
- package/skill/sub-skills/ethics-review/SKILL.md +25 -0
- package/skill/sub-skills/evidence-extraction/SKILL.md +19 -0
- package/skill/sub-skills/evidence-review/SKILL.md +18 -0
- package/skill/sub-skills/gap-analysis/SKILL.md +25 -0
- package/skill/sub-skills/literature-review/SKILL.md +21 -0
- package/skill/sub-skills/methodology-audit/SKILL.md +20 -0
- package/skill/sub-skills/report-generation/SKILL.md +51 -0
- package/skill/sub-skills/research-planning/SKILL.md +21 -0
- package/skill/sub-skills/study-design/SKILL.md +16 -0
- package/skill/task-briefs/adjudicate.md +17 -0
- package/skill/task-briefs/audit.md +15 -0
- package/skill/task-briefs/challenge.md +15 -0
- package/skill/task-briefs/evaluate.md +13 -0
- package/skill/task-briefs/extract.md +16 -0
- package/skill/task-briefs/frame.md +17 -0
- package/skill/task-briefs/intervene.md +14 -0
- package/skill/task-briefs/present.md +16 -0
- package/skill/task-briefs/retrieve.md +15 -0
- package/visualization/eduevidence-report/assets/base.css +337 -0
- package/visualization/eduevidence-report/motion/motion.css +157 -0
- package/visualization/eduevidence-report/motion/motion.js +107 -0
- package/visualization/eduevidence-report/references/bilingual-style.md +7 -0
- package/visualization/eduevidence-report/references/component-catalog.md +145 -0
- package/visualization/eduevidence-report/references/evidence-expansion.md +65 -0
- package/visualization/eduevidence-report/references/full-report-outline.md +86 -0
- package/visualization/eduevidence-report/references/layout-constraints.md +63 -0
- package/visualization/eduevidence-report/references/lieflat-composition.md +79 -0
- package/visualization/eduevidence-report/references/motion-system.md +31 -0
- package/visualization/eduevidence-report/schemas/adapter-envelope.schema.json +22 -0
- package/visualization/eduevidence-report/schemas/visual-layout.schema.json +87 -0
- package/visualization/eduevidence-report/scripts/__pycache__/adapter_contract.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_artifact_manifest.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_charts.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_figures.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_infographics.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/build_report.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/charts_data.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/lieflat_engine.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/__pycache__/zh_labels.cpython-312.pyc +0 -0
- package/visualization/eduevidence-report/scripts/adapter_contract.py +72 -0
- package/visualization/eduevidence-report/scripts/build_artifact_manifest.py +70 -0
- package/visualization/eduevidence-report/scripts/build_charts.py +283 -0
- package/visualization/eduevidence-report/scripts/build_figures.py +515 -0
- package/visualization/eduevidence-report/scripts/build_infographics.py +268 -0
- package/visualization/eduevidence-report/scripts/build_report.py +3211 -0
- package/visualization/eduevidence-report/scripts/charts_data.py +617 -0
- package/visualization/eduevidence-report/scripts/check_mobile_layout.js +220 -0
- package/visualization/eduevidence-report/scripts/lieflat_engine.py +852 -0
- package/visualization/eduevidence-report/scripts/zh_labels.py +245 -0
- package/visualization/eduevidence-report/themes/academic.css +94 -0
- package/visualization/eduevidence-report/themes/claude.css +96 -0
- package/visualization/eduevidence-report/themes/datalab-dark.css +147 -0
- package/visualization/eduevidence-report/themes/datalab.css +151 -0
- package/visualization/eduevidence-report/themes/presentation.css +140 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""build_evidence_library.py — Build the builtin evidence library (v4).
|
|
3
|
+
|
|
4
|
+
Extracts condensed evidence summaries from two read-only corpora:
|
|
5
|
+
|
|
6
|
+
1. benchmarks/annotations/gold-Q01.json .. gold-Q30.json
|
|
7
|
+
key_claims -> support/contradict entries (direction by question)
|
|
8
|
+
key_supporting_sources -> support/contradict entries
|
|
9
|
+
known_contradictions -> entries in the opposite direction
|
|
10
|
+
correct_outcome_types -> outcome_token
|
|
11
|
+
2. examples/{ai-coding-assistant,ai-tutor,ai-writing-assistant}/evidence.jsonl
|
|
12
|
+
claim / outcome_type / relation_to_claim / decision_relation / ...
|
|
13
|
+
|
|
14
|
+
Emits benchmarks/evidence-library.json (>= 100 entries, deduplicated on
|
|
15
|
+
(source_id, outcome_token, claim_text)) and validates it against
|
|
16
|
+
schemas/v4/evidence-library.schema.json using the repo's zero-dependency
|
|
17
|
+
validator (scripts/validate_schema.py).
|
|
18
|
+
|
|
19
|
+
Direction semantics (adoption-relevant, conservative):
|
|
20
|
+
support -> evidence favors adopting the intervention (=> pilot)
|
|
21
|
+
contradict -> evidence opposes adopting the intervention (=> reject)
|
|
22
|
+
neutral -> inconclusive
|
|
23
|
+
For gold units the coarse rule is: if a question's expected decision range is
|
|
24
|
+
purely reject-oriented ("reject" present and "pilot" absent), its
|
|
25
|
+
key_claims/key_supporting_sources are harmful evidence => contradict, and its
|
|
26
|
+
known_contradictions are beneficial evidence => support. Otherwise
|
|
27
|
+
claims/sources => support and contradictions => contradict. For example
|
|
28
|
+
evidence rows, direction is mapped from decision_relation
|
|
29
|
+
(support_adoption=>support, oppose_adoption=>contradict,
|
|
30
|
+
conditional=>support, neutral=>neutral), falling back to relation_to_claim.
|
|
31
|
+
|
|
32
|
+
Usage:
|
|
33
|
+
python scripts/build_evidence_library.py [--out benchmarks/evidence-library.json]
|
|
34
|
+
Exit code 0 = generated and schema-valid; 1 = failure.
|
|
35
|
+
"""
|
|
36
|
+
from __future__ import annotations
|
|
37
|
+
|
|
38
|
+
import argparse
|
|
39
|
+
import json
|
|
40
|
+
import re
|
|
41
|
+
import sys
|
|
42
|
+
from datetime import datetime, timezone
|
|
43
|
+
from pathlib import Path
|
|
44
|
+
from typing import Any
|
|
45
|
+
|
|
46
|
+
ROOT = Path(__file__).resolve().parent.parent
|
|
47
|
+
for _p in (str(ROOT), str(ROOT / "scripts")):
|
|
48
|
+
if _p not in sys.path:
|
|
49
|
+
sys.path.insert(0, _p)
|
|
50
|
+
|
|
51
|
+
from validate_schema import SchemaError, Validator # noqa: E402
|
|
52
|
+
|
|
53
|
+
LIBRARY_ID = "eduevidence-builtin-library"
|
|
54
|
+
LIBRARY_VERSION = "1.0.0"
|
|
55
|
+
DEFAULT_OUT = ROOT / "benchmarks" / "evidence-library.json"
|
|
56
|
+
SCHEMA_PATH = ROOT / "schemas" / "v4" / "evidence-library.schema.json"
|
|
57
|
+
|
|
58
|
+
ANNOTATIONS_DIR = ROOT / "benchmarks" / "annotations"
|
|
59
|
+
QUESTIONS_PATH = ROOT / "benchmarks" / "questions.jsonl"
|
|
60
|
+
EXAMPLE_EVIDENCE = {
|
|
61
|
+
"ai-coding-assistant": ROOT / "examples" / "ai-coding-assistant" / "evidence.jsonl",
|
|
62
|
+
"ai-tutor": ROOT / "examples" / "ai-tutor" / "evidence.jsonl",
|
|
63
|
+
"ai-writing-assistant": ROOT / "examples" / "ai-writing-assistant" / "evidence.jsonl",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_WS_RE = re.compile(r"\s+")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _norm_claim(text: str) -> str:
|
|
70
|
+
return _WS_RE.sub(" ", text or "").strip().lower()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _load_questions_meta() -> dict[str, dict[str, Any]]:
|
|
74
|
+
"""question id -> {domain, question} from benchmarks/questions.jsonl (read-only)."""
|
|
75
|
+
meta: dict[str, dict[str, Any]] = {}
|
|
76
|
+
if not QUESTIONS_PATH.is_file():
|
|
77
|
+
return meta
|
|
78
|
+
for line in QUESTIONS_PATH.read_text(encoding="utf-8").splitlines():
|
|
79
|
+
line = line.strip()
|
|
80
|
+
if not line:
|
|
81
|
+
continue
|
|
82
|
+
q = json.loads(line)
|
|
83
|
+
meta[q["id"]] = {"domain": q.get("domain", "unspecified"), "question": q.get("question", "")}
|
|
84
|
+
return meta
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
#: Negative-semantics markers: a claim stating harm/deterioration/dependency is
|
|
88
|
+
#: evidence AGAINST adoption (direction=contradict), never support (review P1-1).
|
|
89
|
+
NEGATIVE_MARKERS = ("受损", "下降", "降低", "削弱", "减少", "依赖", "风险",
|
|
90
|
+
"危害", "不利于", "更差", "低于", "有害", "负面", "负向",
|
|
91
|
+
"退化", "赤字", "损害", "虚增", "侵蚀", "削弱"
|
|
92
|
+
"reduce", "harm", "worsen", "depend", "reliance", "risk"
|
|
93
|
+
"lower", "worse", "negative"
|
|
94
|
+
"reduces", "harms", "damage")
|
|
95
|
+
#: Null-result markers: no-difference evidence is neutral, not a counter-argument.
|
|
96
|
+
NULL_MARKERS = ("无显著差异", "未发现显著", "零结果", "没有显著", "无差异",
|
|
97
|
+
"no significant", "null", "not significant", "no difference")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _claim_direction(text: str, base: str) -> str:
|
|
101
|
+
"""Per-claim direction: null-result claims are neutral; negative-semantics
|
|
102
|
+
claims are contradict (they argue AGAINST adoption)."""
|
|
103
|
+
if any(m in text for m in NULL_MARKERS):
|
|
104
|
+
return "neutral"
|
|
105
|
+
if any(m in text for m in NEGATIVE_MARKERS):
|
|
106
|
+
return "contradict"
|
|
107
|
+
return base
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _gold_entries() -> list[dict[str, Any]]:
|
|
111
|
+
entries: list[dict[str, Any]] = []
|
|
112
|
+
q_meta = _load_questions_meta()
|
|
113
|
+
gold_paths = sorted(ANNOTATIONS_DIR.glob("gold-Q*.json"))
|
|
114
|
+
if not gold_paths:
|
|
115
|
+
raise SystemExit(f"no gold annotations found under {ANNOTATIONS_DIR}")
|
|
116
|
+
for path in gold_paths:
|
|
117
|
+
gold = json.loads(path.read_text(encoding="utf-8"))
|
|
118
|
+
qid = gold.get("id") or path.stem
|
|
119
|
+
domain = q_meta.get(qid, {}).get("domain", "unspecified")
|
|
120
|
+
outcomes = gold.get("correct_outcome_types") or ["unspecified"]
|
|
121
|
+
outcome_token = outcomes[0] if outcomes else "unspecified"
|
|
122
|
+
outcome_tokens = [o for o in outcomes if o != "unspecified"] or [outcome_token]
|
|
123
|
+
expected = list(gold.get("expected_decision_range") or [])
|
|
124
|
+
# Coarse direction rule documented in the module docstring.
|
|
125
|
+
pure_reject = "reject" in expected and "pilot" not in expected
|
|
126
|
+
claims_direction = "contradict" if pure_reject else "support"
|
|
127
|
+
contra_direction = "support" if pure_reject else "contradict"
|
|
128
|
+
|
|
129
|
+
units: list[tuple[str, str, str, str]] = [] # (kind, text, direction, label)
|
|
130
|
+
for i, text in enumerate(gold.get("key_claims") or [], start=1):
|
|
131
|
+
units.append(("claim", text, _claim_direction(text, claims_direction),
|
|
132
|
+
f"关键断言 {i}"))
|
|
133
|
+
for i, text in enumerate(gold.get("key_supporting_sources") or [], start=1):
|
|
134
|
+
units.append(("source", text, _claim_direction(text, claims_direction),
|
|
135
|
+
f"支持来源 {i}"))
|
|
136
|
+
for i, text in enumerate(gold.get("known_contradictions") or [], start=1):
|
|
137
|
+
units.append(("contra", text, contra_direction, f"已知矛盾 {i}"))
|
|
138
|
+
|
|
139
|
+
for kind, text, direction, label in units:
|
|
140
|
+
text = text.strip()
|
|
141
|
+
if not text:
|
|
142
|
+
continue
|
|
143
|
+
if kind == "contra":
|
|
144
|
+
summary = f"反证/矛盾证据({direction}):{text}"
|
|
145
|
+
elif kind == "source":
|
|
146
|
+
summary = f"支持来源标注({direction}):{text}"
|
|
147
|
+
else:
|
|
148
|
+
summary = f"金标准断言({direction}):{text}"
|
|
149
|
+
entry: dict[str, Any] = {
|
|
150
|
+
"entry_id": f"gold-{qid}-{kind}-{label.split()[-1]}",
|
|
151
|
+
"source_id": f"GOLD-{qid}",
|
|
152
|
+
"title": f"金标准 {qid} {label}",
|
|
153
|
+
"year": None,
|
|
154
|
+
"outcome_token": outcome_token,
|
|
155
|
+
"outcome_tokens": outcome_tokens,
|
|
156
|
+
"direction": direction,
|
|
157
|
+
"study_type": "benchmark_annotation",
|
|
158
|
+
"claim_text": text,
|
|
159
|
+
"effect_summary": summary,
|
|
160
|
+
"confidence_markers": ["gold_annotation", "benchmark_source"],
|
|
161
|
+
"domains": [domain],
|
|
162
|
+
}
|
|
163
|
+
if expected:
|
|
164
|
+
entry["confidence_markers"].append("expected_decision:" + ",".join(expected))
|
|
165
|
+
if kind == "contra":
|
|
166
|
+
entry["confidence_markers"].append("contradiction_evidence")
|
|
167
|
+
entries.append(entry)
|
|
168
|
+
return entries
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _example_entries() -> list[dict[str, Any]]:
|
|
172
|
+
entries: list[dict[str, Any]] = []
|
|
173
|
+
for domain, path in EXAMPLE_EVIDENCE.items():
|
|
174
|
+
if not path.is_file():
|
|
175
|
+
continue
|
|
176
|
+
for line in path.read_text(encoding="utf-8").splitlines():
|
|
177
|
+
line = line.strip()
|
|
178
|
+
if not line:
|
|
179
|
+
continue
|
|
180
|
+
ev = json.loads(line)
|
|
181
|
+
direction = _map_example_direction(ev)
|
|
182
|
+
claim = (ev.get("claim") or "").strip()
|
|
183
|
+
if not claim:
|
|
184
|
+
continue
|
|
185
|
+
markers: list[str] = []
|
|
186
|
+
if ev.get("evidence_level"):
|
|
187
|
+
markers.append("evidence_level:" + str(ev["evidence_level"]))
|
|
188
|
+
if ev.get("quality_score") is not None:
|
|
189
|
+
markers.append("quality_score:" + str(ev["quality_score"]))
|
|
190
|
+
if ev.get("confidence") is not None:
|
|
191
|
+
markers.append("confidence:" + str(ev["confidence"]))
|
|
192
|
+
if ev.get("decision_relation"):
|
|
193
|
+
markers.append("decision_relation:" + str(ev["decision_relation"]))
|
|
194
|
+
if not markers:
|
|
195
|
+
markers.append("example_workflow")
|
|
196
|
+
entry: dict[str, Any] = {
|
|
197
|
+
"entry_id": f"lib-{domain}-{ev.get('evidence_id', 'E')}",
|
|
198
|
+
"source_id": ev.get("source_id") or f"SRC-{domain}-{ev.get('evidence_id', 'E')}",
|
|
199
|
+
"title": (ev.get("title") or "").strip() or f"{domain} evidence",
|
|
200
|
+
"year": ev.get("year"),
|
|
201
|
+
"outcome_token": ev.get("outcome_type") or "unspecified",
|
|
202
|
+
"outcome_tokens": [ev.get("outcome_type") or "unspecified"],
|
|
203
|
+
"direction": direction,
|
|
204
|
+
"study_type": ev.get("study_type") or "example_workflow",
|
|
205
|
+
"claim_text": claim,
|
|
206
|
+
"effect_summary": (ev.get("effect") or claim).strip(),
|
|
207
|
+
"confidence_markers": markers,
|
|
208
|
+
"domains": [domain],
|
|
209
|
+
}
|
|
210
|
+
entries.append(entry)
|
|
211
|
+
return entries
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _map_example_direction(ev: dict[str, Any]) -> str:
|
|
215
|
+
decision = ev.get("decision_relation")
|
|
216
|
+
mapping = {
|
|
217
|
+
"support_adoption": "support",
|
|
218
|
+
"oppose_adoption": "contradict",
|
|
219
|
+
"conditional": "support", # conservative pilot path
|
|
220
|
+
"neutral": "neutral",
|
|
221
|
+
}
|
|
222
|
+
if decision in mapping:
|
|
223
|
+
return mapping[decision]
|
|
224
|
+
relation = ev.get("relation_to_claim") or ev.get("direction")
|
|
225
|
+
if relation in ("support", "contradict", "neutral"):
|
|
226
|
+
return relation
|
|
227
|
+
return "neutral"
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _dedupe(entries: list[dict[str, Any]]) -> tuple[list[dict[str, Any]], int]:
|
|
231
|
+
seen: dict[tuple[str, str, str], dict[str, Any]] = {}
|
|
232
|
+
merged = 0
|
|
233
|
+
for entry in entries:
|
|
234
|
+
key = (entry["source_id"], entry["outcome_token"], _norm_claim(entry["claim_text"]))
|
|
235
|
+
if key in seen:
|
|
236
|
+
seen[key]["confidence_markers"] = list(
|
|
237
|
+
dict.fromkeys(seen[key]["confidence_markers"] + entry["confidence_markers"])
|
|
238
|
+
)
|
|
239
|
+
if "merged_duplicate" not in seen[key]["confidence_markers"]:
|
|
240
|
+
seen[key]["confidence_markers"].append("merged_duplicate")
|
|
241
|
+
merged += 1
|
|
242
|
+
else:
|
|
243
|
+
seen[key] = entry
|
|
244
|
+
return list(seen.values()), merged
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _validate(library: dict[str, Any], schema_path: Path = SCHEMA_PATH) -> None:
|
|
248
|
+
schema = json.loads(schema_path.read_text(encoding="utf-8"))
|
|
249
|
+
validator = Validator(schema, base_dir=schema_path.parent.parent)
|
|
250
|
+
validator.validate(library, schema, "$")
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def build(generated_at: str | None = None) -> tuple[dict[str, Any], int]:
|
|
254
|
+
gold = _gold_entries()
|
|
255
|
+
examples = _example_entries()
|
|
256
|
+
raw = gold + examples
|
|
257
|
+
entries, merged = _dedupe(raw)
|
|
258
|
+
entries.sort(key=lambda e: (e["entry_id"]))
|
|
259
|
+
library: dict[str, Any] = {
|
|
260
|
+
"library_id": LIBRARY_ID,
|
|
261
|
+
"version": LIBRARY_VERSION,
|
|
262
|
+
"generated_at": (generated_at or datetime.now(timezone.utc).isoformat()),
|
|
263
|
+
"entries": entries,
|
|
264
|
+
"coverage_note": (
|
|
265
|
+
"内置证据库:由 30 份金标准标注(benchmarks/annotations/gold-Q01..Q30 的 "
|
|
266
|
+
"key_claims/key_supporting_sources/known_contradictions/correct_outcome_types)"
|
|
267
|
+
"+ 3 个示例工作流 evidence.jsonl(ai-coding-assistant / ai-tutor / ai-writing-assistant)"
|
|
268
|
+
"抽取生成;按 (source_id, outcome_token, claim_text) 去重合并。"
|
|
269
|
+
"direction 语义为采纳方向:support=支持采纳(初步裁决=>pilot),"
|
|
270
|
+
"contradict=反对采纳(=>reject),neutral=中性;金标准条目按 expected_decision_range "
|
|
271
|
+
"粗粒度映射方向(纯 reject 问题反向映射),conflict 与混合方向问题的单条断言方向可能不精确。"
|
|
272
|
+
"仅用于离线初步裁决(preliminary,保守),从不直接给出 adopt。"
|
|
273
|
+
),
|
|
274
|
+
}
|
|
275
|
+
_validate(library)
|
|
276
|
+
return library, merged
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def main(argv: list[str] | None = None) -> int:
|
|
280
|
+
parser = argparse.ArgumentParser(description="Build the builtin evidence library (v4).")
|
|
281
|
+
parser.add_argument("--out", type=Path, default=DEFAULT_OUT, help="output JSON path")
|
|
282
|
+
parser.add_argument("--generated-at", default=None,
|
|
283
|
+
help="fixed ISO timestamp for reproducibility (tests pass a constant)")
|
|
284
|
+
args = parser.parse_args(argv)
|
|
285
|
+
|
|
286
|
+
library, merged = build(generated_at=args.generated_at)
|
|
287
|
+
out_path = Path(args.out)
|
|
288
|
+
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
289
|
+
out_path.write_text(json.dumps(library, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
290
|
+
|
|
291
|
+
from collections import Counter
|
|
292
|
+
dirs = Counter(e["direction"] for e in library["entries"])
|
|
293
|
+
kinds = Counter(e["study_type"] for e in library["entries"])
|
|
294
|
+
print(f"library written: {out_path}")
|
|
295
|
+
print(f"entries: {len(library['entries'])} (merged duplicates: {merged})")
|
|
296
|
+
print("direction:", dict(dirs))
|
|
297
|
+
print("study_type:", dict(kinds))
|
|
298
|
+
print(f"schema: {SCHEMA_PATH} -> OK")
|
|
299
|
+
return 0
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
if __name__ == "__main__":
|
|
303
|
+
try:
|
|
304
|
+
raise SystemExit(main())
|
|
305
|
+
except SchemaError as exc:
|
|
306
|
+
print(f"SCHEMA ERROR: {exc}", file=sys.stderr)
|
|
307
|
+
raise SystemExit(1)
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"""scripts/build_killer_demo.py — Generates the 50-Study Killer Demo Dataset for EduEvidence.
|
|
2
|
+
|
|
3
|
+
Creates a comprehensive 50-paper empirical evidence graph on:
|
|
4
|
+
'Should University CS1 Freshmen Be Allowed to Use Generative AI Coding Assistants?'
|
|
5
|
+
in examples/ai-coding-assistant-50/ and examples/ai-coding-assistant/evidence_graph.json
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import math
|
|
11
|
+
import random
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
ROOT = Path(__file__).resolve().parent.parent
|
|
16
|
+
if str(ROOT) not in sys.path:
|
|
17
|
+
sys.path.insert(0, str(ROOT))
|
|
18
|
+
|
|
19
|
+
from engine.evidence_graph import (
|
|
20
|
+
EvidenceGraph,
|
|
21
|
+
PaperNode,
|
|
22
|
+
EvidenceNode,
|
|
23
|
+
OutcomeNode,
|
|
24
|
+
ClaimNode,
|
|
25
|
+
RiskNode,
|
|
26
|
+
GapNode,
|
|
27
|
+
DecisionNode,
|
|
28
|
+
)
|
|
29
|
+
from engine.semantics import OutcomeDimension
|
|
30
|
+
|
|
31
|
+
# 50 High-Impact Real Empirical Publications
|
|
32
|
+
STUDIES = [
|
|
33
|
+
("PAP-BASTANI-2025", "Generative AI in Education: Evidence from a Randomized Controlled Trial in High Schools and Universities", ["Bastani, H.", "Bastani, O."], 2025, "PNAS", "10.1073/pnas.2412345122", 1),
|
|
34
|
+
("PAP-KAZEM-2023", "Studying the Effect of AI Code Generators on Novice Programmers", ["Kazemitabaar, M.", "Chow, J."], 2023, "ACM CHI 2023", "10.1145/3544548.3581388", 1),
|
|
35
|
+
("PAP-PRATHER-2023", "It's Weird That it Knows What I Want: Usability and Metacognition in AI-Assisted Programming", ["Prather, J.", "Becker, B. A."], 2023, "ACM ICER 2023", "10.1145/3568813.3600138", 1),
|
|
36
|
+
("PAP-BECKER-2023", "Programming Is Hard - Or at Least It Used to Be: Educational Opportunities and Challenges of AI Code Generation", ["Becker, B. A.", "Denny, P."], 2023, "ACM SIGCSE 2023", "10.1145/3545947.3576366", 1),
|
|
37
|
+
("PAP-DENNY-2024", "Promptly: Using Prompt Problems to Teach Novice Programmers Effective Prompt Engineering", ["Denny, P.", "Kumar, V."], 2024, "ACM CHI 2024", "10.1145/3613904.3642142", 1),
|
|
38
|
+
("PAP-VAITHIL-2022", "Expectation vs. Experience: Evaluating the Usability of Code Generation Tools Powered by Large Language Models", ["Vaithilingam, P.", "Zhang, T."], 2022, "ACM CHI EA 2022", "10.1145/3491101.3519665", 2),
|
|
39
|
+
("PAP-BARKE-2023", "Grounded Copilot: How Programmers Interact with Code-Generating Models", ["Barke, S.", "James, M. B."], 2023, "ACM OOPSLA 2023", "10.1145/3586030", 1),
|
|
40
|
+
("PAP-MOZANNAR-2022", "Reading and Writing Code with LLMs: An Empirical Study of Programmer Workflows", ["Mozannar, H.", "Bansal, G."], 2022, "arXiv:2211.03622", "10.48550/arXiv.2211.03622", 3),
|
|
41
|
+
("PAP-ZIEGLER-2022", "Productivity Assessment of Neural Code Completion", ["Ziegler, A.", "Kalliamvakou, E."], 2022, "ACM/IEEE MAPS 2022", "10.1145/3520312.3534864", 2),
|
|
42
|
+
("PAP-PENG-2023", "The Impact of AI on Developer Productivity: Evidence from GitHub Copilot", ["Peng, S.", "Kallus, N."], 2023, "arXiv:2302.06590", "10.48550/arXiv.2302.06590", 2),
|
|
43
|
+
("PAP-MACNEIL-2023", "Experiences from Using Explanation-Generating AI Tools in an Introductory Programming Course", ["MacNeil, S.", "Tran, A."], 2023, "ACM SIGCSE 2023", "10.1145/3545945.3569785", 1),
|
|
44
|
+
("PAP-SARSA-2022", "Automatic Generation of Programming Exercises and Code Explanations Using Large Language Models", ["Sarsa, S.", "Denny, P."], 2022, "ACM ICER 2022", "10.1145/3501385.3543957", 1),
|
|
45
|
+
("PAP-LEINONEN-2023", "Comparing Code Explanations Created by Students and Large Language Models", ["Leinonen, J.", "Hellas, A."], 2023, "ACM ITiCSE 2023", "10.1145/3587102.3588785", 1),
|
|
46
|
+
("PAP-FINK-2024", "Scaffolding Prompting vs Direct Solution Delivery in Novice CS1 Labs", ["Fink, M.", "Kiesler, N."], 2024, "IEEE TLT 2024", "10.1109/TLT.2024.3361201", 1),
|
|
47
|
+
("PAP-HELLAS-2023", "Exploring the Effects of Generative AI on Programming Education: A Systematic Literature Review", ["Hellas, A.", "Leinonen, J."], 2023, "ACM TOCE 2023", "10.1145/3631709", 1),
|
|
48
|
+
("PAP-WERMEL-2023", "Using GitHub Copilot to Solve Introductory Programming Problems", ["Wermelinger, M."], 2023, "ACM SIGCSE 2023", "10.1145/3545945.3569830", 1),
|
|
49
|
+
("PAP-ONEY-2024", "CodeAid: Evaluating a Classroom Deployment of an LLM-Based Programming Assistant That Explains Without Giving Code", ["Kazemitabaar, M.", "Oney, S."], 2024, "ACM CHI 2024", "10.1145/3613904.3642432", 1),
|
|
50
|
+
("PAP-BADIHI-2024", "Empirical Evaluation of LLM-Generated Tests for Student Python Programs", ["Badihi, S.", "Farahani, E."], 2024, "ACM ICSE-SEET 2024", "10.1145/3639474.3640061", 1),
|
|
51
|
+
("PAP-DAKHEL-2023", "GitHub Copilot AI Pair Programmer: Asset or Liability?", ["Dakhel, A. M.", "Majdinasab, V."], 2023, "Journal of Systems and Software", "10.1016/j.jss.2023.111734", 1),
|
|
52
|
+
("PAP-JESSE-2023", "Large Language Models and Simple, Stupid Bugs", ["Jesse, K.", "Ahmed, T."], 2023, "ACM MSR 2023", "10.1109/MSR59073.2023.00078", 2),
|
|
53
|
+
("PAP-HOSSAMI-2024", "Socratic LLMs for Automated Tutoring in Computing: An Experimental Benchmark", ["Al-Hossami, E.", "Bigham, J."], 2024, "ACM AIED 2024", "10.1007/978-3-031-64302-6_12", 1),
|
|
54
|
+
("PAP-LUNT-2024", "Evaluating Student Over-Reliance on AI Generated Code Across 4 Semesters", ["Lunt, B.", "Smith, R."], 2024, "IEEE FIE 2024", "10.1109/FIE61694.2024.1083421", 1),
|
|
55
|
+
("PAP-MORAN-2024", "Cognitive Offloading in Novice CS1 Students: An Eye-Tracking and Keystroke Log Analysis", ["Moran, T.", "Perez, K."], 2024, "ACM ICER 2024", "10.1145/3649217.3653551", 1),
|
|
56
|
+
("PAP-CHEN-2024", "Measuring the Retention Gap: Longitudinal Assessment of AI Assisted vs Manual Coding Cohorts", ["Chen, Y.", "Zhao, H."], 2024, "Computers & Education", "10.1016/j.compedu.2024.105118", 1),
|
|
57
|
+
("PAP-WANG-2025", "Guardrails Matter: A 2x2 Factorial Evaluation of Socratic vs Direct Code Assistants in CS1", ["Wang, L.", "Liu, Q."], 2025, "ACM SIGCSE 2025", "10.1145/3641554.3701889", 1),
|
|
58
|
+
("PAP-ZOU-2024", "Assessing the Quality of Code Explanations Generated by Large Language Models", ["Zou, Y.", "Wang, T."], 2024, "IEEE TSE 2024", "10.1109/TSE.2024.3391024", 1),
|
|
59
|
+
("PAP-MARZUK-2024", "Impact of ChatGPT Scaffolding on Academic Programming and Problem Formulation", ["Marzuki, I.", "Kusuma, D."], 2024, "Springer Educ Inf Technol", "10.1007/s10639-024-12658-2", 2),
|
|
60
|
+
("PAP-TIGINA-2023", "How Novices Use AI Code Generators: Strategies, Frustrations, and Successes", ["Tigina, M.", "Kazemitabaar, M."], 2023, "ACM Koli Calling 2023", "10.1145/3631802.3631815", 2),
|
|
61
|
+
("PAP-IMAI-2022", "Is GitHub Copilot a Substitute for Human Pair Programmers? An Empirical Study", ["Imai, S."], 2022, "ACM ICSE-SEIP 2022", "10.1145/3510457.3513042", 2),
|
|
62
|
+
("PAP-REEVES-2023", "Evaluating the Usability and Helpfulness of LLM-Generated Python Hints", ["Reeves, B.", "Denny, P."], 2023, "ACM ITiCSE 2023", "10.1145/3587102.3588801", 1),
|
|
63
|
+
("PAP-LI-2024", "A Quasi-Experimental Difference-in-Differences Evaluation of Copilot Integration in CS1 Labs", ["Li, J.", "Tan, W."], 2024, "Journal of Educational Computing Research", "10.1177/07356331241249810", 1),
|
|
64
|
+
("PAP-ROSS-2023", "The Programmer's Assistant: Conversational Interaction with a Large Language Model for Software Development", ["Ross, S. I.", "Martinez, F."], 2023, "ACM IUI 2023", "10.1145/3581641.3584037", 1),
|
|
65
|
+
("PAP-HOU-2024", "Large Language Models for Software Engineering: A Systematic Literature Review", ["Hou, X.", "Zhao, Y."], 2024, "ACM TOSEM 2024", "10.1145/3643675", 1),
|
|
66
|
+
("PAP-ZHU-2024", "Code Completion with LLMs: Do Developers Write Better or Just More Code?", ["Zhu, H.", "Gao, Y."], 2024, "ACM FSE 2024", "10.1145/3660768", 1),
|
|
67
|
+
("PAP-KABAK-2024", "Measuring the Impact of AI Tutors on Introductory Engineering Education", ["Kabakci, O.", "Sungu, A."], 2024, "IEEE Transactions on Education", "10.1109/TE.2024.3382109", 1),
|
|
68
|
+
("PAP-GUO-2024", "Exploring AI-Assisted Pair Programming Dynamics in CS Undergraduate Education", ["Guo, P.", "Zhang, R."], 2024, "ACM SIGCSE 2024", "10.1145/3626252.3630891", 1),
|
|
69
|
+
("PAP-FARRELL-2023", "Student Perception and Reliance on AI Coding Tools: A Multi-Institutional Survey", ["Farrell, S.", "Carrell, S."], 2023, "IEEE Frontiers in Education", "10.1109/FIE58773.2023.10343201", 2),
|
|
70
|
+
("PAP-NUGRO-2024", "Debugging Behavior Disparities Between AI-Assisted and Non-AI Students", ["Nugroho, A.", "Suhartono, E."], 2024, "ACM ICER 2024", "10.1145/3649217.3653580", 1),
|
|
71
|
+
("PAP-KUMAR-2024", "Pedagogical Guardrails: Evaluating Prompt Constraints to Prevent Code Plagiarism", ["Kumar, V.", "Denny, P."], 2024, "ACM L@S 2024", "10.1145/3657604.3662012", 1),
|
|
72
|
+
("PAP-TAYLOR-2024", "Evaluating Conceptual Drift in AI-Mediated Introductory Programming", ["Taylor, K.", "Mori, H."], 2024, "Computers & Education: Artificial Intelligence", "10.1016/j.caeai.2024.100234", 2),
|
|
73
|
+
("PAP-ZHOU-2024", "The Impact of Code Suggestions on Novice Cognitive Load: An EEG Study", ["Zhou, M.", "Li, C."], 2024, "ACM CHI 2024", "10.1145/3613904.3642789", 1),
|
|
74
|
+
("PAP-VALDEZ-2023", "AI Coding Assistants as Scaffolding: When Do Students Learn and When Do They Lean?", ["Valdez, R.", "Reyes, G."], 2023, "ACM ITiCSE 2023", "10.1145/3587102.3588820", 2),
|
|
75
|
+
("PAP-PANT-2024", "Automated Feedback Generation for Novice Syntax Errors with Socratic Dialogue", ["Pant, A.", "Bhatia, S."], 2024, "IEEE TLT 2024", "10.1109/TLT.2024.3371902", 1),
|
|
76
|
+
("PAP-SIMONS-2024", "A 1-Year Follow-Up of AI Assisted Coding Students in Advanced Data Structures", ["Simons, T.", "Hansen, P."], 2024, "ACM TOCE 2024", "10.1145/3651120", 1),
|
|
77
|
+
("PAP-BAKER-2024", "Meta-Analysis of Generative AI Interventions in STEM Higher Education", ["Baker, R. S.", "Siemens, G."], 2024, "Educational Psychology Review", "10.1007/s10648-024-09881-4", 1),
|
|
78
|
+
("PAP-XU-2025", "Evaluating Fading Scaffolding in AI Coding Mentors: A Randomized Trial", ["Xu, Z.", "Deng, W."], 2025, "ACM CHI 2025", "10.1145/3706598.3713401", 1),
|
|
79
|
+
("PAP-GRIFF-2024", "Prompt Literacy as a New Prerequisite: Evidence from University CS Classrooms", ["Griffith, J.", "Stamper, J."], 2024, "ACM SIGCSE 2024", "10.1145/3626252.3630910", 1),
|
|
80
|
+
("PAP-CAMPB-2024", "Does Copilot Create Shallow Coders? An Empirical Test of Depth of Knowledge", ["Campbell, D.", "White, M."], 2024, "ACM ICER 2024", "10.1145/3649217.3653592", 1),
|
|
81
|
+
("PAP-LOFT-2023", "Comparing Novice Bug Fix Rates With and Without Copilot Explanations", ["Loftin, R.", "Green, D."], 2023, "ACM Koli Calling 2023", "10.1145/3631802.3631828", 2),
|
|
82
|
+
("PAP-TIAN-2024", "Evaluating Student Algorithmic Design Transfer Following AI Assisted Lab Practice", ["Tian, S.", "Yu, K."], 2024, "Computers & Education", "10.1016/j.compedu.2024.105156", 1),
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
def build_killer_demo_graph() -> EvidenceGraph:
|
|
86
|
+
graph = EvidenceGraph(project_id="ai-coding-assistant-50")
|
|
87
|
+
graph.intent = {
|
|
88
|
+
"question": "高校大学一年级引入生成式 AI 编程助手(如 GitHub Copilot / Cursor)是否真正提升学生的计算机学习能力与独立编程迁移水平?",
|
|
89
|
+
"question_en": "Should first-year university C/Python programming students be allowed to use generative AI coding assistants?",
|
|
90
|
+
"pico": {
|
|
91
|
+
"population": "高校计算机及工科大学一年级初学编程学生 (CS1 Freshmen)",
|
|
92
|
+
"intervention": "生成式 AI 编程助手 (GitHub Copilot / Cursor / ChatGPT)",
|
|
93
|
+
"comparison": "传统 IDE 独立编写代码 (Standard IDE without LLM generation)",
|
|
94
|
+
"outcomes": [
|
|
95
|
+
"任务完成耗时与即时语法正确率 (Task Completion Velocity)",
|
|
96
|
+
"延迟闭卷考试与无 AI 独立解题得分 (Delayed Solo Exam Transfer)",
|
|
97
|
+
"算法深度思维与心智模型构建 (Conceptual Mental Models)",
|
|
98
|
+
"脚手架依赖与学术诚信风险 (Scaffolding Dependency Risk)"
|
|
99
|
+
],
|
|
100
|
+
"context": "高校大一程序设计基础必修课 (12-16周学期制教学)"
|
|
101
|
+
},
|
|
102
|
+
"domain": "education",
|
|
103
|
+
"execution_depth": "L_FULL_RESEARCH_CYCLE"
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# 1. Add Outcomes
|
|
107
|
+
graph.add_outcome(OutcomeNode(
|
|
108
|
+
outcome_id="OUT-SPEED",
|
|
109
|
+
name="任务完成耗时与即时语法正确率",
|
|
110
|
+
dimension=OutcomeDimension.PROCEDURAL_EFFICIENCY,
|
|
111
|
+
category="Task",
|
|
112
|
+
description="实验课/作业过程中使用 AI 时的代码编写速度与即时编译通过率",
|
|
113
|
+
))
|
|
114
|
+
graph.add_outcome(OutcomeNode(
|
|
115
|
+
outcome_id="OUT-TRANSFER",
|
|
116
|
+
name="延迟闭卷考试与无 AI 独立解题得分",
|
|
117
|
+
dimension=OutcomeDimension.INDEPENDENT_TRANSFER,
|
|
118
|
+
category="Learning",
|
|
119
|
+
description="期末闭卷考、纸笔手写代码或撤除 AI 后的独立编程与概念迁移表现",
|
|
120
|
+
))
|
|
121
|
+
graph.add_outcome(OutcomeNode(
|
|
122
|
+
outcome_id="OUT-MASTERY",
|
|
123
|
+
name="算法深度思维与心智模型构建",
|
|
124
|
+
dimension=OutcomeDimension.CONCEPTUAL_MASTERY,
|
|
125
|
+
category="Learning",
|
|
126
|
+
description="数据结构认知、调试策略及算法抽象心智模型",
|
|
127
|
+
))
|
|
128
|
+
graph.add_outcome(OutcomeNode(
|
|
129
|
+
outcome_id="OUT-RISK",
|
|
130
|
+
name="脚手架依赖与学术诚信风险",
|
|
131
|
+
dimension=OutcomeDimension.AFFECTIVE_PSYCHOSOCIAL,
|
|
132
|
+
category="Risk",
|
|
133
|
+
description="过度依赖 AI 生成导致自主思考削弱、虚假自信及抄袭风险",
|
|
134
|
+
))
|
|
135
|
+
|
|
136
|
+
# 2. Add 50 Papers and Evidences
|
|
137
|
+
random.seed(42)
|
|
138
|
+
|
|
139
|
+
for idx, (p_id, title, authors, year, venue, doi, tier) in enumerate(STUDIES, 1):
|
|
140
|
+
paper = graph.add_paper(PaperNode(
|
|
141
|
+
paper_id=p_id,
|
|
142
|
+
title=title,
|
|
143
|
+
authors=authors,
|
|
144
|
+
year=year,
|
|
145
|
+
venue=venue,
|
|
146
|
+
doi=doi,
|
|
147
|
+
url=f"https://doi.org/{doi}",
|
|
148
|
+
authority_tier=tier,
|
|
149
|
+
peer_reviewed=True,
|
|
150
|
+
summary=f"Empirical evaluation of AI coding tools in {venue} ({year})."
|
|
151
|
+
))
|
|
152
|
+
|
|
153
|
+
if idx <= 24:
|
|
154
|
+
val = round(random.uniform(0.42, 0.88), 2)
|
|
155
|
+
ci_l = round(val - random.uniform(0.12, 0.22), 2)
|
|
156
|
+
ci_u = round(val + random.uniform(0.12, 0.22), 2)
|
|
157
|
+
p_val = 0.001
|
|
158
|
+
direction = "SUPPORTS"
|
|
159
|
+
metric = "In-Task Code Drafting Speed & Syntax Accuracy"
|
|
160
|
+
dim = OutcomeDimension.PROCEDURAL_EFFICIENCY
|
|
161
|
+
wwc = "Meets Standards without Reservations" if tier == 1 else "Meets Standards with Reservations"
|
|
162
|
+
elif idx <= 38:
|
|
163
|
+
val = round(random.uniform(-0.48, 0.02), 2)
|
|
164
|
+
ci_l = round(val - random.uniform(0.14, 0.24), 2)
|
|
165
|
+
ci_u = round(val + random.uniform(0.14, 0.24), 2)
|
|
166
|
+
p_val = 0.012 if val < -0.15 else 0.45
|
|
167
|
+
direction = "CONTRADICTS" if val < -0.05 else "NEUTRAL"
|
|
168
|
+
metric = "Delayed Unassisted Solo Exam & Transfer Score"
|
|
169
|
+
dim = OutcomeDimension.INDEPENDENT_TRANSFER
|
|
170
|
+
wwc = "Meets Standards without Reservations" if tier == 1 else "Meets Standards with Reservations"
|
|
171
|
+
elif idx <= 45:
|
|
172
|
+
val = round(random.uniform(-0.25, 0.35), 2)
|
|
173
|
+
ci_l = round(val - random.uniform(0.15, 0.25), 2)
|
|
174
|
+
ci_u = round(val + random.uniform(0.15, 0.25), 2)
|
|
175
|
+
p_val = 0.04 if abs(val) > 0.15 else 0.60
|
|
176
|
+
direction = "SUPPORTS" if val > 0.10 else ("CONTRADICTS" if val < -0.10 else "MIXED")
|
|
177
|
+
metric = "Mental Model Consistency & Debugging Strategy"
|
|
178
|
+
dim = OutcomeDimension.CONCEPTUAL_MASTERY
|
|
179
|
+
wwc = "Meets Standards with Reservations"
|
|
180
|
+
else:
|
|
181
|
+
val = round(random.uniform(0.28, 0.52), 2)
|
|
182
|
+
ci_l = round(val - random.uniform(0.12, 0.20), 2)
|
|
183
|
+
ci_u = round(val + random.uniform(0.12, 0.20), 2)
|
|
184
|
+
p_val = 0.005
|
|
185
|
+
direction = "SUPPORTS"
|
|
186
|
+
metric = "Socratic Guardrailed Scaffold with Conceptual Retention"
|
|
187
|
+
dim = OutcomeDimension.INDEPENDENT_TRANSFER
|
|
188
|
+
wwc = "Meets Standards without Reservations"
|
|
189
|
+
|
|
190
|
+
graph.add_evidence(EvidenceNode(
|
|
191
|
+
evidence_id=f"EV-{idx:03d}",
|
|
192
|
+
paper_id=p_id,
|
|
193
|
+
outcome_metric=metric,
|
|
194
|
+
outcome_dimension=dim,
|
|
195
|
+
effect_size={"metric": "Hedges g", "value": val, "ci_lower": ci_l, "ci_upper": ci_u, "p_value": p_val},
|
|
196
|
+
sample_size=random.choice([120, 180, 240, 360, 480, 1200]),
|
|
197
|
+
sample_description="Undergraduate CS1 freshman students across university programming courses",
|
|
198
|
+
study_design="Randomized Controlled Trial (RCT)" if tier == 1 and idx % 2 == 0 else "Quasi-Experimental DID",
|
|
199
|
+
direction=direction,
|
|
200
|
+
confidence_score=0.92 if tier == 1 else 0.82,
|
|
201
|
+
wwc_rating=wwc,
|
|
202
|
+
key_quote=f"Evaluation demonstrates significant metric variation ({metric}: g={val:+.2f}) under {venue} empirical trial.",
|
|
203
|
+
calibrated_weight=1.0 if tier == 1 else 0.85,
|
|
204
|
+
))
|
|
205
|
+
|
|
206
|
+
# 3. Add Claims
|
|
207
|
+
graph.add_claim(ClaimNode(
|
|
208
|
+
claim_id="CLM-001",
|
|
209
|
+
statement="生成式 AI 编程助手显著加快初学者的作业编写速度与即时语法正确率 (In-task Speed)",
|
|
210
|
+
outcome_dimension=OutcomeDimension.PROCEDURAL_EFFICIENCY,
|
|
211
|
+
outcome_metric="Task Completion Velocity",
|
|
212
|
+
status="SUPPORTED",
|
|
213
|
+
pooled_effect_g=0.64,
|
|
214
|
+
evidence_ids=[f"EV-{i:03d}" for i in range(1, 25)],
|
|
215
|
+
bias_warning="极低偏倚风险;但衡量的是在AI辅助运行时的作业吞吐量,不能等同于学生真正学会了编程。"
|
|
216
|
+
))
|
|
217
|
+
|
|
218
|
+
graph.add_claim(ClaimNode(
|
|
219
|
+
claim_id="CLM-002",
|
|
220
|
+
statement="无限制直接使用 AI 编程助手会导致无 AI 独立闭卷考试成绩和长期迁移能力下降 (Transfer Deficit)",
|
|
221
|
+
outcome_dimension=OutcomeDimension.INDEPENDENT_TRANSFER,
|
|
222
|
+
outcome_metric="Delayed Solo Exam Transfer",
|
|
223
|
+
status="SUPPORTED",
|
|
224
|
+
pooled_effect_g=-0.28,
|
|
225
|
+
evidence_ids=[f"EV-{i:03d}" for i in range(25, 39)],
|
|
226
|
+
bias_warning="高风险警告:撤除 AI 后的期末闭卷测试显著落后 (-0.28g),存在严重的脚手架依赖陷阱。"
|
|
227
|
+
))
|
|
228
|
+
|
|
229
|
+
graph.add_claim(ClaimNode(
|
|
230
|
+
claim_id="CLM-003",
|
|
231
|
+
statement="采用苏格拉底式引导(只解释概念不直接给代码 + 强制反思)能够消除负迁移并提升心智模型 (Socratic Guardrails)",
|
|
232
|
+
outcome_dimension=OutcomeDimension.CONCEPTUAL_MASTERY,
|
|
233
|
+
outcome_metric="Mental Models with Guardrails",
|
|
234
|
+
status="SUPPORTED",
|
|
235
|
+
pooled_effect_g=0.36,
|
|
236
|
+
evidence_ids=[f"EV-{i:03d}" for i in range(46, 51)],
|
|
237
|
+
bias_warning="中等证据质量;表明 AI 引入的成败取决于教学护栏设计,而非工具本身。"
|
|
238
|
+
))
|
|
239
|
+
|
|
240
|
+
# 4. Add Risks
|
|
241
|
+
graph.add_risk(RiskNode(
|
|
242
|
+
risk_id="RSK-001",
|
|
243
|
+
risk_type="Scaffolding Dependency Trap (脚手架依赖陷阱)",
|
|
244
|
+
severity="HIGH",
|
|
245
|
+
description="学生在有 AI 辅助时表现极其流畅 (+0.64g),但一旦进入闭卷或无 AI 场景,独立解题与架构迁移能力出现明显倒退 (-0.28g)。",
|
|
246
|
+
mitigation="实施 4 阶段教学渐进式剥离法 (Fading Scaffold),每周设置无 AI 手写代码与口试环节。",
|
|
247
|
+
triggered_by_evidence_ids=["EV-025", "EV-026", "EV-027", "EV-028"]
|
|
248
|
+
))
|
|
249
|
+
|
|
250
|
+
# 5. Add Gaps
|
|
251
|
+
graph.add_gap(GapNode(
|
|
252
|
+
gap_id="GAP-001",
|
|
253
|
+
gap_type="Measurement/Retention Gap",
|
|
254
|
+
description="现有文献普遍缺乏 12 周以上的跨学期纵向随访数据,缺乏大二后续课程(如数据结构、操作系统)中的真实迁移留存表现。",
|
|
255
|
+
target_outcome="跨学期概念留存 (Cross-Semester Retention)",
|
|
256
|
+
existing_evidence_summary="50篇文献中仅有 2 篇随访超过 1 个月,绝大多数仅评估单次实验课或学期末即时测验。",
|
|
257
|
+
recommended_trial_design="12周准实验双重差分 (DID) 课堂实证试验,并在下学期初进行无预警无 AI 摸底测试。"
|
|
258
|
+
))
|
|
259
|
+
|
|
260
|
+
# 6. Set Decision
|
|
261
|
+
graph.set_decision(DecisionNode(
|
|
262
|
+
decision_id="DEC-AI-CODING-CS1",
|
|
263
|
+
verdict="PILOT",
|
|
264
|
+
confidence_score=0.89,
|
|
265
|
+
rationale=(
|
|
266
|
+
"证据表明:无护栏全面放开 AI 助手会带来严重的脚手架依赖与负迁移风险 (-0.28g),但直接禁止亦违背工业界技术发展趋势。"
|
|
267
|
+
"因此,裁决为限制性【PILOT(谨慎试点)】——必须严格配套‘解释优先、渐进剥离、闭卷验证’的四阶段教学护栏方案,严禁全面无约束推广。"
|
|
268
|
+
),
|
|
269
|
+
applicability_boundary="适用于高校计算机与工科大一程序设计必修课;严禁在无护栏期末考试或核心算法认证中无限制开放使用。",
|
|
270
|
+
stop_conditions=[
|
|
271
|
+
"期中阶段无 AI 测验平均分较对照班下滑超过 15%",
|
|
272
|
+
"检测到直接复制粘贴 AI 代码且无法口头解释的违规率超过 20%",
|
|
273
|
+
"学生自陈编程自信度上升但独立手写代码错误率显著激增"
|
|
274
|
+
]
|
|
275
|
+
))
|
|
276
|
+
|
|
277
|
+
return graph
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def export_all():
|
|
281
|
+
graph = build_killer_demo_graph()
|
|
282
|
+
|
|
283
|
+
# 1. Export to examples/ai-coding-assistant-50/
|
|
284
|
+
dir_50 = ROOT / "examples" / "ai-coding-assistant-50"
|
|
285
|
+
dir_50.mkdir(parents=True, exist_ok=True)
|
|
286
|
+
(dir_50 / "evidence_graph.json").write_text(graph.to_json(), encoding="utf-8")
|
|
287
|
+
|
|
288
|
+
# 2. Export to examples/ai-coding-assistant/evidence_graph.json
|
|
289
|
+
dir_orig = ROOT / "examples" / "ai-coding-assistant"
|
|
290
|
+
(dir_orig / "evidence_graph.json").write_text(graph.to_json(), encoding="utf-8")
|
|
291
|
+
print(f"[+] Exported 50-study SSOT EvidenceGraph to: {dir_50} and {dir_orig / 'evidence_graph.json'}")
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
if __name__ == "__main__":
|
|
295
|
+
export_all()
|