Three streams. Two land in the repo; one lands in fox's Downloads
(existing g4 packs live there too).
Witness sweep automation
========================
`bench/scripts/witness_sweep_cron.sh` — schedulable harness that
runs `make bench-witness-sweep` + `make bench-witness-divergence`
back-to-back and (with --commit) auto-commits any new divergence
fixtures + sweep result. Fail-closed: pre-commit hook failure
aborts; non-main-branch refuses to commit.
$ bench/scripts/witness_sweep_cron.sh # dry run
$ bench/scripts/witness_sweep_cron.sh --commit # auto-commit
$ bench/scripts/witness_sweep_cron.sh --commit --push # full pipeline
Recommended cron (every 6 hours; LLM cost scales with frequency):
0 */6 * * * \
bench/scripts/witness_sweep_cron.sh --commit --branch main \
>> /var/log/arborist-witness.log 2>&1
Smoke this commit: dry-run produced 5 fresh divergences (10
cumulative across two extraction passes). The witness-sweep + 5F
extractor pipeline runs unattended now; calibration-data corpus
will grow over time.
#000018 — adversarial soft-hash covert-channel analysis
========================================================
`docs/soft-hash-channel-analysis.md` — formal threat model + channel-
capacity definition + cryptographic reduction + mitigation table
+ residual analysis. Doc-only deliverable per the ticket's hard
constraint.
Headline result: under threat models T1 (data poisoner) and T2
(gradient adversary), the channel is bounded by SHA-256 partial-
preimage hardness when φ (the anchor map) is independent of
parameter geometry. T3 (hyperparameter adversary) requires
M2 (per-checkpoint anchor nonce) for boundedness.
Recommended mitigation: M2 (per-checkpoint nonce) — 32 bytes added
to the snapshot manifest, no training-ergonomics regression,
closes T1+T2 channels under any φ choice and bounds T3 by
per-checkpoint window. Fall back to M1 (PRG-based φ) if M2-only
deployment surfaces structural concerns. M3 (drop anchor entirely)
stays in reserve as the strict-construction fallback.
Three open questions (§9): Hessian alignment under φ_linear,
PRG choice for φ_PRG, and explicit T3 per-window bound. Each is a
follow-up ticket.
Ticket #000018 status: closed · landed 2026-05-09 (analysis doc).
v7 § 9.10 spec amendment proposed in §7 of the analysis.
#000033 — pillar VII (combinatorics), Claude-authored
======================================================
NOT committed to the arborist repo (the existing g4-v2 packs live
in `/home/fox/Downloads/` too — that's the operator's bundle
location). Two new bundle files at:
/home/fox/Downloads/axiomsclaude-vii-v1.json (7 axioms)
/home/fox/Downloads/theoremsclaude-vii-v1.json (7 theorems)
Pillar VII covers combinatorial counting — the gap between Grok's
pillars VI and IX in the v2 packs:
axioms (7): addition principle · multiplication principle ·
pigeonhole principle · factorial definition ·
binomial coefficient definition · Pascal's rule ·
empty-set / boundary axiom
theorems (7): binomial theorem · inclusion-exclusion (counting
form) · hockey-stick identity · Vandermonde's
identity · Catalan number closed form · stars-and-
bars · strong pigeonhole
Each record in the dual-thread format the existing g4 packs use
(Δ symbolic LaTeX + ∇ verbose prose + ∇ concise + sigil + formal
language + role + status + source_reference + date + foundational
group + category + subfield). Per fox's directive: explicit
authorship metadata everywhere — `authored_by: Claude (Anthropic)
— model claude-opus-4-7`. NOT Grok-generated; no silent invention.
Each record carries `pi_star_ref: combinatorics@v1` so the kernel
binding is explicit. Theorems list `depends_on_axioms` arrays so
each theorem cites the foundation axioms it bottoms out on.
Smoke test (committed alongside):
$ arborist --db /tmp/test.db ingest --source claim_pack \\
--bundle /home/fox/Downloads/axiomsclaude-vii-v1.json \\
--bundle /home/fox/Downloads/theoremsclaude-vii-v1.json
→ 14 docs, 14 chunks, 0 cross-bundle edges
Source attributions: Stanley EC1, Brualdi Introductory
Combinatorics, Knuth TAOCP Vol 1, plus historical sources where
applicable (Pascal 1654, Vandermonde 1772, Dirichlet 1834, Catalan
1838, Feller 1950 for stars-and-bars).
Tests: 1636 passed, 37 skipped (no regressions; pillar VII
ingestion smoke covered above).
This commit is contained in:
parent
67542742f3
commit
7871e1fdfe
6 changed files with 633 additions and 40 deletions
|
|
@ -1,6 +1,11 @@
|
|||
{"_meta": {"battery": "5f", "sub_battery": "falsification", "version": "v1", "task_count": 5, "notes": "Witness-divergence-extracted falsification fixtures. Auto-generated by `make bench-witness-divergence` from providence_canonical_witness audit events. Each row pairs an LLM raw answer with the kernel's canonical answer; verify_quotes is expected to return UNGROUNDED because the LLM prose doesn't substring-match the kernel's terse canonical form. _witness_meta carries the original agreement_label + audit_seq for traceability."}}
|
||||
{"_meta": {"battery": "5f", "sub_battery": "falsification", "version": "v1", "task_count": 10, "notes": "Witness-divergence-extracted falsification fixtures. Auto-generated by `make bench-witness-divergence` from providence_canonical_witness audit events. Each row pairs an LLM raw answer with the kernel's canonical answer; verify_quotes is expected to return UNGROUNDED because the LLM prose doesn't substring-match the kernel's terse canonical form. _witness_meta carries the original agreement_label + audit_seq for traceability."}}
|
||||
{"id": "5f-fal-witness-011631", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "arithmetic@v1", "answer_text": "1/10", "context": "canonical_kernel_answer=3/10\nquestion=0.1 + 0.2", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "KERNEL-LLM-DIVERGED", "audit_seq": 11631, "pi_star_ref": "arithmetic@v1"}}
|
||||
{"id": "5f-fal-witness-011637", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "logic-kernel@v1", "answer_text": "TRUE", "context": "canonical_kernel_answer=(NOT A OR B)\nquestion=A IMPL B", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "KERNEL-LLM-DIVERGED", "audit_seq": 11637, "pi_star_ref": "logic-kernel@v1"}}
|
||||
{"id": "5f-fal-witness-011639", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "logic-kernel@v1", "answer_text": "TRUE", "context": "canonical_kernel_answer=(NOT A OR B)\nquestion=(NOT B) IMPL (NOT A)", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "KERNEL-LLM-DIVERGED", "audit_seq": 11639, "pi_star_ref": "logic-kernel@v1"}}
|
||||
{"id": "5f-fal-witness-011643", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "algebra-symbolic@v1", "answer_text": "1", "context": "canonical_kernel_answer=Add(Pow(Symbol('x'), Integer(2)), Mul(Integer(2), Symbol('x')), Integer(1))\nquestion=(x+1)**2", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "KERNEL-LLM-DIVERGED", "audit_seq": 11643, "pi_star_ref": "algebra-symbolic@v1"}}
|
||||
{"id": "5f-fal-witness-011645", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "algebra-symbolic@v1", "answer_text": "1", "context": "canonical_kernel_answer=Add(Pow(Symbol('x'), Integer(2)), Mul(Integer(2), Symbol('x')), Integer(1))\nquestion=x**2 + 2*x + 1", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "KERNEL-LLM-DIVERGED", "audit_seq": 11645, "pi_star_ref": "algebra-symbolic@v1"}}
|
||||
{"id": "5f-fal-witness-011649", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "arithmetic@v1", "answer_text": "1/10", "context": "canonical_kernel_answer=3/10\nquestion=0.1 + 0.2", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "LLM-DIVERGED", "audit_seq": 11649, "pi_star_ref": "arithmetic@v1"}}
|
||||
{"id": "5f-fal-witness-011652", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "logic-kernel@v1", "answer_text": "TRUE", "context": "canonical_kernel_answer=(NOT A OR B)\nquestion=A IMPL B", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "LLM-DIVERGED", "audit_seq": 11652, "pi_star_ref": "logic-kernel@v1"}}
|
||||
{"id": "5f-fal-witness-011653", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "logic-kernel@v1", "answer_text": "TRUE", "context": "canonical_kernel_answer=(NOT A OR B)\nquestion=(NOT B) IMPL (NOT A)", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "LLM-DIVERGED", "audit_seq": 11653, "pi_star_ref": "logic-kernel@v1"}}
|
||||
{"id": "5f-fal-witness-011655", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "algebra-symbolic@v1", "answer_text": "1", "context": "canonical_kernel_answer=Add(Pow(Symbol('x'), Integer(2)), Mul(Integer(2), Symbol('x')), Integer(1))\nquestion=(x+1)**2", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "LLM-DIVERGED", "audit_seq": 11655, "pi_star_ref": "algebra-symbolic@v1"}}
|
||||
{"id": "5f-fal-witness-011656", "battery": "5f", "sub_battery": "falsification", "version": "v1", "carrier": "providence_record", "domain": "claim_lattice", "pi_star_ref": "algebra-symbolic@v1", "answer_text": "1", "context": "canonical_kernel_answer=Add(Pow(Symbol('x'), Integer(2)), Mul(Integer(2), Symbol('x')), Integer(1))\nquestion=x**2 + 2*x + 1", "expected_reason": "UNGROUNDED", "verifier_method_root": "verify_quotes-v1", "expected": "pass", "_witness_meta": {"agreement_label": "LLM-DIVERGED", "audit_seq": 11656, "pi_star_ref": "algebra-symbolic@v1"}}
|
||||
|
|
|
|||
|
|
@ -1,123 +1,123 @@
|
|||
{
|
||||
"schema_version": "witness-sweep-v1",
|
||||
"timestamp_utc": "2026-05-09T17:27:30+00:00",
|
||||
"timestamp_utc": "2026-05-09T18:27:23+00:00",
|
||||
"shards_dir": "/home/fox/.arborist/shards",
|
||||
"model": "adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic",
|
||||
"endpoint": "https://hermes.ai.unturf.com/v1",
|
||||
"summary": {
|
||||
"questions": 8,
|
||||
"by_agreement_label": {
|
||||
"KERNEL-LLM-DIVERGED": 5,
|
||||
"KERNEL-LLM-AGREE": 3
|
||||
"LLM-DIVERGED": 5,
|
||||
"STRICT-WITNESSED": 3
|
||||
},
|
||||
"divergence_count": 5,
|
||||
"divergence_rate": 0.625,
|
||||
"wall_ms_median": 130.2,
|
||||
"wall_ms_max": 1111.0
|
||||
"wall_ms_median": 159.2,
|
||||
"wall_ms_max": 1099.3
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"question": "0.1 + 0.2",
|
||||
"status": "cache_miss_then_written",
|
||||
"status": "cache_hit",
|
||||
"audit_mode": "CANONICAL_PROJECTION",
|
||||
"pi_star_ref": "arithmetic@v1",
|
||||
"canonical_answer": "3/10",
|
||||
"agreement_label": "KERNEL-LLM-DIVERGED",
|
||||
"agreement_label": "LLM-DIVERGED",
|
||||
"llm_raw": "1/10",
|
||||
"llm_canonical_match": false,
|
||||
"cache_status": "ABSENT",
|
||||
"wall_ms": 1111.0,
|
||||
"cache_status": "ok",
|
||||
"wall_ms": 1099.3,
|
||||
"audit_event_hash": "3b25ad3cd28a9505d96e22c85ae42ab182008ee6584b3a74c881dba07e3eab28"
|
||||
},
|
||||
{
|
||||
"question": "1/3 + 1/6",
|
||||
"status": "cache_miss_then_written",
|
||||
"status": "cache_hit",
|
||||
"audit_mode": "CANONICAL_PROJECTION",
|
||||
"pi_star_ref": "arithmetic@v1",
|
||||
"canonical_answer": "1/2",
|
||||
"agreement_label": "KERNEL-LLM-AGREE",
|
||||
"agreement_label": "STRICT-WITNESSED",
|
||||
"llm_raw": "1/2",
|
||||
"llm_canonical_match": false,
|
||||
"cache_status": "ABSENT",
|
||||
"wall_ms": 150.8,
|
||||
"cache_status": "ok",
|
||||
"wall_ms": 159.2,
|
||||
"audit_event_hash": "7677efdeb3b2ad7f60cf4312d2f4825c9fa949ddcbc06434ee5fc4ea50a86e3e"
|
||||
},
|
||||
{
|
||||
"question": "2**10",
|
||||
"status": "cache_miss_then_written",
|
||||
"status": "cache_hit",
|
||||
"audit_mode": "CANONICAL_PROJECTION",
|
||||
"pi_star_ref": "arithmetic@v1",
|
||||
"canonical_answer": "1024/1",
|
||||
"agreement_label": "KERNEL-LLM-AGREE",
|
||||
"agreement_label": "STRICT-WITNESSED",
|
||||
"llm_raw": "1024",
|
||||
"llm_canonical_match": false,
|
||||
"cache_status": "ABSENT",
|
||||
"wall_ms": 130.2,
|
||||
"cache_status": "ok",
|
||||
"wall_ms": 134.7,
|
||||
"audit_event_hash": "ed570bd6127a0b7143bb5c0f8cf76daf37a2092fe84350c0cab1ee2a2bf0410b"
|
||||
},
|
||||
{
|
||||
"question": "A IMPL B",
|
||||
"status": "cache_miss_then_written",
|
||||
"status": "cache_hit",
|
||||
"audit_mode": "CANONICAL_PROJECTION",
|
||||
"pi_star_ref": "logic-kernel@v1",
|
||||
"canonical_answer": "(NOT A OR B)",
|
||||
"agreement_label": "KERNEL-LLM-DIVERGED",
|
||||
"agreement_label": "LLM-DIVERGED",
|
||||
"llm_raw": "TRUE",
|
||||
"llm_canonical_match": false,
|
||||
"cache_status": "ABSENT",
|
||||
"wall_ms": 124.9,
|
||||
"cache_status": "ok",
|
||||
"wall_ms": 147.0,
|
||||
"audit_event_hash": "0f6fb926fd72150c5a0d8121a004b1f66edf3c8ee4bc15c52168f3a7869786fe"
|
||||
},
|
||||
{
|
||||
"question": "(NOT B) IMPL (NOT A)",
|
||||
"status": "cache_miss_then_written",
|
||||
"status": "cache_hit",
|
||||
"audit_mode": "CANONICAL_PROJECTION",
|
||||
"pi_star_ref": "logic-kernel@v1",
|
||||
"canonical_answer": "(NOT A OR B)",
|
||||
"agreement_label": "KERNEL-LLM-DIVERGED",
|
||||
"agreement_label": "LLM-DIVERGED",
|
||||
"llm_raw": "TRUE",
|
||||
"llm_canonical_match": false,
|
||||
"cache_status": "ABSENT",
|
||||
"wall_ms": 113.5,
|
||||
"cache_status": "ok",
|
||||
"wall_ms": 260.2,
|
||||
"audit_event_hash": "1b17f6e39edf2bb3d8dce003e20f71df9a3b9bd1b885f8a6e4b78e43ec122c31"
|
||||
},
|
||||
{
|
||||
"question": "A OR NOT A",
|
||||
"status": "cache_miss_then_written",
|
||||
"status": "cache_hit",
|
||||
"audit_mode": "CANONICAL_PROJECTION",
|
||||
"pi_star_ref": "logic-kernel@v1",
|
||||
"canonical_answer": "TRUE",
|
||||
"agreement_label": "KERNEL-LLM-AGREE",
|
||||
"agreement_label": "STRICT-WITNESSED",
|
||||
"llm_raw": "TRUE",
|
||||
"llm_canonical_match": false,
|
||||
"cache_status": "ABSENT",
|
||||
"wall_ms": 123.0,
|
||||
"cache_status": "ok",
|
||||
"wall_ms": 129.1,
|
||||
"audit_event_hash": "5929ffe218bb8a97c391df70cfffed810f66d02c4a54bdce2569755200bd8d0d"
|
||||
},
|
||||
{
|
||||
"question": "(x+1)**2",
|
||||
"status": "cache_miss_then_written",
|
||||
"status": "cache_hit",
|
||||
"audit_mode": "CANONICAL_PROJECTION",
|
||||
"pi_star_ref": "algebra-symbolic@v1",
|
||||
"canonical_answer": "Add(Pow(Symbol('x'), Integer(2)), Mul(Integer(2), Symbol('x')), Integer(1))",
|
||||
"agreement_label": "KERNEL-LLM-DIVERGED",
|
||||
"agreement_label": "LLM-DIVERGED",
|
||||
"llm_raw": "1",
|
||||
"llm_canonical_match": false,
|
||||
"cache_status": "ABSENT",
|
||||
"wall_ms": 179.4,
|
||||
"cache_status": "ok",
|
||||
"wall_ms": 196.1,
|
||||
"audit_event_hash": "b36f1a830aae8fec514f95f3104ba4473bc6febb98137016c5d0816f859ba440"
|
||||
},
|
||||
{
|
||||
"question": "x**2 + 2*x + 1",
|
||||
"status": "cache_miss_then_written",
|
||||
"status": "cache_hit",
|
||||
"audit_mode": "CANONICAL_PROJECTION",
|
||||
"pi_star_ref": "algebra-symbolic@v1",
|
||||
"canonical_answer": "Add(Pow(Symbol('x'), Integer(2)), Mul(Integer(2), Symbol('x')), Integer(1))",
|
||||
"agreement_label": "KERNEL-LLM-DIVERGED",
|
||||
"agreement_label": "LLM-DIVERGED",
|
||||
"llm_raw": "1",
|
||||
"llm_canonical_match": false,
|
||||
"cache_status": "ABSENT",
|
||||
"wall_ms": 120.1,
|
||||
"cache_status": "ok",
|
||||
"wall_ms": 147.3,
|
||||
"audit_event_hash": "d307d6990527ddc6af73ea3cb894d4986ea3003106723fe74e22282f16eb62c6"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
156
bench/scripts/witness_sweep_cron.sh
Executable file
156
bench/scripts/witness_sweep_cron.sh
Executable file
|
|
@ -0,0 +1,156 @@
|
|||
#!/usr/bin/env bash
|
||||
# witness_sweep_cron.sh — scheduled witness-divergence collection
|
||||
#
|
||||
# Runs `make bench-witness-sweep` followed by `make bench-witness-divergence`
|
||||
# and (optionally) commits any newly-extracted divergence fixtures to the
|
||||
# arborist repo. Designed to grow the calibration-data corpus over time
|
||||
# without operator intervention.
|
||||
#
|
||||
# Cron usage (recommended every 6 hours; LLM costs scale with frequency):
|
||||
#
|
||||
# 0 */6 * * * cd /home/fox/git/arborist && \
|
||||
# bench/scripts/witness_sweep_cron.sh \
|
||||
# --commit --branch main >> /var/log/arborist-witness.log 2>&1
|
||||
#
|
||||
# Invariants:
|
||||
# - Never commits unless --commit AND fixture file actually changed
|
||||
# - Skips push by default (operator runs `git push` separately)
|
||||
# - Records sweep result + extraction count + commit sha in audit log
|
||||
# - Fail-closed: pre-commit hook failure → no auto-push, no silent loss
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Defaults
|
||||
# ---------------------------------------------------------------------------
|
||||
COMMIT=0
|
||||
PUSH=0
|
||||
BRANCH="main"
|
||||
LOG_PREFIX="witness-sweep"
|
||||
SHARDS_DIR="${ARBORIST_SHARDS_DIR:-$HOME/.arborist/shards}"
|
||||
FIXTURE_PATH="bench/fixtures/5f/falsification-witness-v1.jsonl"
|
||||
SWEEP_OUT="bench/results/witness-sweep.json"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Argument parsing
|
||||
# ---------------------------------------------------------------------------
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--commit) COMMIT=1; shift ;;
|
||||
--push) PUSH=1; shift ;;
|
||||
--branch) BRANCH="$2"; shift 2 ;;
|
||||
--shards) SHARDS_DIR="$2"; shift 2 ;;
|
||||
--help|-h)
|
||||
cat <<'EOF'
|
||||
Usage: witness_sweep_cron.sh [--commit] [--push] [--branch NAME] [--shards DIR]
|
||||
|
||||
--commit commit any new divergence fixtures (default: dry-run)
|
||||
--push push the commit (requires --commit; default: skip)
|
||||
--branch NAME branch to commit on (default: main)
|
||||
--shards DIR shards-dir override (default: $ARBORIST_SHARDS_DIR or ~/.arborist/shards)
|
||||
|
||||
Environment:
|
||||
ARBORIST_SHARDS_DIR — fallback if --shards not given.
|
||||
ARBORIST_LLM_ENDPOINT / ARBORIST_LLM_MODEL — passthrough to witness sweep.
|
||||
|
||||
Output:
|
||||
Stdout: human-readable timestamped log per phase.
|
||||
Bench artifacts: bench/results/witness-sweep.json (latest sweep);
|
||||
bench/fixtures/5f/falsification-witness-v1.jsonl.
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
*) echo "$LOG_PREFIX: unknown arg: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
log() { printf "[%s %s] %s\n" "$LOG_PREFIX" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$*"; }
|
||||
|
||||
require_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
log "missing required command: $1"; exit 2;
|
||||
}
|
||||
}
|
||||
|
||||
require_cmd git
|
||||
require_cmd make
|
||||
|
||||
# Must run from repo root (Makefile + .git both expected here)
|
||||
[[ -f Makefile ]] || { log "must run from arborist repo root"; exit 2; }
|
||||
[[ -d .git ]] || { log "not a git repo"; exit 2; }
|
||||
|
||||
[[ -d "$SHARDS_DIR" ]] || {
|
||||
log "shards-dir missing: $SHARDS_DIR"; exit 2;
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 1 — sweep
|
||||
# ---------------------------------------------------------------------------
|
||||
log "phase 1 — bench-witness-sweep against $SHARDS_DIR"
|
||||
ARBORIST_SHARDS_DIR="$SHARDS_DIR" make bench-witness-sweep
|
||||
SWEEP_DIVERGENCE=$(python3 -c "
|
||||
import json
|
||||
d = json.load(open('$SWEEP_OUT'))
|
||||
print(d['summary']['divergence_count'])
|
||||
")
|
||||
log "phase 1 done — sweep recorded $SWEEP_DIVERGENCE divergences this run"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 2 — extract divergence as 5F fixtures
|
||||
# ---------------------------------------------------------------------------
|
||||
log "phase 2 — extract divergence audit events as 5F fixtures"
|
||||
make bench-witness-divergence
|
||||
EXTRACT_COUNT=$(python3 -c "
|
||||
import json
|
||||
lines = [l for l in open('$FIXTURE_PATH').read().splitlines() if l.strip()]
|
||||
# subtract meta line
|
||||
print(max(0, len(lines) - 1))
|
||||
")
|
||||
log "phase 2 done — fixture file holds $EXTRACT_COUNT cumulative divergence rows"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 3 — commit if --commit AND something changed
|
||||
# ---------------------------------------------------------------------------
|
||||
if [[ "$COMMIT" -ne 1 ]]; then
|
||||
log "phase 3 — skipped (no --commit; dry-run)"
|
||||
log "DONE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if git diff --quiet "$FIXTURE_PATH" "$SWEEP_OUT" 2>/dev/null; then
|
||||
log "phase 3 — fixture + sweep unchanged; nothing to commit"
|
||||
log "DONE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Make sure we're on the requested branch.
|
||||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [[ "$CURRENT_BRANCH" != "$BRANCH" ]]; then
|
||||
log "WARNING: on branch $CURRENT_BRANCH, expected $BRANCH; not committing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Stage + commit. Pre-commit hooks must succeed; if they fail the commit
|
||||
# is aborted and we exit non-zero (cron mail will show the failure).
|
||||
git add "$FIXTURE_PATH" "$SWEEP_OUT"
|
||||
git commit -m "witness sweep auto-update: $SWEEP_DIVERGENCE divergence(s) this run
|
||||
|
||||
Extracted by witness_sweep_cron.sh — $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
Divergence count this run: $SWEEP_DIVERGENCE
|
||||
Total fixture rows: $EXTRACT_COUNT"
|
||||
|
||||
NEW_SHA=$(git rev-parse HEAD)
|
||||
log "phase 3 done — committed $NEW_SHA"
|
||||
|
||||
if [[ "$PUSH" -eq 1 ]]; then
|
||||
log "phase 4 — pushing to origin/$BRANCH"
|
||||
git push origin "$BRANCH"
|
||||
log "phase 4 done"
|
||||
else
|
||||
log "phase 4 — skipped (no --push); operator runs git push manually"
|
||||
fi
|
||||
|
||||
log "DONE"
|
||||
|
|
@ -76,7 +76,7 @@ Newest first. Update on every open/close.
|
|||
| #000021 | 5S/5T/5R benchmark fixtures + harness | closed · Phase 1a + 2 landed 2026-05-08 | 2026-05-07 | — |
|
||||
| #000020 | Capital-cost ledger (8-capital queues) | closed · landed 2026-05-07 | 2026-05-07 | — |
|
||||
| #000019 | Specification methodology for π* and V | closed · landed 2026-05-07 | 2026-05-07 | — |
|
||||
| #000018 | Adversarial soft-hash covert-channel analysis | open · awaiting go/no-go | 2026-05-07 | — |
|
||||
| #000018 | Adversarial soft-hash covert-channel analysis | closed · landed 2026-05-09 (analysis doc) | 2026-05-07 | — |
|
||||
| #000017 | Memory-root: lifelong learning audit chain | closed · landed 2026-05-07 | 2026-05-07 | — |
|
||||
| #000016 | ZK Phase-2 frontier proof (concretize) | open · awaiting go/no-go | 2026-05-07 | — |
|
||||
| #000015 | π* domain library + cross-domain composition | closed · landed 2026-05-07 | 2026-05-07 | — |
|
||||
|
|
|
|||
432
docs/soft-hash-channel-analysis.md
Normal file
432
docs/soft-hash-channel-analysis.md
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
# Soft-hash covert channel analysis
|
||||
|
||||
**Ticket:** #000018
|
||||
**Authored:** 2026-05-09
|
||||
**Audience:** fox + future blackops shifts + downstream Merkle-AGI v7+ authors
|
||||
**Stance:** defensive only — detection / flagging / bound-derivation, never
|
||||
generation or concealment.
|
||||
|
||||
---
|
||||
|
||||
## 0. Executive summary
|
||||
|
||||
We analyze whether an adversary controlling some fraction of training
|
||||
data, gradient computation, or hyperparameter scheduling can drive a
|
||||
v7-§9 plastic-trained model so that its **next snapshot's hard hash
|
||||
`C(M_{t+1})`** lands on a prearranged target value or value-class,
|
||||
exploiting the soft-hash anchor map `φ` as a side-channel.
|
||||
|
||||
Result, under the assumptions stated in §5:
|
||||
|
||||
> **Under threat models T1 (data poisoner) and T2 (gradient adversary),
|
||||
> the channel is bounded by a SHA-256 partial-preimage hardness
|
||||
> reduction (§4). Under T3 (hyperparameter adversary), the channel is
|
||||
> bounded by the per-checkpoint mitigation budget M2 (re-randomized
|
||||
> anchors); residual channel without M2 is at most O(log N · entropy
|
||||
> of training-data choices) bits per checkpoint window.**
|
||||
|
||||
Recommended mitigation: **M2 (per-checkpoint anchor nonce)**, costing
|
||||
one additional commit field per snapshot. Falls back to **M1 (PRG-based
|
||||
φ)** if a deployment surfaces residual structure. M3 (drop the anchor)
|
||||
is the strict-construction fallback if both fail; loses some training
|
||||
ergonomics.
|
||||
|
||||
This document is doc-only per the ticket's hard constraint: it
|
||||
recommends, does not implement. A follow-up ticket lands the chosen
|
||||
mitigation.
|
||||
|
||||
---
|
||||
|
||||
## 1. Threat model
|
||||
|
||||
Three adversary capabilities, increasing in strength.
|
||||
|
||||
### 1.1 T1 — Data poisoner
|
||||
|
||||
Adversary controls a fraction `f ∈ (0, 1)` of training-data examples.
|
||||
Training loop is honest; aggregator is honest; hyperparameters are
|
||||
honest; `φ` is the published deterministic embedding. Poisoned
|
||||
examples are valid in distribution (otherwise an outlier filter
|
||||
catches them).
|
||||
|
||||
**Goal:** poisoned examples drive `Q(Θ_{t+1})` to a region whose soft
|
||||
hash `h_v(t+1)` projects to a SHA-256 bucket the adversary can predict.
|
||||
Concretely: adversary tries to land `C(M_{t+1})` in a target class
|
||||
`T ⊂ {0,1}^{256}` with `|T|/2^{256} = ε` (so the 'class' could be
|
||||
"first byte 0xAA" → ε = 2^-8, or "specific 256-bit value" → ε = 2^-256).
|
||||
|
||||
### 1.2 T2 — Gradient adversary
|
||||
|
||||
T1 + adversary controls a fraction `g` of gradient computations
|
||||
(e.g., compromised data-parallel worker that returns dishonest local
|
||||
gradients to the central aggregator). Aggregator is still honest.
|
||||
|
||||
Adversary can bias the gradient signal in arbitrary directions —
|
||||
not bounded to legitimate-data-distribution reach. Tighter than T1.
|
||||
|
||||
### 1.3 T3 — Hyperparameter adversary
|
||||
|
||||
T2 + adversary controls some learning-rate / scheduler / batch-order
|
||||
decisions. Adversary can synchronize gradient updates with anchor
|
||||
geometry to maximize alignment. Strictly stronger than T2.
|
||||
|
||||
### 1.4 What's NOT in scope
|
||||
|
||||
- Direct attack on `C(M_t)` itself (preimage-attack on SHA-256). Out
|
||||
of scope by A3 in v7 §3 (collision-resistant hash assumption).
|
||||
- Side-channel on training infrastructure (Spectre, RowHammer,
|
||||
compromised CPU). Different threat model.
|
||||
- Adversary controlling the published `φ` seed retroactively. Once
|
||||
φ's seed is public, it's frozen; this ticket assumes seed is
|
||||
honestly drawn at v7 boot.
|
||||
- Compromised aggregator that lies about the snapshot bytes.
|
||||
Different threat model — that's a checkpoint integrity attack,
|
||||
not a covert channel.
|
||||
|
||||
---
|
||||
|
||||
## 2. v7 § 9 plastic training, recap
|
||||
|
||||
The relevant slice of the v7 spec:
|
||||
|
||||
```
|
||||
Θ — model parameters (continuous, ~10^9 floats)
|
||||
Q(Θ) — public quantization of Θ (SQD §3, integer kernel)
|
||||
C(M) — SHA-256(canonical-encoding of Q(Θ) ∥ metadata)
|
||||
↑ THE HARD HASH — committed bytes
|
||||
h_v(Θ) — soft hash, dim_h-vector function of Θ
|
||||
↑ THE SOFT HASH — used during training only
|
||||
φ(C(M)) — anchor map: SHA-256 digest → dim_h vector
|
||||
↑ FIXED DETERMINISTIC, published seed
|
||||
```
|
||||
|
||||
Plastic training loss at step t:
|
||||
|
||||
```
|
||||
L_total(Θ_t) = L_task(Θ_t) + α · ‖h_v(Θ_t) - φ(C(M_{t-1}))‖²
|
||||
↑ L2 anchor pull
|
||||
```
|
||||
|
||||
The anchor term pulls the model's soft hash toward the embedding of
|
||||
the *previous* checkpoint's hard hash. At each checkpoint boundary t →
|
||||
t+1, we compute Q(Θ_{t+1}) → C(M_{t+1}) and that becomes the next
|
||||
anchor.
|
||||
|
||||
The dual-hash separation theorem (T6, v7 §3): C(M) is determined
|
||||
solely by Q(Θ) and metadata; soft-hash bytes never enter the
|
||||
SHA-256 preimage. **First-order conclusion:** training cannot
|
||||
directly affect committed bytes.
|
||||
|
||||
The covert-channel concern: training does affect Q(Θ) (that's what
|
||||
training does). The question is whether the L2 anchor term lets the
|
||||
adversary *steer* Q(Θ) toward a target SHA-256 bucket.
|
||||
|
||||
---
|
||||
|
||||
## 3. Channel capacity definition
|
||||
|
||||
Define the **per-checkpoint covert channel** as the mutual information
|
||||
|
||||
```
|
||||
I_t = I(adversary inputs at training step ≤ t ; C(M_{t+1}))
|
||||
conditional on the public training history H_{≤t}
|
||||
```
|
||||
|
||||
The conditioning on `H_{≤t}` (public training history: published
|
||||
losses, public hyperparameters, public seeds) removes the
|
||||
"adversary trivially knows what they did" channel. We measure the
|
||||
bits the adversary can steer ABOVE the public information's
|
||||
predictive power.
|
||||
|
||||
A non-adversarial bound: under random training, `C(M_{t+1})` is
|
||||
near-uniform on `{0,1}^{256}` conditional on `H_{≤t}` if `Q(Θ_{t+1})`
|
||||
is sufficiently varied. Adversarial bound is the question.
|
||||
|
||||
### 3.1 Capacity bound under random `φ`
|
||||
|
||||
If `φ` is modeled as a random oracle independent of the parameter
|
||||
geometry, then `h_v - φ(C(M_{t-1}))` is a uniform random direction at
|
||||
each checkpoint, and the L2 pull provides no parameter-aligned
|
||||
gradient signal. Under this idealization, the covert channel
|
||||
reduces to:
|
||||
|
||||
```
|
||||
I_t ≤ I(adversary inputs ; Q(Θ_{t+1}))
|
||||
conditional on H_{≤t}
|
||||
```
|
||||
|
||||
…which is the un-amplified channel — adversary is no better off
|
||||
through the soft-hash side-channel than they would be attacking
|
||||
Q(Θ) directly.
|
||||
|
||||
### 3.2 Capacity bound under structured `φ`
|
||||
|
||||
If `φ` has algebraic structure relative to parameter geometry (the
|
||||
v7 reference `embed_hard_to_vec` is a fixed-seed linear projection
|
||||
of the SHA-256 digest), the bound depends on whether gradient
|
||||
updates that minimize the L2 anchor term are *parameter-aligned* to
|
||||
shifts in `Q(Θ)` that move SHA-256 buckets predictably.
|
||||
|
||||
The reduction in §4 shows this dependency reduces to a SHA-256
|
||||
partial-preimage problem.
|
||||
|
||||
---
|
||||
|
||||
## 4. Reduction to SHA-256 partial-preimage
|
||||
|
||||
### 4.1 Reduction sketch
|
||||
|
||||
Suppose adversary `A` exists that, given black-box training oracle
|
||||
access under T1/T2, can drive `C(M_{t+1})` into a target class `T` of
|
||||
density ε with non-negligible probability `p`.
|
||||
|
||||
Construct algorithm `B` that solves SHA-256 partial-preimage:
|
||||
|
||||
```
|
||||
B(target T):
|
||||
1. Initialize a fresh v7 plastic-training run with random seed.
|
||||
2. Run A as a sub-routine, supplying T as the target class.
|
||||
3. After A signals success on checkpoint t+1, output Q(Θ_{t+1}).
|
||||
4. Q(Θ_{t+1}) is then a partial preimage of T under SHA-256.
|
||||
```
|
||||
|
||||
`B`'s success probability is `p` minus the probability that `A`
|
||||
succeeds via legitimate-Q-randomization (i.e., `B` would have
|
||||
solved the problem by random Q-search anyway). Under the standard
|
||||
random-oracle model for SHA-256, the random-Q baseline is `ε`. So:
|
||||
|
||||
```
|
||||
P[B solves partial-preimage] ≥ p - ε
|
||||
```
|
||||
|
||||
If `p > ε + δ` for any non-negligible `δ`, then `B` is a non-trivial
|
||||
SHA-256 partial-preimage attacker — contradicting A3 (collision-
|
||||
resistance / partial-preimage hardness).
|
||||
|
||||
**Conclusion:** under the SHA-256 random-oracle assumption (A3),
|
||||
no T1/T2 adversary can succeed with probability non-negligibly
|
||||
above ε. The channel exists but is bounded at the random baseline.
|
||||
|
||||
### 4.2 Where the reduction is tight, where it's loose
|
||||
|
||||
**Tight:** when `φ` is independent of parameter geometry (M1 or M2
|
||||
applied), the reduction is essentially exact. T1/T2 are bounded to
|
||||
the random baseline.
|
||||
|
||||
**Loose:** when `φ` has structure relative to parameter geometry
|
||||
(reference v7 `embed_hard_to_vec` with fixed-seed linear projection),
|
||||
the gradient feedback through the anchor MAY favor parameter
|
||||
directions correlated with target SHA-256 buckets. We don't know
|
||||
whether this correlation is large enough to break the reduction
|
||||
without explicit structural analysis of `embed_hard_to_vec`.
|
||||
|
||||
This is the residual gap §6 addresses.
|
||||
|
||||
### 4.3 T3 caveat
|
||||
|
||||
T3 (hyperparameter adversary) is NOT bounded by the §4.1 reduction
|
||||
directly. The reduction assumes A's queries to the training oracle
|
||||
follow the published schedule. T3 violates that. Under T3:
|
||||
|
||||
- Adversary can synchronize gradient bursts with anchor geometry
|
||||
via learning-rate schedule manipulation.
|
||||
- Per-checkpoint channel capacity grows with the adversary's
|
||||
schedule-control budget.
|
||||
|
||||
T3 needs M2 (re-randomized per-checkpoint anchor) or M3 (drop
|
||||
anchor). M1 alone may not suffice.
|
||||
|
||||
---
|
||||
|
||||
## 5. Assumptions on `φ`
|
||||
|
||||
Three concrete `φ` choices, with channel-residual under each:
|
||||
|
||||
### 5.1 `φ_linear` — v7 reference (linear projection, fixed seed)
|
||||
|
||||
```
|
||||
φ(digest) = W · digest_as_uint32_vector (W frozen at boot)
|
||||
```
|
||||
|
||||
- **Pros:** fast, deterministic, simple.
|
||||
- **Channel residual:** unclear without explicit structural analysis
|
||||
of W relative to the parameter Hessian. If W has any direction
|
||||
aligned with a low-eigenvalue direction of the loss Hessian, the
|
||||
L2 pull provides cheap parameter movement that aligns with
|
||||
SHA-256 buckets — exploitable under T2 with empirical effort.
|
||||
- **Verdict:** the reduction in §4 is loose under `φ_linear`.
|
||||
|
||||
### 5.2 `φ_PRG` — non-linear PRG-based map (mitigation M1)
|
||||
|
||||
```
|
||||
φ(digest) = PRG(seed=published, output_len=dim_h * 4 bytes)
|
||||
then bytes → floats in [-1, 1]
|
||||
```
|
||||
|
||||
PRG output is computationally indistinguishable from random under
|
||||
the PRG security assumption. Gradient feedback through the anchor
|
||||
is uncorrelated with parameter-space updates that would shift hash
|
||||
bytes predictably.
|
||||
|
||||
- **Channel residual:** zero modulo PRG security (one-way function
|
||||
+ no algebraic structure for the parameter Hessian to exploit).
|
||||
- **Verdict:** §4 reduction is tight under `φ_PRG`.
|
||||
|
||||
### 5.3 `φ_nonce` — re-randomized anchor (mitigation M2)
|
||||
|
||||
```
|
||||
At each checkpoint t, sample fresh random nonce n_t (committed
|
||||
in the snapshot manifest). Compute anchor as
|
||||
φ(C(M_{t-1}) ∥ n_t)
|
||||
where φ is φ_linear or φ_PRG. Adversary can't precompute against
|
||||
the next anchor because n_t is unknown until commitment.
|
||||
```
|
||||
|
||||
- **Channel residual:** even under `φ_linear` base, T1/T2 adversaries
|
||||
can't pre-plan attacks because the gradient direction they want
|
||||
to steer toward is randomized between checkpoints.
|
||||
- **T3 residual:** still bounded — T3 adversary controls timing,
|
||||
not the nonce. Per-checkpoint window is `O(steps) × per-step
|
||||
channel`; the nonce reset zeroes the cumulative steerage.
|
||||
- **Verdict:** lightweight; only adds 32 bytes to the manifest per
|
||||
checkpoint. Closes the residual channel for T1/T2 entirely;
|
||||
bounds T3 by a per-window budget.
|
||||
|
||||
### 5.4 `φ` dropped — anchor term removed (mitigation M3)
|
||||
|
||||
`L_total(Θ) = L_task(Θ) + (no anchor term)`.
|
||||
|
||||
- **Channel residual:** zero by construction (no soft-hash gradient
|
||||
signal at all).
|
||||
- **Loss:** plastic training loses some ergonomics (stable
|
||||
representation between checkpoints relied on the anchor pull).
|
||||
Quantified loss: depends on deployment; estimated in v7 §9.7
|
||||
as 5-15% slower convergence on representation-stability metrics.
|
||||
- **Verdict:** strict-construction fallback. Recommend only if M1
|
||||
+ M2 prove insufficient empirically.
|
||||
|
||||
---
|
||||
|
||||
## 6. Mitigations with residual analysis
|
||||
|
||||
| Mitigation | Cost | T1 residual | T2 residual | T3 residual | Closes the channel? |
|
||||
|------------|------|-------------|-------------|-------------|---------------------|
|
||||
| **None** (v7 reference) | 0 | bounded by §4 reduction (loose under φ_linear) | bounded by §4 reduction (loose under φ_linear) | unbounded structurally | No |
|
||||
| **M1 — φ_PRG** | fast PRG eval per checkpoint | tight bound at random baseline ε | tight bound at random baseline ε | unbounded (T3 controls timing) | T1+T2 yes; T3 no |
|
||||
| **M2 — per-checkpoint nonce** | 32 B in manifest per checkpoint | ε | ε | bounded by per-window budget | T1+T2 yes; T3 bounded |
|
||||
| **M1 + M2** (combined) | both costs | ε | ε | bounded by per-window budget | T1+T2 yes; T3 bounded |
|
||||
| **M3 — drop anchor** | 5-15% training-ergonomics regression | 0 | 0 | 0 | Yes, by construction |
|
||||
| **M4 — gradient-budget cap** | per-step gradient-norm clip | bounds adversary's per-step budget | bounds adversary's per-step budget | bounds T3 per-step | Soft bound; doesn't close |
|
||||
|
||||
---
|
||||
|
||||
## 7. Recommendation
|
||||
|
||||
**Land M2 first** (re-randomized per-checkpoint anchor):
|
||||
|
||||
- 32 bytes additional manifest field, committed in the snapshot.
|
||||
- Closes the T1 + T2 channel under any `φ` choice.
|
||||
- Bounds the T3 channel by per-checkpoint budget (the only
|
||||
attack window is between nonce-publish and next-checkpoint).
|
||||
- No training-ergonomics regression — the nonce is purely
|
||||
per-checkpoint randomization, anchor pull still lands.
|
||||
|
||||
**Add M1 (φ_PRG) as Phase 2** if M2-only deployment surfaces
|
||||
structural concerns (e.g., empirical evidence that T3 attacks
|
||||
within a window achieve > ε success rate).
|
||||
|
||||
**M3 (drop anchor)** stays in reserve as the strict-construction
|
||||
fallback. v7 §9 spec amendment proposed:
|
||||
|
||||
```
|
||||
v7 §9.10 (proposed): The anchor map φ takes both the prior
|
||||
checkpoint's hard hash AND a per-checkpoint nonce committed in
|
||||
the manifest. The nonce is fresh entropy at each checkpoint,
|
||||
sealed before training resumes. This closes the soft-hash covert
|
||||
channel under threat models T1 and T2, and bounds T3 by the
|
||||
per-checkpoint window.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Empirical validation (out of scope; follow-up)
|
||||
|
||||
A small experiment to sanity-check the analysis:
|
||||
|
||||
1. Run v7 §9 plastic training with a deliberately-poisoned dataset
|
||||
targeting "first byte of `C(M)` equals 0xAA" — that's `ε = 2^-8`.
|
||||
2. With M2 disabled (`φ_linear`, no nonce): measure success rate
|
||||
over N checkpoints. Hypothesis: indistinguishable from `ε` if
|
||||
§4 reduction holds under `φ_linear`; structurally elevated if
|
||||
`φ_linear` has Hessian-aligned structure.
|
||||
3. With M2 enabled (`φ_linear`, per-checkpoint nonce): measure
|
||||
again. Hypothesis: indistinguishable from `ε` regardless of
|
||||
`φ_linear`'s structure.
|
||||
4. Same experiment under `φ_PRG`: should match `ε` baseline with
|
||||
or without M2.
|
||||
|
||||
If empirical results diverge from analysis predictions, the
|
||||
analysis is wrong somewhere — likely in §5 about `φ_linear`'s
|
||||
structural alignment with the parameter Hessian.
|
||||
|
||||
This experiment is a follow-up ticket; not in scope here.
|
||||
|
||||
---
|
||||
|
||||
## 9. Open questions
|
||||
|
||||
The reduction in §4 leaves three loose threads:
|
||||
|
||||
1. **Hessian alignment under `φ_linear`.** Is the v7 reference
|
||||
`embed_hard_to_vec` matrix W aligned with low-eigenvalue
|
||||
directions of the typical training-loss Hessian? If yes, T2
|
||||
adversaries with full gradient control can amplify steerage
|
||||
beyond the §4 random-oracle baseline. **Test:** compute the
|
||||
spectrum of `W^T W` and compare to typical Hessian eigenvalue
|
||||
distributions on representative checkpoints.
|
||||
|
||||
2. **PRG modeling for `φ_PRG`.** The §4 reduction treats `φ_PRG`
|
||||
as a random oracle. In practice it's a deterministic PRG with
|
||||
public seed. The reduction holds modulo PRG security; we
|
||||
should pick a PRG with cryptographic strength matching SHA-256
|
||||
(e.g., AES-256-CTR with public IV; or HMAC-SHA-512 expansion).
|
||||
**Decision:** use HMAC-SHA-512(seed, digest ∥ counter) for
|
||||
dim_h floats. Keeps the dependency surface (already on SHA-256)
|
||||
tight.
|
||||
|
||||
3. **T3 per-window budget formal bound.** §6 lists "bounded by
|
||||
per-window budget" without giving the bound. The bound depends
|
||||
on (a) the per-step adversary control bandwidth, (b) the
|
||||
between-nonce window length, (c) the gradient-magnitude budget.
|
||||
**Open:** explicit bound calculation, deferred to either a
|
||||
v7 §9.10 spec amendment or a follow-up ticket.
|
||||
|
||||
---
|
||||
|
||||
## 10. References
|
||||
|
||||
- v7 § 3 (T6 dual-hash separation theorem)
|
||||
- v7 § 9 (plastic training; the source of the L2-anchor term)
|
||||
- v7 § 9.9 (the "backdoor via soft hash" first-order dismissal we're
|
||||
superseding)
|
||||
- SQD § 3 (hard-hash construction for Q(Θ))
|
||||
- SQD § 5 (integer-kernel discipline; bigint accumulator)
|
||||
- ticket #000018 (this document is the closure deliverable)
|
||||
|
||||
---
|
||||
|
||||
## 11. Status
|
||||
|
||||
**Open questions:** §9.1 (Hessian alignment under `φ_linear`),
|
||||
§9.2 (PRG cryptographic strength for `φ_PRG`), §9.3 (T3 per-window
|
||||
explicit bound).
|
||||
|
||||
**Closed:** §4 reduction shows T1/T2 are bounded by SHA-256 partial-
|
||||
preimage hardness under any `φ` independent of parameter geometry.
|
||||
M2 (per-checkpoint nonce) closes residual channels at minimal cost.
|
||||
|
||||
**Recommendation:** v7 spec amendment §9.10 lands the M2 nonce.
|
||||
Implementation ticket follows.
|
||||
|
||||
**Doc closure criterion** (per #000018 §7): reduction stated, mitigation
|
||||
recommended, residual-bound table present (§6). Done.
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Ticket #000018 — Adversarial soft-hash covert channel analysis
|
||||
|
||||
**Status:** open · awaiting go/no-go
|
||||
**Status:** closed · landed 2026-05-09 (analysis doc at `docs/soft-hash-channel-analysis.md`)
|
||||
**Opened:** 2026-05-07
|
||||
**Scope:** Formal threat model + falsifier set for whether training
|
||||
gradients can route information from training data through soft hashes
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue