Skip to content

Releases: ValiChord/ValiChord

v0.6.5 — Holochain 0.7, and the protocol work that rode the hash break

Choose a tag to compare

@topeuph-ai topeuph-ai released this 04 Aug 21:39

v0.6.5 — Holochain 0.7, and the protocol work that rode the hash break

The migration to the Holochain 0.7.0 toolchain (hdi 0.8.0 / hdk 0.7.0), merged to main on 2026-08-03 after being developed in isolation on a v0.7.0 branch. main was deliberately kept on the working, publicly-demoed 0.6.2 stack until the branch was fully green.

⚠️ Despite the patch-level version number, this is a breaking release. The number is kept in the 0.6.x line to avoid colliding with "Holochain 0.7.0" in conversation — it does not mean the change is small.

⚠️ Breaking — read before upgrading

  • DNA hashes changed. Zome-definition serialization differs in 0.7, so an otherwise-identical DNA hashes differently. Holochain 0.7 agents form a network separate from 0.6 agents.
  • Every previously published HarmonyRecord URL dies. This was accepted deliberately rather than worked around; the alternative (a close_chain/open_chain migration) carries an agent's own source chain, not the DHT, so it would not have saved a single published record. Prior art assessed in docs/DNA_MIGRATION_PRIOR_ART.md.
  • Conductor state must be cleared. Persistence moved to holochain_data with no migration path. Demo nodes need docker compose -f demo/docker-compose.yml down -v, not just a binary swap.
  • Toolchain pins move to holochain / holochain_cli 0.7.0 and kitsune2_bootstrap_srv 0.5.0.

Protocol work that shipped on top of the migration

Changes that needed a DNA-hash break were deliberately batched into this one rather than buying a second break later.

  • Validator→bundle binding — a validator may set reproduction_bundle_hash, the content_hash of their own valichord_attestation bundle. It is inside the hashed struct, so it is sealed into the commitment automatically: a verdict becomes a claim about a specific set of per-sample outputs rather than the bare word "Reproduced". Optional, and None is a legitimate permanent state — an unbound verdict, not a missing one.
  • The honest recordvalidators_requested now sits beside the participant list, so a round that closed early reads "3 of 7" rather than silently "3". The denominator is part of the permanent record. Scoping, including the two arguments against doing it, is in docs/HONEST_RECORD_SCOPING.md.
  • HarmonyRecord undercount fix — participation could be understated permanently, and the count feeds the badge tier. A HarmonyRecord is immutable, so a wrong tier was wrong forever.
  • The liveness gate — force-finalisation now refuses while a validator still holds a live claim. Age alone is not evidence of abandonment.
  • DataLocalityMode (Gdpr | OpenAudit) groundwork, plus the LockedResult delete guard that had been missing entirely.

Testing

  • The Tryorama suite was retired, not migrated (92 TypeScript tests). Upstream @holochain/tryorama is unmaintained — a banner landed in Jan 2026 saying Holochain 0.7+ support "should not be expected", pointing at sweettest. Porting to a dead runner would have been work with a known expiry date.
  • It was audited one test at a time before deletion. ~69 were already duplicated in sweettest; every unique test was ported and run green first. That audit found three guards with no working coverage at all — the conflict-of-interest rule, DNA 2's cross-agent privacy, and link_agent_identity's two signature checks — each now covered by a test that has been seen to fail.
  • The immutability tripwires are no longer branch-scoped. They were gated to the v0.7.0 branch, which would have silently stopped them the moment that branch merged — removing the only proof that the integrity zomes still reject forbidden updates and deletes. They now run everywhere.
  • A negative control was run for the governance delete guards: deleting the GovernanceDecision arm made a forbidden delete succeed with a real ActionHash. The test failed as designed; restoring the arm turned it green.
  • 150 automated tests, none skipped — 114 sweettest (including the 15 immutability tripwires and 5 real-Ed25519 membrane-proof tests), 30 Rust unit, 6 Playwright browser e2e.

Frontend and tooling

  • Svelte UI on @holochain/client 0.21.0 — 6/6 Playwright e2e green against a real 0.7 conductor.
  • Wind-tunnel builds on 0.7 again. The merge broke it in a way the "blocked upstream" note had hidden: the scenarios depend on valichord_shared_types by path, so moving that crate to hdi 0.8.0 collided with the crates.io runner's Holochain 0.6. Fixed properly by pinning the runner to a git rev of upstream's own "Update to Holochain 0.7.0" commit; the CI job is re-enabled rather than muted.

Documentation corrections

The README described the 0.6.2 stack and carried instructions that had been dead since the Tryorama retirement — cd tests && npm test pointed at a deleted directory. Also corrected: three numbers, all re-measured rather than remembered (valichord_attestation is 487 tests, not 537; six adapters, not five — WandbRunAdapter was undocumented; the 97% coverage figure was right).

🔴 Known limitation — the live demos are not this build

