Skip to content

152 test vector - #345

Merged
rampyg merged 5 commits into
mainfrom
152_test_vector
Jul 24, 2026
Merged

152 test vector#345
rampyg merged 5 commits into
mainfrom
152_test_vector

Conversation

@kautilyaa

Copy link
Copy Markdown
Collaborator

Summary

Adds the missing upstream contract for the six Vouch runtime module ports (#94 through #105). One Python harness emits canonical test-vectors/<module>/vector.json files from the reference implementation, plus a pytest self check so CI catches drift before Go and TypeScript porters diverge.

Problem

Each runtime module port issue asks contributors to reproduce test-vectors/<module>/vector.json byte for byte from the Python module. Before this PR:

  • No generator existed, so every porter would invent their own fixtures.
  • No canonical vectors were checked in for trust_entropy, quorum, merkle, canary, behavioral_attestation, or heartbeat.
  • trust_entropy uses wall clock time, so ad hoc vectors would be unstable.

Without a single source of truth, the twelve port PRs (#94 through #105) would drift apart.

Solution

Deliverable Purpose
scripts/gen_runtime_vectors.py Imports each runtime module, drives fixed inputs under a pinned clock, UUID and RNG, writes deterministic JSON
test-vectors/<module>/vector.json (six files) Committed cross language contract porters must match
tests/test_runtime_vectors.py Regenerates vectors in memory and asserts byte for byte equality with committed files
test-vectors/README.md Documents format, encodings, determinism rules and the regeneration command

This mirrors the existing test-vectors/ pattern used by jcs/, data-integrity-eddsa-jcs-2022/ and hybrid-eddsa-mldsa44/.

Files changed

scripts/gen_runtime_vectors.py          # new: canonical generator and pinned() context
tests/test_runtime_vectors.py           # new: CI self check (7 parametrized cases)
test-vectors/README.md                  # updated: runtime module section added
test-vectors/trust_entropy/vector.json
test-vectors/quorum/vector.json
test-vectors/merkle/vector.json
test-vectors/canary/vector.json
test-vectors/behavioral_attestation/vector.json
test-vectors/heartbeat/vector.json

Module coverage

Folder Python module Spec Cases What we exercise
trust_entropy/ vouch.trust_entropy 11.5 13 compute_trust_at, evaluate_trust, half_life_seconds, time_until_threshold at pinned times
quorum/ vouch.quorum 11.6 2 2 of 3 approval; rejection when canary chain breaks below threshold
merkle/ vouch.merkle 11.3 8 hash_leaf, hash_node, tree root, inclusion proof verify and fail, compute_action_merkle_root
canary/ vouch.canary 11.7 5 compute_commitment, verify_reveal, 3 interval chain, verifier intact then broken
behavioral_attestation/ vouch.behavioral_attestation 11.3 8 BehavioralCollector.digest, drift scorers, valid and invalid digest validation
heartbeat/ vouch.heartbeat 11.3 3 Two interval build_request, accept first heartbeat, reject broken canary

Total: 39 cases across six modules.

Vector format

Each vector.json follows one shape, modelled on jcs/vectors.json:

{
  "description": "...",
  "module": "vouch.<module>",
  "spec_reference": "Specification 11.x",
  "version": "1.0",
  "pinned": { "now": "...", "uuid": "...", "os_urandom": "..." },
  "cases": [
    { "name": "...", "function": "...", "input": { ... }, "expected": { ... } }
  ]
}
  • cases is ordered. Each case names the function, carries self contained input, and the expected output a porter must match.
  • pinned documents clock, UUID and RNG only where needed (trust_entropy, canary, heartbeat, quorum).
  • Encodings match module wire format: multibase u prefix, lowercase hex hashes, standard base64 secrets, ISO 8601 UTC with trailing Z.

Determinism contract

The pinned() context manager pins every non deterministic source:

Source Pin
Wall clock 2026-01-01T00:00:00Z via explicit at_time / now params and vouch.vc.datetime mock
SessionVoucher UUID urn:uuid:00000000-0000-4000-8000-000000000001
os.urandom (canary secrets) nth call returns byte (n+1) repeated to length; counter resets per vector build
behavioral_attestation._now_ns Pinned for audit samples (not used by digest(), but keeps captured values stable)

Serialization: json.dumps(indent=2, ensure_ascii=False) plus a single trailing newline.

Notes for porters

  • Structural vectors (merkle, canary, heartbeat, quorum, behavioral_attestation) must match exactly.
  • trust_entropy floats: vectors carry exact Python float results for the Python self check. Go and TypeScript should compare exp() and log() within a small tolerance (for example 1e-12 absolute), as documented in test-vectors/README.md.
  • Folder names match Python module names so issue text maps one to one to fixtures.

Acceptance criteria

  • python scripts/gen_runtime_vectors.py produces no diff on re run
  • pytest tests/test_runtime_vectors.py passes (regenerates in memory, asserts byte for byte match for all six modules)
  • Each port issue (Port trust-entropy decay to TypeScript #94 through Port validator quorum to Go #105) can link its test-vectors/<module>/vector.json as the fixture to reproduce
  • README documents format, encodings, determinism and regeneration

Test plan

# Regenerate (should be a no op if vectors are current)
python scripts/gen_runtime_vectors.py
git diff --exit-code test-vectors/

# Self check
pytest tests/test_runtime_vectors.py -v
  • Generator run is idempotent (no diff)
  • All 7 pytest cases pass (test_builders_cover_exactly_the_six_runtime_modules plus 6 parametrized vector checks)
  • Spot check one vector file: inputs are sufficient to implement the case without reading Python source

Related issues

Signed-off-by: kautilyaa <arunbh.y@gmail.com>
Signed-off-by: kautilyaa <arunbh.y@gmail.com>
@kautilyaa
kautilyaa requested a review from rampyg as a code owner July 13, 2026 01:19
@kautilyaa

Copy link
Copy Markdown
Collaborator Author

@rampyg Sorry for the delay here is the piece pelase check this

rampyg added 2 commits July 19, 2026 21:24
The committed vector stored intentDriftScore as 0.15, but the generator
produces the exact IEEE-754 value 0.15000000000000002 (0.05 + 0.1), so the
self-check in tests/test_runtime_vectors.py failed on a byte-for-byte
comparison. Regenerate the file so the committed vector matches a fresh
generation.

Signed-off-by: Ramprasad G <rampyg@users.noreply.github.com>
The intentDriftScore and scorer outputs were computed from drift samples
0.1/0.2/0.0/0.3, whose mean is not exactly representable in IEEE-754.
CPython 3.12 switched sum() to compensated (Neumaier) summation, so the
mean is 0.15 on 3.12 and later but 0.15000000000000002 on 3.11 and
earlier, and no single committed float passed the whole 3.9 to 3.12 CI
matrix byte for byte.

Use power-of-two drift samples (0.5/0.25/0.0/0.25) so the mean is exactly
0.25 on every runtime, and regenerate the vector.

Signed-off-by: Ramprasad G <rampyg@users.noreply.github.com>
@kautilyaa

kautilyaa commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator Author

Let me take a look in this

@rampyg
rampyg merged commit 81455bd into main Jul 24, 2026
17 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Vouch Verified Contributor ✨

Thank you @kautilyaa. This merged pull request earns a signed
Vouch Verified Contributor certificate, chained to the project root authority.

Vouch Verified Contributor

Your certificate (download and share it): https://vouch-protocol.com/c/kautilyaa/345

Add the badge to your profile or site (optional):

[![Vouch Verified Contributor](https://img.shields.io/badge/Vouch-Verified_Contributor-7C2D3A?style=for-the-badge&labelColor=2d2d2d)](https://vouch-protocol.com/c/kautilyaa/345)
Your Verifiable Credential (eddsa-jcs-2022)
{
  "@context": [
    "https://www.w3.org/ns/credentials/v2",
    "https://vouch-protocol.com/contexts/v1"
  ],
  "id": "urn:uuid:cd4870e8-aad7-42e1-b750-e1f5baa6f532",
  "type": [
    "VerifiableCredential",
    "VouchCredential"
  ],
  "issuer": "did:web:vouch-protocol.com:contributors",
  "validFrom": "2026-07-24T23:05:52Z",
  "validUntil": "2126-06-30T23:05:52Z",
  "credentialSubject": {
    "id": "did:web:vouch-protocol.com:contributors",
    "vouchVersion": "1.0",
    "intent": {
      "action": "attest",
      "target": "github:kautilyaa",
      "resource": "https://github.com/vouch-protocol/vouch/pull/345",
      "role": "verified-contributor",
      "repository": "vouch-protocol/vouch",
      "pullRequest": 345
    },
    "delegationChain": [
      {
        "issuer": "did:web:vouch-protocol.com",
        "subject": "did:web:vouch-protocol.com:contributors",
        "intent": {
          "action": "attest",
          "target": "github:kautilyaa",
          "resource": "https://github.com/vouch-protocol/vouch/pull/345",
          "role": "verified-contributor",
          "repository": "vouch-protocol/vouch",
          "pullRequest": 345
        },
        "validFrom": "2026-06-19T04:45:43Z",
        "validUntil": "2036-06-16T04:45:43Z",
        "parentProofValue": "z5g1N4udQdy5asdxnV3qFhApB5cAh28DkMqHjEUSNG6cc8hrDDsxWyVbgn1XXUFR"
      }
    ]
  },
  "proof": {
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-jcs-2022",
    "created": "2026-07-24T23:05:52Z",
    "verificationMethod": "did:web:vouch-protocol.com:contributors#key-1",
    "proofPurpose": "assertionMethod",
    "proofValue": "z3iANyQgx9L3SAmr2Ztzeu6kttyhLkDgosDxXWj75s3RnUokp8NH8McxDhRrYJn3EWqvYbhCQq3UVSkEoAmpJraft"
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a test-vector generation harness for the six runtime modules (Python source of truth)

2 participants