summaryrefslogtreecommitdiff
path: root/experiments
diff options
context:
space:
mode:
authorYurenHao0426 <Blackhao0426@gmail.com>2026-07-23 07:18:57 -0500
committerYurenHao0426 <Blackhao0426@gmail.com>2026-07-23 07:18:57 -0500
commit87cfb93fb75b4a45e88a5706c12d446ec92c7008 (patch)
tree34da4d63c3231c0eb9d6c796eea5a4a160c3ba05 /experiments
parente292d8f58f5ab02cc3e0fe93fe5caf73a8abfc4a (diff)
paper: add evidence-bound ICLR manuscript draft
Diffstat (limited to 'experiments')
-rw-r--r--experiments/audit_manuscript.py257
-rwxr-xr-xexperiments/finalize_accept.sh18
-rw-r--r--experiments/plot_resnet_confirmation.py28
3 files changed, 301 insertions, 2 deletions
diff --git a/experiments/audit_manuscript.py b/experiments/audit_manuscript.py
new file mode 100644
index 0000000..5743f24
--- /dev/null
+++ b/experiments/audit_manuscript.py
@@ -0,0 +1,257 @@
+#!/usr/bin/env python3
+"""Bind publication-facing manuscript claims to audited result sources."""
+import argparse
+import hashlib
+import json
+import os
+import re
+
+
+ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
+EXPECTED_SECTIONS = [
+ "## Abstract",
+ "## 1. Introduction",
+ "## 2. Somato-dendritic innovation learning",
+ "## 3. What residualization guarantees—and what it does not",
+ "## 4. Experimental protocol",
+ "## 5. Results",
+ "## 6. Biological-signature test and negative evidence",
+ "## 7. Related work",
+ "## 8. Limitations and discussion",
+ "## 9. Reproducibility statement",
+]
+
+
+def absolute(path):
+ return path if os.path.isabs(path) else os.path.join(ROOT, path)
+
+
+def load_json(path):
+ with open(path) as handle:
+ return json.load(handle)
+
+
+def sha256(path):
+ digest = hashlib.sha256()
+ with open(path, "rb") as handle:
+ for chunk in iter(lambda: handle.read(1024 * 1024), b""):
+ digest.update(chunk)
+ return digest.hexdigest()
+
+
+def require(condition, message):
+ if not condition:
+ raise RuntimeError(message)
+
+
+def pointer_get(value, pointer):
+ require(pointer.startswith("/"), f"invalid JSON pointer: {pointer}")
+ current = value
+ for part in pointer[1:].split("/"):
+ part = part.replace("~1", "/").replace("~0", "~")
+ if isinstance(current, list):
+ current = current[int(part)]
+ else:
+ require(part in current, f"missing JSON pointer component {part!r}")
+ current = current[part]
+ return current
+
+
+def render(value, format_name):
+ require(
+ isinstance(value, (int, float)) and not isinstance(value, bool),
+ f"claim source is not numeric: {value!r}",
+ )
+ value = float(value)
+ if format_name == "fixed0_comma":
+ return f"{value:,.0f}"
+ if format_name == "fixed1":
+ return f"{value:.1f}"
+ if format_name == "fixed2":
+ return f"{value:.2f}"
+ if format_name == "fixed2_percent":
+ return f"{value:.2f}%"
+ if format_name == "fixed3":
+ return f"{value:.3f}"
+ if format_name == "fixed3_percent":
+ return f"{value:.3f}%"
+ if format_name == "fixed4":
+ return f"{value:.4f}"
+ if format_name == "fixed6":
+ return f"{value:.6f}"
+ if format_name == "percent3":
+ return f"{100 * value:.3f}"
+ if format_name == "percent2_percent":
+ return f"{100 * value:.2f}%"
+ if format_name == "percent3_percent":
+ return f"{100 * value:.3f}%"
+ if format_name == "abs_percent3":
+ return f"{100 * abs(value):.3f}"
+ raise RuntimeError(f"unknown claim format: {format_name}")
+
+
+def false_check_paths(value, prefix="checks"):
+ paths = []
+ if isinstance(value, dict):
+ for key, child in value.items():
+ paths.extend(false_check_paths(child, f"{prefix}.{key}"))
+ elif value is False:
+ paths.append(prefix)
+ return paths
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--ledger", default="paper/CLAIM_LEDGER.json")
+ parser.add_argument("--out", default="paper/manuscript_audit.json")
+ args = parser.parse_args()
+
+ ledger_path = absolute(args.ledger)
+ ledger = load_json(ledger_path)
+ require(ledger.get("version") == 1, "claim-ledger version drift")
+ manuscript_path = absolute(ledger["manuscript"])
+ require(os.path.isfile(manuscript_path), "manuscript is missing")
+ with open(manuscript_path) as handle:
+ manuscript = handle.read()
+
+ require(
+ manuscript.startswith(
+ "# Learning from the Unexpected: Somato-Dendritic Innovations "
+ "for Local Credit Assignment\n"
+ ),
+ "working title drift",
+ )
+ for section in EXPECTED_SECTIONS:
+ require(manuscript.count(section) == 1, f"section drift: {section}")
+ require("TODO" not in manuscript and "TBD" not in manuscript,
+ "unresolved manuscript placeholder")
+
+ manuscript_dir = os.path.dirname(manuscript_path)
+ expected_figures = {
+ os.path.normpath(os.path.join(manuscript_dir, item))
+ for item in ledger["figures"]
+ }
+ linked_figures = {
+ os.path.normpath(os.path.join(manuscript_dir, item))
+ for item in re.findall(r"!\[[^\]]*\]\(([^)]+)\)", manuscript)
+ if not item.startswith(("http://", "https://"))
+ }
+ require(
+ linked_figures == expected_figures,
+ "manuscript figure set disagrees with claim ledger",
+ )
+ for path in sorted(expected_figures):
+ require(os.path.isfile(path), f"missing manuscript figure: {path}")
+
+ source_cache = {}
+ audited_claims = []
+ for claim in ledger["numeric_claims"]:
+ source_path = absolute(claim["source"])
+ if source_path not in source_cache:
+ source_cache[source_path] = load_json(source_path)
+ value = pointer_get(source_cache[source_path], claim["pointer"])
+ rendered = render(value, claim["format"])
+ require(
+ rendered == claim["token"],
+ f"{claim['id']}: ledger token {claim['token']!r} "
+ f"does not match source rendering {rendered!r}",
+ )
+ require(
+ claim["token"] in manuscript,
+ f"{claim['id']}: audited number is absent from manuscript",
+ )
+ audited_claims.append(
+ {
+ "id": claim["id"],
+ "pointer": claim["pointer"],
+ "rendered": rendered,
+ "source": claim["source"],
+ }
+ )
+
+ gate_audits = []
+ for gate_spec in ledger["gate_statuses"]:
+ gate_path = absolute(gate_spec["source"])
+ gate = load_json(gate_path)
+ require(
+ gate.get("status") == gate_spec["expected"],
+ f"{gate_spec['source']}: gate status drift",
+ )
+ false_paths = false_check_paths(gate.get("checks", {}))
+ if gate_spec["expected"] == "passed":
+ require(not false_paths, f"{gate_spec['source']}: passed gate has false check")
+ else:
+ require(false_paths, f"{gate_spec['source']}: failed gate has no false check")
+ gate_audits.append(
+ {
+ "false_checks": false_paths,
+ "source": gate_spec["source"],
+ "status": gate["status"],
+ }
+ )
+
+ manuscript_flat = re.sub(r"\s+", " ", manuscript)
+ for sentence in ledger["required_boundary_text"]:
+ require(
+ re.sub(r"\s+", " ", sentence) in manuscript_flat,
+ f"required claim boundary absent: {sentence}",
+ )
+ for url in ledger["required_reference_urls"]:
+ require(url in manuscript, f"required primary reference absent: {url}")
+
+ source_paths = sorted(
+ {absolute(item["source"]) for item in ledger["numeric_claims"]}
+ | {absolute(item["source"]) for item in ledger["gate_statuses"]}
+ )
+ output = {
+ "audited_numeric_claims": audited_claims,
+ "figures": [
+ {
+ "path": os.path.relpath(path, ROOT),
+ "sha256": sha256(path),
+ }
+ for path in sorted(expected_figures)
+ ],
+ "gates": gate_audits,
+ "ledger": {
+ "path": os.path.relpath(ledger_path, ROOT),
+ "sha256": sha256(ledger_path),
+ },
+ "manuscript": {
+ "path": os.path.relpath(manuscript_path, ROOT),
+ "sha256": sha256(manuscript_path),
+ "word_count": len(re.findall(r"\b[\w'-]+\b", manuscript)),
+ },
+ "sources": [
+ {
+ "path": os.path.relpath(path, ROOT),
+ "sha256": sha256(path),
+ }
+ for path in source_paths
+ ],
+ "status": "passed",
+ "strict": True,
+ }
+ out_path = absolute(args.out)
+ os.makedirs(os.path.dirname(out_path), exist_ok=True)
+ with open(out_path, "w") as handle:
+ json.dump(output, handle, indent=2, sort_keys=True)
+ handle.write("\n")
+ print(
+ json.dumps(
+ {
+ "false_gate_checks_retained": sum(
+ len(item["false_checks"]) for item in gate_audits
+ ),
+ "numeric_claims": len(audited_claims),
+ "status": output["status"],
+ "word_count": output["manuscript"]["word_count"],
+ },
+ indent=2,
+ sort_keys=True,
+ )
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/experiments/finalize_accept.sh b/experiments/finalize_accept.sh
index 70208e9..b39a714 100755
--- a/experiments/finalize_accept.sh
+++ b/experiments/finalize_accept.sh
@@ -23,7 +23,8 @@ experiments/finalize_claims.sh
experiments/analyze_bci_td_confirmation.py \
experiments/oral_a_dynamic_scaling.py \
experiments/analyze_oral_a_dynamic_scaling.py \
- experiments/plot_resnet_confirmation.py
+ experiments/plot_resnet_confirmation.py \
+ experiments/audit_manuscript.py
/home/yurenh2/miniconda3/envs/ep_pascal/bin/python3 \
experiments/analyze_kp_dynamic_projection.py >/dev/null
/home/yurenh2/miniconda3/envs/ep_pascal/bin/python3 \
@@ -43,7 +44,10 @@ if [ -f results/kp_dynamic_projection_confirmation_gate.json ]; then
.statistics.clean_minus_dynamic_one_sided_95pct_upper_points <= 2.5 and
.statistics.dynamic_early_alignment_mean >= 0.90 and
.statistics.dynamic_mac_ratio_to_bp <= 1.34 and
- .statistics.dynamic_logical_task_loss_queries == [0]
+ .statistics.dynamic_logical_task_loss_queries == [0] and
+ .statistics.dynamic_neutral_observations_per_ordinary_example == [1] and
+ .statistics.dynamic_peak_allocated_gib_mean <= 2.5 and
+ .statistics.dynamic_wall_ratio_to_clean_kp_mean > 1
' results/figs/figure4_resnet_confirmation_manifest.json >/dev/null
fi
if [ -f results/bci_td_dev_gate.json ]; then
@@ -66,6 +70,16 @@ fi
experiments/audit_native_baselines.py \
--results results/native \
--output results/native_baseline_audit.md
+/home/yurenh2/miniconda3/envs/ep_pascal/bin/python3 \
+ experiments/audit_manuscript.py >/dev/null
+jq -e '
+ .strict == true and
+ .status == "passed" and
+ (.audited_numeric_claims | length) == 34 and
+ (.gates | map(select(.status == "passed")) | length) == 1 and
+ (.gates | map(select(.status == "failed")) | length) == 1 and
+ (.gates[] | select(.status == "failed") | .false_checks | length) == 7
+' paper/manuscript_audit.json >/dev/null
git diff --check
echo "accept-bar mechanical audits passed"
diff --git a/experiments/plot_resnet_confirmation.py b/experiments/plot_resnet_confirmation.py
index efd0d48..99a55d4 100644
--- a/experiments/plot_resnet_confirmation.py
+++ b/experiments/plot_resnet_confirmation.py
@@ -483,6 +483,7 @@ def main():
"statistics": {
"clean_kp_test_accuracy_mean": float(clean.mean()),
"dynamic_test_accuracy_mean": float(dynamic.mean()),
+ "dynamic_test_accuracy_min": float(dynamic.min()),
"dynamic_minus_clean_points_mean": float(
(dynamic - clean).mean() * 100
),
@@ -499,6 +500,22 @@ def main():
for seed in EXPECTED_SEEDS
)
),
+ "dynamic_peak_allocated_gib_mean": float(
+ statistics.mean(
+ records[(seed, "kp_traffic")]["hardware"][
+ "peak_memory_allocated_bytes"
+ ]
+ / (1024 ** 3)
+ for seed in EXPECTED_SEEDS
+ )
+ ),
+ "dynamic_wall_ratio_to_clean_kp_mean": float(
+ statistics.mean(
+ records[(seed, "kp_traffic")]["timing"]["total_timed_wall_s"]
+ / records[(seed, "kp")]["timing"]["total_timed_wall_s"]
+ for seed in EXPECTED_SEEDS
+ )
+ ),
"dynamic_logical_task_loss_queries": sorted(
{
records[(seed, "kp_traffic")]["work"][
@@ -507,6 +524,17 @@ def main():
for seed in EXPECTED_SEEDS
}
),
+ "dynamic_neutral_observations_per_ordinary_example": sorted(
+ {
+ records[(seed, "kp_traffic")]["counters"][
+ "neutral_projection_examples"
+ ]
+ / records[(seed, "kp_traffic")]["counters"][
+ "ordinary_examples"
+ ]
+ for seed in EXPECTED_SEEDS
+ }
+ ),
},
"sources": [
{"path": args.gate, "sha256": sha256(args.gate)}