Oracle still runs Holochain 0.6.2. main and the public demos at valichord-demo.onrender.com therefore describe different stacks until Oracle is rebuilt. That rebuild is a full rebuild with state loss and is the next deployment task. The README now says so in place.

Verification

CI run 30819563258 on bc3ed82b was 10/10 green across every job — sweettest matrix, unit, Playwright e2e, immutability tripwires, and the dependency-free supply-chain guard that checks the committed bundles contain no test-only hooks. A full demo round was also run end-to-end on the merged DNA. Only markdown changed between that commit and this tag.

v0.6.1 — Coordinator auto-updater + live-ops hardening

Choose a tag to compare

@topeuph-ai topeuph-ai released this 23 Jul 20:53

v0.6.1 — Coordinator auto-updater + live-ops hardening

Still on the Holochain 0.6.2 toolchain — no DNA-hash or protocol change. This release is about operating the live demo safely and keeping the always-on Oracle nodes current without downtime.

Coordinator auto-updater (new)

A checksum-verified way to roll coordinator-zome fixes onto the live Oracle nodes with zero DNA-hash change, so published HarmonyRecord URLs survive. Opt-in and default-OFF — nothing changes until a deployment sets AUTOUPDATE=on.

  • demo/pack-coordinators.mjs — packs the coordinator WASMs and emits a coordinators-manifest.json with a monotonic revision, a pinned conductor version, and a sha256 over each raw WASM.
  • demo/coordinator-autoupdate.mjs — a poller that, on a newer revision, downloads each WASM and sha256-verifies it before applying anything (any mismatch aborts), guards the manifest's Holochain version against the running conductor, applies UpdateCoordinators per cell, asserts the DNA hash is unchanged, runs a read-only verify call, and records the applied revision on the persisted volume. Modes: loop / --once / --check. Non-fatal in loop mode.
  • Rollback safety valveAUTOUPDATE_MAX_REVISION pin ceiling holds the fleet at a known-good revision; revert by rolling forward (immutable releases).
  • demo/publish-coordinators.sh — publishes the manifest + WASMs as an immutable GitHub release and prints the AUTOUPDATE_MANIFEST_URL.
  • demo/rehearse-autoupdate.sh — self-cleaning end-to-end rehearsal against a throwaway conductor. Ran green: applies to all four cells, DNA-hash assertion holds on each, verify OK, marker advances.
  • Plan + full detail: docs/AUTO_UPDATER_SIDECAR_PLAN.md.

Live-ops hardening

  • First live coordinator hot-swap on Oracle (demo/hotswap-coordinators.mjs) — rolled the local-read change onto all four nodes via UpdateCoordinators, zero downtime, HarmonyRecord URLs preserved.
  • Self-authored lookups now read locally (GetStrategy::Local) in the attestation coordinator — avoids cold-cell DHT-walk stalls; quorum/other-agent reads stay Network.
  • Decentralised demo rebuilt on a new Oracle server (Ampere A1 / ARM) after the previous free-tier VM was reclaimed; Dockerfile.node now arch-detects and fetches the right binaries.

UI end-to-end tests

  • Playwright e2e suite against a real conductor for valichord-ui, plus a CI job.
  • Fixed a production bug it caught: a pattern attribute on the data-hash input silently blocked every request submission.

Docs & site

  • GitHub Pages refresh (live-demo wiring, logo, ownership repoint), a forward-looking sharding impact/migration design note, and the Holochain 0.7.0 release-candidate watch note (we hold on 0.6.2 until 0.7.0 is stable).

Full changelog: v0.6.0...v0.6.1

Coordinator revision 1 (holochain 0.6.2)

Choose a tag to compare

@topeuph-ai topeuph-ai released this 23 Jul 21:07

Coordinator auto-updater bundle, revision 1, built against holochain 0.6.2. Consumed by demo/coordinator-autoupdate.mjs (see docs/AUTO_UPDATER_SIDECAR_PLAN.md).

v0.6.0 — Commit-reveal verification enforced on-chain + Holochain 0.6.2

Choose a tag to compare

@topeuph-ai topeuph-ai released this 06 Jul 16:51

First release since v0.5.4 (2026-05-24) — 194 commits across the protocol, the attestation library, the demo stack, and testing infrastructure.

Versioning note: v0.5.5–v0.5.7 were used as internal milestone labels in project docs but never tagged; GitHub releases jump from v0.5.4 directly to v0.6.0. The minor bump reflects protocol-level changes below (including a DNA hash change).

