Releases: amitpatole/verel
v0.40.0 — remove the metrics dashboard from the package (not a Verel feature)
Reverts the v0.39.0 decision to ship the metrics dashboard inside verel. The dashboard is a maintainer tool — it tracks the author's own projects' adoption and reads GitHub traffic data (which needs push access via local gh auth), so it has no use for anyone who installs Verel.
- Removed
verel.dashboardand theverel-dashboardconsole script from the package. - The dashboard lives under
tools/metrics_dashboard.pyagain (not packaged); it keeps the fail-closed auth+TLS hardening and may be extracted into its own project later. - No API a Verel user relied on is affected.
v0.39.0 is yanked on PyPI/TestPyPI — install verel>=0.40.0. (Package versions are immutable; yank, not delete, is the correct supersede.)
🤖 Generated with Claude Code
v0.39.0 — ship the metrics dashboard, hardened (auth + TLS)
The live metrics dashboard graduates from a tools/ script (which bound 0.0.0.0 unauthenticated) to a first-class shipped component, verel.dashboard, run via the verel-dashboard console script. It reuses the same fail-closed transport hardening as the brain/lease/registry:
- Loopback (
127.0.0.1) default is zero-config plain http, no token. A routable bind (incl.0.0.0.0) requires both an auth token AND TLS or it refuses to start — the GitHub-traffic data it shows is account-scoped, so it's never served to the open network unauthenticated (verified to bind no socket on refusal). - Auth is a constant-time bearer token (
Authorization: Bearer …) or?token=…for a browser; 401 before any data is served. TLS handshake off the accept loop; global + per-IP connection caps; slowloris timeout — all from the auditedverel.transport. - Config is operator env only:
VEREL_DASHBOARD_HOST/VEREL_DASHBOARD_TOKEN/VEREL_DASHBOARD_CERT/VEREL_DASHBOARD_KEY.tools/metrics_dashboard.pystays a thin back-compat shim.
A focused red-team (auth bypass / token leakage / SSRF / DoS / fail-closed) came back clean; the dashboard passes the MEDIUM+ security gate.
Operational note: a systemd unit running the dashboard now needs VEREL_DASHBOARD_HOST + VEREL_DASHBOARD_TOKEN + VEREL_DASHBOARD_CERT/KEY to serve on the LAN; otherwise it binds loopback only.
🤖 Generated with Claude Code
v0.38.0 — the security gate, fixed and stricter (dogfooding)
Dogfooding Verel's own pre-merge gate on Verel found the security grader was broken — it contradicted its own "HIGH/CRITICAL gate" docstring: it ran bandit -r . over the whole tree and failed on any finding, so it flagged every test assert (B101) and all of .venv, and could never pass on a normal project (and bandit wasn't even a declared dev dependency, so the gate failed closed as "security grader absent").
- bandit is now a
[dev]dependency — the pre-mergesecuritygrader is reproducible (an absent required grader is a red gate, not a silent pass). - The grader is fixed into a real gate: scans the shipped package (excludes
tests/,tools/,scripts/,.venv, build dirs) and gates on MEDIUM+ severity at MEDIUM+ confidence — real SQL injection / weak crypto / command injection block a merge; LOW stays advisory. - Verified false-positives resolved at the source so the gate is green and meaningful: a real scheme guard on the LLM/embedding clients (refuse to send the bearer key to a non-
http(s)base_url), and justified# nosecon the constant-column SQL, the in-sandbox--tmpfsmount, and the restricted-__builtins__skillexec. - Verel's own pre-merge gate now passes at MEDIUM+ with a publicly-verifiable ed25519 receipt (
graders_checked=4) — the wedge, dogfooded end to end.
🤖 Generated with Claude Code
v0.37.0 — mTLS, certificate pinning, per-IP fairness
Closes the three code-closeable transport residuals named in v0.36.0 (§15.4), uniformly across the brain, lease authority, and registry via verel.transport.
- mTLS — servers take
client_ca=(require a client cert signed by it,CERT_REQUIRED): transport-layer client authentication beneath the bearer/signature layers, so a stolen bearer token alone no longer connects. Clients presentclient_cert=/client_key=. - Certificate pinning — clients take
pin_sha256=(transport.cert_sha256()computes it): reject any server leaf cert outside the pinned set even if a trusted CA signed it (defeats a mis-issued/compromised CA). Validated 64-hex at build time; additive to CA + hostname verification. - Per-source-IP fairness — servers take
max_per_ip=bounding how many of the globalmax_connectionsslots one source IP may hold (off by default; for routable/exposed binds). - MCP wiring —
VEREL_BRAIN_CLIENT_CERT/VEREL_BRAIN_CLIENT_KEY/VEREL_BRAIN_PIN(operator env only).
Honest residuals (stay operational/inherent, §15.5): endpoint trust is closed at the application layer by verel_verify on the ed25519 receipt (a malicious configured server's trust/author claims); certificate issuance/rotation is operator-run (Verel is not a CA); per-IP is a concurrency bound, not a rate limiter; and the stdlib/OS/kernel/unknown-unknowns no audit removes.
Hardened through a 3-round adversarial red-team (one LOW pin-validation footgun fixed; the last round came back empty). 35 tests in tests/test_brain_tls.py. See docs/SUBSTRATE_DESIGN.md §15.5.
🤖 Generated with Claude Code
v0.36.0 — TLS for routable brain/lease/registry binds
Roadmap item 3. Transport confidentiality on any non-loopback bind — fail closed, loopback stays zero-config. One shared verel.transport module hardens all three HTTP services (the brain, the lease authority, the registry).
- Server TLS —
MemoryServer/ControlPlaneServer/RegistryServertakecertfile=/keyfile=/ssl_context=;urlreportshttps://; TLS 1.2+ floor. - Bind policy (fail closed) — a non-loopback bind now requires both an
auth_tokenand TLS, else the server refuses to start.host=""is treated as routable (it's the0.0.0.0wildcard). Loopback stays plain-HTTP, zero-config. - Client cleartext-secret guard — clients take
cafile=/ssl_context=(verify internal/pinned CAs) and refuse to attach a bearer/cluster token to a non-loopbackhttp://URL (re-checked per request on the live token);insecure=Trueopts out for a TLS-terminating proxy. - DoS-resistant — the TLS handshake runs in the per-connection worker thread (not the accept loop), a
max_connectionssemaphore (default 128, tunable) bounds concurrency, the client opener ignores ambientHTTP_PROXY/ALL_PROXY, and token leaks across HTTP redirects are blocked.
Hardened through a 5-round adversarial red-team — closed a wildcard-host bind bypass, an HTTP-redirect token leak, a post-init guard bypass, a TLS-handshake accept-loop DoS, a proxy-env token leak, and an unbounded-connection DoS; the last two rounds came back empty. 25 tests in tests/test_brain_tls.py. See docs/SUBSTRATE_DESIGN.md §15.4.
🤖 Generated with Claude Code
v0.35.0 — MCP recall/remember over a remote authenticated brain
Roadmap item 2. The MCP tools can now read from and write to a hosted, multi-principal brain, so a fleet on different machines draws from ONE authenticated memory instead of per-install local stores.
- With
VEREL_BRAIN_URLset,verel_recallreads the remoteMemoryServerandverel_rememberauthors a signed write as an authenticated principal (VEREL_PRINCIPAL_SEED, a 32-byte ed25519 seed) — the server enforces every guard (reserved-key, non-FACT backstop, cross-principal protection) and the cross-principalverifiedtier (fact-boundevidence). OptionalVEREL_BRAIN_TOKEN(bearer) andVEREL_CLUSTER_TOKEN(replication) are threaded through. - The local per-install brain stays the zero-config default — no behaviour change without the env.
- Trust model (honest): the remote
trust/author/reverifiedreflect the configured server's claim (operator-trusted, same tier as a DB URL). An agent wanting integrity independent of the server callsverel_verifyon the underlying ed25519 receipt — that survives a malicious peer. - Fails closed, never leaks: missing/invalid seed → can read, can't author; an unenrolled principal is rejected; a bad bearer surfaces as
HTTP 401; an unreachable brain as a clean error — neither echoes the token or seed. Config is operator-env only.
Shipped through a 3-round adversarial red-team (every round clean). See docs/SUBSTRATE_DESIGN.md §15.2.
🤖 Generated with Claude Code
v0.34.0 — cross-principal verified tier (fact-bound attestation)
Roadmap item 1 of 3. Closes the last brain trust residual: a peer's belief can now earn the verified tier (not just candidate) — but only via a fact-bound attestation, so trust still never travels by say-so.
Highlights
verdict.fact_commitment(subject,predicate,text)— a 256-bit commitment to a claim's content;attest_fact()mints a portable signed GateReceipt whose signedsubjectIS that commitment;verify_fact_attestation()accepts it iff it verifies, attestsverdict=PASS, AND is bound to THIS exact claim (an unrelated valid receipt can't launder a different fact).authenticated_remember(evidence=…)earns the cross-principalverifiedtier only with a publicly-verifiable ed25519 attestation (a peer verifies without the producer's secret);RemoteMemory.remember_signed(evidence=…)threads it; the MCPverel_rememberalso promotes on a fact-bound attestation (local = single-principal, hmac accepted).- Reserved-key + non-FACT guards run before promotion; local and remote write paths now share one
is_reserved_keysource of truth.
Security
Shipped through a 4-round adversarial red-team (the 4th came back clean): 256-bit commitment, local non-FACT backstop, local reserved-key guard, and proven local↔remote guard parity. 446-test suite; ruff + mypy clean. pip install "verel[attest]".
v0.32.0 — the authenticated multi-principal brain
Turns the deferred multi-principal items from the 0.31.0 brain audit into real controls, so a shared remote brain can be trusted across principals — not just one local operator. Closes the deferred Findings 3 & 4.
Highlights
- Authenticated principals. A principal is an ed25519 keypair whose
key_idIS its identity (verel.memory.Principal). A write is signed; the server derivesauthorfrom the verified key — so you can't author as someone else, andAuthorTrustcan't be forged/inflated/impersonated (Finding 3). - Trust-weighted recall.
rank()folds in the trust tier — a verified memory edges out an equally-relevant candidate, so a poisoned candidate can't outrank a verified fact (Finding 4). - Hosted wiring.
MemoryServer(trusted_principals=…)+/write_signed(RemoteMemory.remember_signed); the verbatim replication channel (/apply,/replicate) requires a separate cluster credential (X-Cluster-Token), not the client bearer.
Security — 7-round adversarial red-team (7th clean)
Secure-by-default signed-writes mode (a bearer connects + reads, but only signed writes author; raw /write + all trust-mutation endpoints refused); a structural backstop so a client FACT can never supersede a server-managed non-FACT record (failure ledger, skills, induced rules/schemas) + a reserved-predicate/scope denylist for the one FACT-kind control record; verified beliefs can't be overwritten or reattributed by a peer; graduate() stamps a collective author so a pre-empted key can't forge authorship of team knowledge.
Residuals (honest): cross-principal verified tier still candidate-only (deferred); no TLS on a routable bind (non-loopback refuses without a token); the FACT-kind reserved-predicate denylist is a per-name maintenance obligation.
413-test suite; ruff + mypy clean. pip install "verel[attest]" for the principal layer.
v0.31.0 — the shared verified brain
Completes the substrate's four hero verbs (gate, sight, recall/remember, verify): any agent over MCP can now read and write a shared verified brain — and trust does not travel.
Highlights
verel_recall(query, scope, kind, k)— reads via the scope lattice, resolving DOWN (self < team < org < global; most specific wins) and surfacing trust/confidence/support/provenance/fingerprint.verel_remember(fact, scope, evidence, author)— writes a CANDIDATE. The caller's self-asserted trust is ignored; a verifiableevidencereceipt records attested grounding but does NOT auto-promote (the receipt attests a run, not the fact). A forged receipt can't launder trust; a VERIFIED belief is protected from silent overwrite.- One persistent brain per server (
VEREL_MEMORY_STOREor~/.config/verel/brain.db), fixed and not agent-controllable; bounded inputs; parameterized SQL.
Security
Audit → 3-round adversarial red-team: store/input/DoS clean; the trust hard-guarantee (no verified without a genuine runner-signed receipt) holds; two soft-trust paths fixed. The unauthenticated-author and trust-blind-ranking items are documented as the deferred multi-principal remote-brain auth layer — acceptable under the local single-principal model.
390-test suite; ruff + mypy clean. pip install verel
v0.30.0 — the verification substrate
Verel becomes a verification substrate any agent can call over MCP — a conscience, a pair of eyes, and a receipt a different party can check. Three substrate slices, each shipped through the full audit → 3-round adversarial red-team cadence.
Highlights
- Publicly-verifiable receipts (ed25519). A second party verifies a receipt offline with only the producer's public key — no shared secret. Trust is pinning, never TOFU: a valid signature isn't enough; the
key_idmust be trusted. Newverify_receipt()+verel verify <receipt.json>. Optional extraverel[attest]; absent → ed25519 fails closed. gateover MCP (the conscience).verel_gateruns the real graders on a repo and returns the attested verdict + a signed, publicly-verifiable gate-level receipt. An agent can no longer self-declare "done"; "an agent cannot fake green" becomes checkable. Newverel_verifyMCP verb.sightover MCP (the eyes).verel_sightrenders a URL through AgentVision and returns an attested percept — observations with pixel bboxes, animage_ref, intent conformance, and a receipt bound to the screenshot bytes. SSRF-safe by default;allow_localis an explicit opt-in.
Security
Shipped through audit → ≥3 adversarial red-team rounds per slice. Hardening (all regression-pinned): injective length-prefixed signing payloads across every signer (closed a real delimiter-injection on receipts and the toolsmith/registry signers), strict base64, ASCII-only key_id, cross-type domain separation, the gate envelope signs the verdict + ceiling_clamped + a percept subject so no trust-implying field is unsigned, and MCP host-boundary crash safety.
378-test suite; ruff + mypy clean.
pip install verel · pip install "verel[attest]" for public verifiability