Core protocol (valichord/)

  • Commit-reveal hash verification enforced on-chain for real nonces. submit_attestation's verification bypass is narrowed from "credential issuer empty" to "issuer empty AND nonce empty", mirroring reveal_researcher_result. A validator's revealed verdict is now checked against their sealed commitment even on dev-mode networks whenever a real nonce is used — a tampered reveal is rejected with a hash mismatch. Proven by two new security sweettests: S7 (genuine seal → nonce → reveal flow passes verification) and S8 (verdict altered between sealing and reveal is rejected). Empty-nonce test flows are unaffected.
  • StudyClaim immutability. Integrity-zome guards now block updates and deletes on StudyClaim — claims are vacated via StudyClaimRelease, as the architecture doc always stated. ⚠️ This is an integrity change: the attestation DNA hash has changed (dev-only impact; existing dev conductors must reinstall the hApp).
  • DeliberateAbstention entry type (validator_workspace) — a validator can cryptographically record a reasoned recusal as a first-class, immutable private entry, distinct from simply never showing up. With duplicate-guard, link index, and 3 sweettests.
  • Reveal-phase quorum gate counts distinct validators (was raw reading count).
  • Holochain 0.6.2 — hdk 0.6.2, hdi 0.7.2, holochain/holo_hash/keystore 0.6.2 across all zomes; hApp repacked; CI binaries bumped.

Attestation library (valichord_attestation)

  • LmEvalAdapter — converts lm-evaluation-harness results_*.json (+ optional samples_*.json) into canonical attestation bundles. Covers the de-facto industry standard for LLM benchmarking. 51 tests.
  • AiluminateAdapter — converts MLCommons AILuminate (modelbench) safety-benchmark reports, committing model responses and grader-ensemble verdicts together as Merkle leaves — blind independent verification for LLM-as-judge grading. 42 tests.
  • prml_lock_hash field — links a bundle to a Falsify/PRML pre-registration lock, plus canonicalization edge-case tests.
  • Library now at 537 tests, 97% line coverage, five adapters total (InspectAI, InspectEvals, PiSession, LmEval, AILuminate).

Interoperability

  • OETP bridge — embed a ValiChord HarmonyRecord into an Open Ethics Transparency Protocol disclosure (IETF Internet-Draft JSON standard); --emit-oetp flag on the demo runner. 28 tests.
  • EveryEvalEver worked example — offline bundle generator for the EEE convergence path.

Demo & operations

  • Security sweep: visitor API keys scrubbed from job state on completion + 1 h TTL eviction; agent-env cache keyed by key hash and size-capped; opt-in node-API write authentication (NODE_API_KEY, timing-safe); memory caps on node-side maps; constant-time API-key comparison in the backend; CI action pinned to SHA.
  • Honest reveal-verification copy on the demo website — the site now states precisely what the demo network enforces versus what production networks enforce.
  • CMA performance: one shared agent environment per run, session timeout, and tool-call cap.
  • Claim-vocabulary headline for custom-claim results; node URLs default to localhost.

Project & governance

  • CONTRIBUTING.md (contributor guide + lightweight CLA), NOTICE, and TRADEMARK.md — open-core IP structure established.
  • EU AI Act Article 12 compliance plan — ValiChord as evaluation-layer evidence infrastructure.

Testing & infrastructure

  • Wind-Tunnel: runner bumped to 0.7.0; two new propagation scenarios (dht_sync_lag, Kitsune substrate prototype); first live multi-conductor run — median cross-DHT sync lag ≈ 185 ms; CI smoke job.
  • Badge sweettest hardening: gold, silver, and bronze badge tests now use a re-sync + re-query retry loop against the documented badge-index gossip-lag flake; full CI matrix green (97 Tryorama + 5 sweettest suites).
  • Dev conductor lifetime tied to dev.sh (setpriv --pdeathsig); @holochain/client floor at 0.20.5.

Full changelog: v0.5.4...v0.6.0


Addendum (2026-07-06, same day): UI e2e suite + form-blocking bug fix

  • Playwright e2e suite for the browser UI (valichord-ui/tests/e2e/) — one real throwaway conductor per run, no mocks: connection bootstrap, validator profile via the UI form, request submission via the researcher form, pending-request rendering, zome-seeded data, governance view. Runs locally via npm run test:e2e (~1.3 min) and in CI as a new independent ui-e2e job (~2 min, traces uploaded on failure). Pattern ported from happenings-community/requests-and-offers.
  • Fixed: the researcher form's Submit button silently did nothing. Svelte parses {64} inside a quoted attribute as a template expression, so pattern="[0-9a-f]{64}" rendered as pattern="[0-9a-f]64" — native form validation rejected every real 64-character hash with no visible error. Caught by the e2e suite on its first run.
  • README refreshed: repo links updated to the ValiChord org, current Your Hypothesis demo described, test counts corrected (183 across three suites), Holochain 0.6.2 quickstart, five attestation adapters.

Addendum (2026-07-08, post-tag — commits 7e8b2e6 + a2593d0 on main): local-read rule + first live coordinator hot-swap

  • Self-authored lookups now read locally (attestation coordinator). release_claim, get_my_claimed_studies, and the duplicate-commitment guard in notify_commitment_sealed use GetStrategy::Local for reads whose results are entirely the calling agent's own writes — the source chain is complete by construction, so a network walk adds nothing except a hang risk on a fresh or cold cell. Everything that can include other agents' writes (reveal-quorum counts, reclaimer-written releases, protocol guards) still reads from the network. This is a reliability fix, not a speed-up: typical demo-run time is unchanged; what's eliminated is a class of cold-node stalls and timeouts, plus snappier claimed-studies views in the browser UI. Pattern borrowed from flowsta-signing-dna v1.4. Verified by the four sweettests covering the changed functions plus the full CI matrix.
  • First live coordinator hot-swap. Because the change touches no integrity zome, it was rolled onto all four live Oracle demo nodes via AdminRequest::UpdateCoordinators — zero downtime, DNA hashes unchanged, no container restarts, every published HarmonyRecord URL preserved. The rollout tooling ships as demo/hotswap-coordinators.mjs (local rehearsal mode + per-container runbook in the header), establishing a minutes-not-hours upgrade path for future coordinator-level fixes to the live network.

v0.5.4 — Security hardening and audit sweep

Choose a tag to compare

@topeuph-ai topeuph-ai released this 24 May 18:24

Security hardening

Warrant gate coverage

Four coordinator entry points that previously allowed warranted (banned) agents to write state have been closed:

  • submit_validation_request — warranted agents could spam fake study submissions
  • publish_validator_profile — warranted agents could create/update validator profiles
  • assess_difficulty — warranted agents could manipulate difficulty assessments
  • link_agent_identity — warranted agents could inject cross-device identity links

All four now call reject_if_warranted(&agent)? at the start of the handler, consistent with the existing pattern on notify_commitment_sealed, submit_attestation, and claim_study.

Integrity validation gaps closed

Two entry types had no validate() coverage and are now guarded at the integrity zome level:

  • ResearcherResultCommitmentresult_commitment_hash must be exactly 32 bytes (SHA-256). A malformed hash would permanently block the researcher's reveal with no visible error.
  • HarmonyRecordvalidator_types (position-parallel to participating_validators) must be empty or the same length. A length mismatch causes out-of-bounds panics in UI lookups. The field is #[serde(default)] for backwards compatibility with pre-existing records.

TypeScript serde fix

BadgeType in valichord-ui/src/lib/types.ts used the wrong string names ("Gold", "Silver", "Bronze", "Failed"). The Rust enum serialises to "GoldReproducible", "SilverReproducible", "BronzeReproducible", "FailedReproduction". Fixed — get_badges_by_type calls from the UI now match DHT records.


Earlier fixes (since v0.5.3)

  • Badge issuance hardening — atomic check before writing HarmonyRecord; BadgeType imported from valichord_shared_types, not re-declared in governance
  • Claim release authorisation — only the original claimant or study submitter may release a claim
  • Warrant filter in governanceget_all_validators no longer surfaces warranted agents
  • Cross-DNA error handlingcall_attestation_zome_opt propagates WasmError correctly instead of swallowing internal failures
  • Timeout cast safetyreclaim_abandoned_claim timeout comparison uses saturating arithmetic

Test coverage

New sweettest tests (attestation DNA — tests 16–20):

# Test What it covers
16 update_validator_profile_merges_fields Supplied Some fields overwrite; None fields preserved
17 check_all_commitments_sealed_lifecycle Returns false before quorum, true after both validators commit
18 get_researcher_reveal_none_then_some Returns None before reveal, Some(Record) after
19 revoke_agent_identity_link_removes_from_linked_agents Deleted entry filtered from get_linked_agents
20 get_my_claimed_studies_filtered_by_release Released claim excluded from Vec<Record> result

New sweettest test (governance DNA — test 17): get_pending_request_refs returns studies for both ComputationalBiology and Discipline::Other("custom") disciplines; force_finalize_round succeeds end-to-end for Discipline::Other.

Total sweettest coverage: 20 attestation + 17 governance tests.

v0.5.3 — Live web demo + valichord_attestation v1.2.0

Choose a tag to compare

@topeuph-ai topeuph-ai released this 22 May 18:23

Live web demo

valichord-demo.onrender.com/demo

One-click browser interface to the full ValiChord commit-reveal protocol. Click Run Protocol and watch the live Holochain network on Oracle Cloud run a real reproducibility validation — researcher and three independent Claude Haiku validators committing blind, then revealing simultaneously. Takes ~2 minutes because that is real network time, not a timer.

At the end of each run the page shows a curl command to fetch the HarmonyRecord directly from the Oracle DHT — confirming the result was written by the Holochain network, not generated by the web page.

See demo/DEMO_WEBSITE.md for the full technical guide (Flask architecture, request flow, concurrency design, Render deployment).


valichord_attestation v1.2.0

PiSessionAdapter — new adapter for pi coding agent session v3 JSONL files. Resolves the active branch via parentId walk, applies compaction filtering, extracts 8 metrics (turns, tool calls, error rate, tokens, cost, compaction count, stop reason), and builds a full Merkle tree over all branch entries. 67 tests.

ValiChordLogger for lm-evaluation-harness — optional logger following the wandb/trackio pattern. Hooks into post_initlog_eval_samples, builds a valichord_attestation bundle (Merkle tree over per-sample filtered_resps, stable SHA-256 commitment via RFC 8785), and saves it alongside the results_*.json artifact. Wired via --valichord_args output_path=./results CLI flag. See topeuph-ai/lm-evaluation-harness.

Format v1.2 (carried from v0.5.21): Metric.filter field for multi-filter tasks; Bundle.meta provenance block; dual bundle_hash / content_hash. All v1.0 and v1.1 bundles remain valid.

326 tests, 99% line coverage.


falsify/PRML integration

valichord_attestation is now cited in falsify-cookbook Pattern 13 (PRML + commit-reveal validation, co-authored with Cüneyt Öztürk / Studio 11) and in the falsify v0.3 spec backlog as a prior-art precedent for bundle-side count commitment (samples_totalleaves_total analogy).


Other changes since v0.5.21

  • Holochain 0.6.1 upgrade complete (iroh/QUIC transport; kitsune2-bootstrap-srv 0.4.1)
  • Svelte 5 UI wired end-to-end to live conductor; all three protocol roles functional
  • Governance badge idempotency fix — issue_badge_if_missing() now retries from the idempotency return path
  • Full test suite: 96 Tryorama tests pass (1 skipped — WebSocket exhaustion in Codespaces), 47 sweettest tests pass

v0.5.21 — InspectAILogAdapter + eval_yaml_metadata enrichment + attestation skill

Choose a tag to compare

@topeuph-ai topeuph-ai released this 17 May 13:22

What's new since v0.5.2

InspectAILogAdapter — direct inspect_ai log file support

New adapter that reads inspect_ai `.eval` / `.json` log files directly via the inspect_ai Python API, with no pre-parsing step.

Field mapping:

  • `EvalSpec.model` → `model_id`
  • `EvalSpec.task` → `task_id`
  • `EvalSpec.created` → `generated_at`
  • `EvalSpec.revision.commit` → `repo_commit` (auto-extracted)
  • `EvalResults.scores` → `metrics` (all scorers combined; scorer-name prefix on key collision)
  • `EvalLog.samples` → `outputs_merkle_root` (per-sample dicts: id, epoch, output, scores)

`inspect_ai` is an optional dependency — pass a pre-loaded duck-type to avoid the import. Use `score_name=` to restrict to a single scorer. Use `meta_extras=` to merge extra provenance into `Bundle.meta`.

from valichord_attestation import InspectAILogAdapter

adapter = InspectAILogAdapter()
bundle = adapter.to_bundle("logs/my_eval.eval")

InspectEvalsAdapter — eval.yaml metadata enrichment

New optional `eval_yaml_metadata=` parameter on `InspectEvalsAdapter.to_bundle()`. Pass the top-level `eval.yaml` dict (not the `evaluation_report` block) to fold task-level provenance into `Bundle.meta`:

eval.yaml field Bundle.meta key
`arxiv` `paper_arxiv`
`group` `eval_group`
`version` `task_version`
`tasks[*].human_baseline` `human_baseline`
`external_assets[*].state: floating` `dataset_reproducibility_warning`
`metadata.requires_internet` `requires_internet`

These fields are excluded from `content_hash` (as all meta fields are), so they do not affect scientific equivalence comparison between runs.

import yaml
from valichord_attestation import InspectEvalsAdapter

with open("src/gpqa/eval.yaml") as f:
    full_yaml = yaml.safe_load(f)

eval_report_block = full_yaml.pop("evaluation_report")
bundle = InspectEvalsAdapter().to_bundle(
    eval_report_block,
    samples,
    eval_yaml_metadata=full_yaml,
)

generate-attestation-bundle Claude Code skill

New project-local skill at `.claude/skills/generate-attestation-bundle/`. Step-by-step workflow for adding attestation as the final step after an inspect_evals eval report — covers both the `InspectAILogAdapter` (file path) and `InspectEvalsAdapter` (eval.yaml) paths, plus challenge-response verification.


Package exports

Both `InspectAILogAdapter` and `InspectEvalsAdapter` are now exported from the package top level:

from valichord_attestation import InspectAILogAdapter, InspectEvalsAdapter

`inspect-ai` added as an optional dependency group in `pyproject.toml`:

pip install "valichord_attestation[inspect-ai]"

Running the examples

pip install -e "valichord_attestation[dev]"
pytest valichord_attestation/tests/   # 259 tests, 100% line coverage

# GSM8K demo (Mistral-7B, no GPU required):
python valichord_attestation/examples/mistral_7b_gsm8k_demo/challenge_response_demo.py

# inspect_ai popularity demo (GPT-4o-mini, no GPU required):
python valichord_attestation/examples/inspect_ai_popularity_demo/challenge_response_demo.py

259 valichord_attestation tests (183 → 259, +76). 100% line coverage maintained.

v0.5.2 — Holochain 0.6.1 (iroh/QUIC) + attestation format v1.2 + coordinator_utils + UI patterns

Choose a tag to compare

@topeuph-ai topeuph-ai released this 11 May 20:07

What's new since v0.5.1

Holochain 0.6.1 upgrade — iroh/QUIC transport (2026-05-13)

Full upgrade of the Holochain toolchain from 0.6.0 to 0.6.1. All 166 integration tests confirmed green on the new transport.

Transport: iroh/QUIC replaces tx5/WebRTC as the default. The advanced.tx5Transport conductor config block is dead and has been removed from all conductor YAMLs. kitsune2-bootstrap-srv bumped to 0.4.1 (0.3.x is wire-incompatible).

API changes applied:

  • get_agent_activity now requires a 4th GetOptions::network() parameter — added at all call sites in attestation and governance coordinators
  • recv_remote_signal double-decode removed — 0.6.1 delivers signal payload directly as a msgpack map (no outer bin8 wrapper)
  • WarrantSignedWarrant type rename in AgentActivityResponse — handled automatically by HDK version bump

Version bumps: hdk = "=0.6.1", hdi = "=0.7.1", holochain_serialized_bytes = "=0.0.57", @holochain/tryorama = "0.19.1"

Demo scripts: retryOnTx5retryOnNetworkError in serve.mjs, node-lib.mjs, validator-node.mjs — tx5-specific error strings replaced with generic timeout/channel-drop detection.


valichord_attestation format v1.2

Two additive, backward-compatible changes informed by FazeelUsmani's lm-evaluation-harness PR #3752.

Metric.filter (optional str)
Disambiguates metrics sharing the same key produced by different filter passes (e.g. strict-match vs flexible-extract). None/absent → omitted from canonical encoding entirely.

Bundle.meta + content_hash
meta: Optional[dict] — free-form provenance block (commit, harness version, command, timestamp, n_shot, etc.). Included in bundle_hash (byte identity); excluded from content_hash (scientific equivalence). v1.1 bundles with no meta have content_hash == bundle_hash.

content_hash() added to canonical.py and exported from __init__.py. build_bundle() default format_version bumped to "v1.2". All v1/v1.1 bundles remain valid — no existing hash values change.

Tests: 142 → 183 (+41 new). 100% line coverage maintained.

from valichord_attestation import build_bundle, content_hash

bundle = build_bundle(
    results,
    meta={"commit": "abc123", "n_shot": 5, "harness": "lm-eval 0.4.7"},
)
print(bundle.bundle_hash)   # identity hash (includes meta)
print(content_hash(bundle)) # scientific equivalence hash (excludes meta)

valichord_coordinator_utils — shared Holochain coordinator crate

New coordinator_utils workspace crate (coordinator-only, hdk dep, no integrity zome impact):

  • records_for_links — previously duplicated in both attestation_coordinator and governance_coordinator; now in one place
  • call_other_role_opt — generic typed cross-DNA call helper

No DNA hash change: coordinator zomes only. No behaviour change.


Three flux/ad4m utility patterns ported to ValiChord UI

valichord-ui/src/lib/utils.ts (new)

  • asyncFilter<T> — parallel async predicate filter
  • upsertByHash<T> — immutable upsert for Holochain record arrays keyed by ActionHash

valichord-ui/src/lib/tabCoordinator.ts (new)

  • isLeaderTab writable store — gates periodic DHT polls to the leading tab
  • initTabCoordinator() — BroadcastChannel leader election (claim/hb/resign protocol with UUID tiebreak)

demo/ai_validator.pyform_verdicts() retry loop

  • LLM retry-with-error-feedback (up to 5 attempts per verdict)
  • Validates outcome and confidence against allowed value sets; strips ```json fences

Running the examples

pip install -e "valichord_attestation[dev]"
pytest valichord_attestation/tests/   # 183 tests, 100% line coverage

# GSM8K demo (Mistral-7B, no GPU required):
python valichord_attestation/examples/mistral_7b_gsm8k_demo/challenge_response_demo.py

# inspect_ai popularity demo (GPT-4o-mini, no GPU required):
python valichord_attestation/examples/inspect_ai_popularity_demo/challenge_response_demo.py

166 Holochain integration tests passing (97 Tryorama + 69 Rust sweettest), 183 valichord_attestation tests. Holochain 0.6.1, iroh/QUIC transport.

v0.5.1 — inspect_ai demo + Wind-Tunnel scenarios

Choose a tag to compare

@topeuph-ai topeuph-ai released this 07 May 11:12

What's new since v0.5.0

inspect_ai Popularity Demo — second real-data example

valichord_attestation/examples/inspect_ai_popularity_demo/ is a new end-to-end walkthrough of the v1.1 protocol against an inspect_ai .eval log — a different eval harness format (ZIP-based binary, structured per-sample JSON, C/I scorer values) from the lm-evaluation-harness JSONL format used in the GSM8K demo.

Task: popularity — AI personality self-assessment
Model: openai/gpt-4o-mini
Scorer: match (C/I values)
Source: inspect_ai test suite (21 KB, no GPU required)

The parsing layer uses EveryEvalEver's InspectAIAdapter (pinned to commit dec1ae43), not inspect_ai.log.read_eval_log() directly. This is the concrete alignment artefact with the EvalEval Coalition's aggregate schema, referenced by Matt Fisher in PR #1610 and Scott Simmons's inspect_evals#910 proposal for executable evaluation reports.

# No download required — fixture mode (committed bundle.json):
python valichord_attestation/examples/inspect_ai_popularity_demo/challenge_response_demo.py

# Full reproduction with the real .eval log:
bash valichord_attestation/examples/inspect_ai_popularity_demo/download_eval.sh
python valichord_attestation/examples/inspect_ai_popularity_demo/build_bundle.py --eval-path ./popularity.eval
python valichord_attestation/examples/inspect_ai_popularity_demo/challenge_response_demo.py
File Purpose
download_eval.sh Downloads popularity.eval (21 KB) from inspect_ai's public test suite
build_bundle.py EEE-based parsing path + --fixture mode (committed bundle.json)
challenge_response_demo.py k=20 challenge-response with tamper detection
bundle.json Committed bundle (50-sample simulated fixture, random.Random(42), 80% accuracy)

Honest EEE trade-offs documented in README.md: transitive dependencies (duckdb, seaborn, huggingface-hub<1.0.0 conflict), file-system side-effect (temporary JSONL), and Merkle root change (56c91950…227b5f8d… because EEE emits sample_id as strings vs integers).

Wind-Tunnel performance scenarios

valichord/wind-tunnel/ adds three performance test scenarios for the Holochain protocol layer (separate Cargo workspace, requires a pre-built .happ):

Scenario Description
single_researcher_single_validator Baseline: one commit, one reveal — cold-start timing
three_validators_sequential Three validators commit and reveal sequentially — typical small-panel run
concurrent_commit_burst Ten agents commit simultaneously — DHT write contention under load
VALICHORD_HAPP_PATH=path/to/valichord.happ cargo test --release -p wind_tunnel

Issues backlog

valichord_issues_backlog.md — 20 GitHub issue drafts across three sections: Protocol & architecture (8), Integration & extensions (8), and Honourable mentions (4). Ready to stage and open on GitHub.


Running the examples

pip install -e "valichord_attestation[dev]"
pytest valichord_attestation/tests/   # 142 tests, 100% line coverage

# GSM8K demo (Mistral-7B, no GPU required):
python valichord_attestation/examples/mistral_7b_gsm8k_demo/challenge_response_demo.py

# inspect_ai popularity demo (GPT-4o-mini, no GPU required):
python valichord_attestation/examples/inspect_ai_popularity_demo/challenge_response_demo.py

142 tests, 100% line coverage. Holochain protocol unchanged from v0.5.0.

v0.5.0 — valichord_attestation: canonical AI evaluation attestation

Choose a tag to compare

@topeuph-ai topeuph-ai released this 05 May 13:37

valichord_attestation — Canonical AI Evaluation Attestation Format

This release introduces valichord_attestation/, a Python library that extends ValiChord's commit-hash-reveal principle to AI capability evaluation. A published benchmark score — accuracy, pass@k, agent utility — can now be cryptographically bound to the specific run that produced it and independently verified by any third party.

What's new

valichord_attestation Python library

A harness-agnostic library for producing verifiable attestation bundles for AI evaluation runs. Two properties make a bundle verifiable:

  • Deterministic hash — bundles are encoded with RFC 8785 (JSON Canonicalization Scheme / JCS), so the same run always produces the same bytes and the same SHA-256 digest.
  • Merkle root — a SHA-256 Merkle tree over per-sample outputs lets the log holder prove any individual sample to a verifier without disclosing the full log.
from valichord_attestation import build_bundle, hash_bundle, merkle_proof, verify_faithfulness

bundle = build_bundle(
    model_id="gpt-4o-2024-08-06",
    task_id="gsm8k",
    raw_metrics=[{"key": "accuracy", "value": 0.847, "stderr": 0.025}],
    samples=[{"index": i, "output": "...", "correct": True} for i in range(1319)],
    samples_total=1319,           # assert intended run size — detects silent sample omission
    repo_commit="abc123",
    harness_version="inspect_ai/0.3.19",
)
bundle_hash = hash_bundle(bundle)        # publish alongside the report
proof = merkle_proof(samples, index=42)  # selective disclosure to a verifier
ok = verify_faithfulness(bundle.outputs_merkle_root, 42, samples[42], proof)

Key modules:

Module Purpose
builder.py build_bundle(...) — constructs and validates a Bundle, computes Merkle root, enforces 6dp pre-rounding, rejects NaN/Infinity
canonical.py RFC 8785 JCS encoding; hash_bundle() — SHA-256 hex of the canonical encoding
merkle.py leaf_hash, merkle_root, merkle_proof, verify_faithfulness
bundle.py Bundle dataclass — MalformedBundleError on absent or non-finite fields
challenge.py Challenge, derive_seed, generate_indices, compute_challenge_hash
response.py ChallengeResponse, ResponseSample, build_response, verify_response
adapters/base.py AdapterBase ABC — subclass to wrap any eval harness
adapters/inspect_evals_stub.py Inspect AI stub adapter

Explicit samples_total — sample-omission defence

build_bundle now accepts samples_total: Optional[int]. When provided and larger than len(samples), bundle.samples_total > bundle.samples_completed is directly visible in the bundle without out-of-band context, closing the silent-truncation attack surface described in threat model §10(d). Raises ValueError if samples_total < len(samples) — the declared total can never be less than what was actually logged.

bundle = build_bundle(
    ...
    samples_total=1319,   # declared; if adapter drops samples silently,
                          # bundle.samples_total > bundle.samples_completed
)

Probabilistic challenge-response (additive, no bundle format change)

Selective disclosure lets the log holder choose which samples to prove. The challenge-response protocol inverts control: the verifier picks which samples to inspect, the holder must reveal exactly those, and the verifier gains high-confidence faithfulness evidence without receiving the full log.

from valichord_attestation import hash_bundle, Challenge, build_response, verify_response
import os

challenge = Challenge(
    bundle_hash=hash_bundle(bundle),
    verifier_nonce=os.urandom(32),  # verifier-chosen; holder cannot predict indices
    k=60,
)
response = build_response(challenge, samples)      # holder reveals hashes + Merkle paths only
ok = verify_response(challenge, response, bundle)  # verifier checks all paths against root

Protocol:

  • Seed: HMAC-SHA256(key=verifier_nonce, msg=bundle_hash_ascii)
  • Indices: SHA-256 counter-mode — SHA256(seed || counter_u64_be) mod total_samples, rejection-sampled for distinctness. Language-agnostic; any conforming implementation produces identical indices.
  • Response: hashes and proof paths only — no raw sample content
  • challenge_hash: SHA-256(JCS({"bundle_hash", "k", "verifier_nonce_hex"})) binds the response to the specific challenge

Sensitivity (catch probability = 1 − (1−f)^k):

f \ k k=30 k=60 k=100 k=300
f = 1% 26% 45% 63% 95%
f = 5% 79% 95% 99% >99%
f = 10% 96% >99% >99% >99%

Fixed test vector: bundle_hash='a'*64, nonce=bytes(range(16)), k=5, total=100 → indices [9, 69, 33, 74, 38]

Real-data example — Mistral-7B-Instruct-v0.3 on GSM8K

valichord_attestation/examples/mistral_7b_gsm8k_demo/ is an end-to-end demonstration of the full v1.1 protocol on a real AI benchmark. Runnable without a GPU:

python valichord_attestation/examples/mistral_7b_gsm8k_demo/challenge_response_demo.py
File Purpose
run_eval.sh lm-evaluation-harness v0.5.0, Mistral-7B-Instruct-v0.3, GSM8K 100-sample subset — ~10 min, ~£1.50 on a 4090
build_bundle.py Parses lm-eval output → bundle.json; or --fixture mode (no GPU required). samples_total=100 declared explicitly.
challenge_response_demo.py k=20 challenge with documented fixed nonce, Merkle verification, tamper detection
bundle.json Committed bundle (deterministic fixture, random.Random(42), 35% accuracy — replace with real eval output)

The _source.warning field in bundle.json documents that the committed bundle uses simulated data. Run run_eval.sh on a GPU and re-run build_bundle.py --output-path ./eval_output to produce a bundle from a real evaluation.

Format spec

valichord_attestation/spec/attestation_format_v1.md — bundle schema, canonical encoding rules, pre-rounding policy, Merkle tree construction, proof format and verifier algorithm, probabilistic challenge-response (Section 6, with schemas, seed derivation, index algorithm, sensitivity table, test vector), versioning policy, security considerations including threat model.

142 tests, 100% line coverage.

pip install -e "valichord_attestation[dev]"
pytest valichord_attestation/tests/

# Real-data demo (no GPU required)
python valichord_attestation/examples/mistral_7b_gsm8k_demo/challenge_response_demo.py

What v1 does not include (non-goals)

  • Cryptographic signing — reserved for v2
  • Zero-knowledge proofs — v2+ scope
  • Holochain DHT integration (bundles as on-chain attestations) — follows format stabilisation
  • TEE-backed attestation — separate v2 design

Architectural context

The format was designed in response to Scott Simmons's review of UKGovernmentBEIS/inspect_evals#1610. The core feedback: the canonical attestation spec belongs in ValiChord (the verification infrastructure), not inside each eval harness, and the meaningful attestation is not "I have the log file" but "this reported result is faithful to the run that produced it." The challenge-response protocol moves materially closer to the "verify without log access" property without waiting for ZK proofs or TEE infrastructure.

Documentation updates

  • README.md🔬 AI Evaluation Attestation section updated with challenge-response description, samples_total, real-data demo
  • valichord_attestation/README.md — "Probabilistic Challenge-Response" subsection; "Running the examples" updated
  • valichord_attestation/spec/attestation_format_v1.md — Section 6 (challenge-response) added; §10 threat model updated for samples_total; sections renumbered

166 integration tests passing (97 Tryorama + 69 Rust sweettest), 1 skipped. Holochain protocol unchanged.