Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
6548cd6
leaderboard fix
Badoot Oct 18, 2026
1c87466
clean up leaderboardl
Badoot Oct 18, 2026
326a0f1
campaign live context
Badoot Oct 18, 2026
1c7d1d2
formation evidence + diagnosis grade fix + investigation ideintify fixes
Badoot Oct 18, 2026
5de851c
campaign metrics and investigation scenerio definitions
Badoot Oct 18, 2026
ec66b9e
tribunal
Badoot Oct 18, 2026
702fb60
more tribunal progress
Badoot Oct 19, 2026
f8f2e16
ratify and notary posture
Badoot Oct 19, 2026
f4d68e3
update model catalog
Badoot Oct 19, 2026
34ad622
approvals
Badoot Oct 19, 2026
32b87aa
consensus test
Badoot Oct 19, 2026
64ed3be
native defs
Badoot Oct 19, 2026
e02423c
intent pipeline fix progress
Badoot Oct 19, 2026
4c52b09
test fixtures
Badoot Oct 19, 2026
3c9b0f4
real stack runs execute in doctrine
Badoot Oct 19, 2026
e7c0c26
e2e client fix
Badoot Oct 19, 2026
fca2e92
continue code cleanup
Badoot Oct 19, 2026
258fdb2
continue continuing code cleanup
Badoot Oct 19, 2026
b270ca9
cleanup polling
Badoot Oct 19, 2026
29ac92f
eval run events, assignment audit, many test updates + code cleanup
Badoot Oct 19, 2026
e876b35
eval run events, assignment audit, many test updates + code cleanup
Badoot Oct 19, 2026
0e844c5
code cleanup progress capture
Badoot Oct 19, 2026
2557752
more code cleanup progress capture
Badoot Oct 19, 2026
162d2ae
process exit and test updates
Badoot Oct 19, 2026
22cd04a
eval loop test
Badoot Oct 19, 2026
d1fe3d5
e2e tests and doc updates
Badoot Oct 19, 2026
642c3a0
tribunal
Badoot Oct 19, 2026
a64f3ff
Native MCP Ingress & Deliberation Tool Order
Badoot Oct 19, 2026
77c26ce
tribunal defs
Badoot Oct 19, 2026
7ccbf80
eval live loop e2e test + run shell command
Badoot Oct 19, 2026
34021fe
break out rollout test
Badoot Oct 19, 2026
f1feed4
platform enrollment approver test
Badoot Oct 19, 2026
ad2732b
real stack integraiton test
Badoot Oct 19, 2026
514b4c7
shared-runtime ledger-bracket blocker
Badoot Oct 19, 2026
f8d0daf
ollama service inventory and approve slow execution tests
Badoot Oct 20, 2026
34b6eb3
cleanup proto and eval sut and tests
Badoot Oct 20, 2026
d099840
tests and fixtures
Badoot Oct 20, 2026
dba5142
campaign tests
Badoot Oct 20, 2026
2e50999
cleanup tests
Badoot Oct 20, 2026
971470e
test fixes
Badoot Oct 20, 2026
08eb8c6
lints
Badoot Oct 20, 2026
3133bb7
release v1.2.0 prep
Badoot Oct 20, 2026
70a4062
much code cleanup and new eval tests
Badoot Oct 20, 2026
c5afc4f
code review fixes
Badoot Oct 20, 2026
7f539c9
consensus binding and store
Badoot Oct 20, 2026
dbcd02c
scrubbing boundary fix
Badoot Oct 20, 2026
b3f9a38
update website
Badoot Oct 20, 2026
3b99359
update docs and cli fix
Badoot Oct 20, 2026
bd04da1
evaluation explorer fixes and compliance evidence
Badoot Oct 20, 2026
81ec941
public feed fix
Badoot Oct 20, 2026
a34a412
test harness fix
Badoot Oct 20, 2026
5566421
run shell command fix
Badoot Oct 20, 2026
b03b0f4
assigment table eval explorer fix
Badoot Oct 20, 2026
2252ed7
eval stack gate fixture
Badoot Oct 20, 2026
a23be29
integration test tampering with itself
Badoot Oct 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ Run the narrowest check that covers your changes, then the broader owning suite
| Change | Command |
|---|---|
| Go unit tests | `./ztd test unit` |
| Cross-process evaluation qualification | `./ztd test eval-loop` |
| Isolated governed release smoke | `./ztd test release-smoke` |
| Operator fleet scale qualification | `./ztd test scale` |
| Repository tools (`internal/tools/*`) | `./ztd test unit --pkg ./internal/tools/<tool>` |
| Setup and CI helper scripts | `bash -n` and `shellcheck` on the changed script |

Expand Down
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ run:
tests: true
build-tags:
- integration
- evalstack
linters:
default: none
enable:
Expand Down
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ make build
./ztd test chaos # Chaos & fault injection tests
./ztd test summary # Chaos test summary
./ztd test public-loop --candidate candidate.json --output evidence.json
./ztd test eval-loop # Cross-process eval qualification under ratify and notary
./ztd test release-smoke # Isolated governed execution and local evidence smoke
./ztd test scale # Real Operator fleet scale qualification

# Narrow Go integration tests by package or test name
./ztd test integration --pkg ./internal/cli/cmd/gw --run TestGatewayConnect
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

---

## v1.2.x

| Version | Date | Description | Notes |
|---------|------|-------------|-------|
| 1.2.0 | 2026-10-20 | Production Tribunal (`POST /api/v1/operators/intents`), CLI and outbound-Operator L3 approval (`ztd auth approve --cli`, `PasskeyVerificationContext`), K-of-N consensus bindings (`--member-app`, `--quorum`), fresh/persistent investigation campaigns with Tribunal-authored commands, sealed `agent-trace.v7` evidence and witness policies, event-driven process exit, and removal of the legacy evaluation SUT and JSON agent-tool registry. | [v1.2.0](docs/release_notes/v1.2.x/v1.2.0.md) |

## v1.1.x

| Version | Date | Description | Notes |
Expand Down
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ make build
./ztd test chaos
./ztd test summary
./ztd test public-loop --candidate candidate.json --output evidence.json
./ztd test eval-loop # Cross-process eval qualification under ratify and notary
./ztd test release-smoke # Isolated governed execution and local evidence smoke
./ztd test scale # Real Operator fleet scale qualification

# Narrow integration tests by package/name
./ztd test integration --pkg ./internal/cli/cmd/gw --run TestGatewayConnect
Expand Down
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,19 @@ test-integration:
@echo "Running Tier 2 (In-Process Integration) tests..."
@go test $(if $(TEST_P),-p=$(TEST_P),) -tags=integration $(TEST_RACE) $(TEST_COUNT) -timeout $(TEST_TIMEOUT) $(TEST_PKGS)

# Real eval stack tests (fixtures.NewEvalStack: Gateway plus outbound Data and
# Inference Operators) skip without the evalstack tag, so they never run in CI.
# Keep EVAL_STACK_TEST_TIMEOUT in sync with evalStackTestTimeout in
# internal/cli/cmd/test/test.go.
EVAL_STACK_TEST_TIMEOUT := 30m
EVAL_STACK_PKGS := ./internal/cli/cmd/eval ./internal/cli/cmd/compliance \
./internal/cli/cmd/gwremote ./internal/services/compliance/report \
./internal/services/evaluation ./internal/services/gateway ./test/fixtures
.PHONY: test-eval-stack
test-eval-stack:
@echo "Running real eval stack integration tests..."
@go test -tags='integration evalstack' $(TEST_RACE) $(TEST_COUNT) -timeout $(EVAL_STACK_TEST_TIMEOUT) $(EVAL_STACK_PKGS)

# Timing contracts run separately from race and coverage instrumentation.
.PHONY: test-enrollment-burst
test-enrollment-burst:
Expand Down Expand Up @@ -1039,7 +1052,7 @@ _ci-test:
@$(MAKE) test-coverage

# Release-shape checks GitHub Actions runs on the built binaries: the Windows
# cross-compile, then (on a Linux host, the FIPS tested OE) the FIPS self-check
# cross-compile, then (on a Linux host; the affirmed FIPS OE is Debian GNU/Linux 12) the FIPS self-check
# and fully static standard and FIPS binaries.
.PHONY: _ci-binaries
_ci-binaries:
Expand Down
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![License](https://img.shields.io/badge/license-BSL%201.1-blue.svg)](LICENSE)
[![CI](https://github.com/zerotrustdata/ztd/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/zerotrustdata/ztd/actions/workflows/build-and-test.yml)
[![Version](https://img.shields.io/badge/version-v1.1.3-green.svg)](docs/release_notes/v1.1.x/v1.1.3.md)
[![Version](https://img.shields.io/badge/version-v1.2.0-green.svg)](docs/release_notes/v1.2.x/v1.2.0.md)

**A model can ask, but it cannot directly act.**

Expand Down Expand Up @@ -33,7 +33,7 @@ Safety fine-tuning and system prompts are not security boundaries. You cannot pr

ztd splits operations into two distinct protocol roles, packaged into a single static Go binary (`ztd`):

```
```text
┌────────────────────────────────────────┐
│ AI Model / MCP Client │
└───────────────────┬────────────────────┘
Expand Down Expand Up @@ -63,7 +63,7 @@ ztd splits operations into two distinct protocol roles, packaged into a single s
The Gateway is the front door and protocol coordinator. It ingests intent via MCP (`POST /mcp` or stdio), Agent-to-Agent (A2A), HTTP dispatch, or CLI. It checks technical bedrock rules, coordinates multi-agent consensus or human passkey authorizations, and packages admitted intent into a canonical, signed `GovernanceEnvelope`. It also serves the embedded browser console and hosts an in-process Operator substrate strictly for Gateway-local operations.

### The Policy Execution Point: Operator (`ztdo`)
The Operator is a lightweight daemon that lives on the target machine owning the data. It connects **strictly outbound** over mTLS to the Gateway and listens on zero inbound network ports. It pulls transactions from its dedicated session channel, independently re-evaluates the envelope at Layer 4, mints a short-lived capability, dispatches the action locally, and records cryptographic receipts in its own local SQLite audit database and git file ledger.
The Operator is a lightweight process that runs on the target machine that owns the data. It connects **strictly outbound** over mTLS to the Gateway and listens on zero inbound network ports. It pulls transactions from its dedicated session channel, independently re-evaluates the envelope at Layer 4, mints a short-lived capability, dispatches the action locally, and records cryptographic receipts in its own local SQLite audit database and git file ledger.

Even if the Gateway is compromised, an Operator refuses to execute any envelope whose canonical transaction hash, state Merkle root, or cryptographic proofs fail its independent verification. Delivery from the Gateway does not equal authorization.

Expand Down Expand Up @@ -99,7 +99,7 @@ Universal integrity checks (L1, L4, and L5) are mandatory in every posture. Fail
Most cloud-managed agent tools ship logs back to a vendor bucket. If the vendor goes down or credentials leak, your audit trail goes with it.

ztd uses a **Local-First Audit Architecture**:
- **Authoritative local store:** Each Operator maintains its own encrypted SQLite database (`audit.db`) and a git-backed file history ledger under its runtime directory.
- **Authoritative local store:** Each Operator maintains its own encrypted SQLite audit records in `data/ztd.db` and a git-backed file history ledger under its runtime directory.
- **Projections, not truth:** The Gateway mirrors receipts for the UI and CLI, but the local host remains the single authoritative root of truth for what ran.
- **Incremental Merkle commitment:** State roots are computed incrementally across 65,536 buckets in a 16-ary tree. Proofs don't degrade into full-table scans as your audit history grows.
- **Local secret rehydration:** Sensitive credentials and tokens never travel across the wire in plaintext. They are scrubbed to reversible placeholders (`{{UEI_N}}`) and rehydrated by the L5 Actuator inside the target host's memory immediately before execution.
Expand All @@ -108,7 +108,7 @@ ztd uses a **Local-First Audit Architecture**:

## Quickstart

ztd runs natively as a static binary on Linux, macOS, and Windows. No Docker daemon, no background hypervisor, no sudo required.
ztd runs natively as a static binary on Linux, macOS, and Windows. No Docker daemon, no background hypervisor, and no sudo for the one-line install.

### 1. One-line install

Expand All @@ -122,7 +122,7 @@ On **Windows** (PowerShell 7):
irm https://zerotrustdata.io/start.ps1 | iex
```

This downloads the checksum-verified binary to `~/ztd`, starts a local Gateway on `https://localhost:8443`, creates a CLI identity, and runs your first governed action through an embedded Operator.
This installs the checksum-verified binary into `~/ztd`, starts a local Gateway on `https://localhost:8443`, creates a CLI identity, and runs your first governed action through an embedded Operator.

### 2. Build from source

Expand Down Expand Up @@ -168,8 +168,9 @@ Once the Gateway is running, here is how you drive it:
# Run a governed command across all active Operators
./ztd operator run --all-active --cmd "uptime"

# Inspect the cryptographic audit receipts for a session
./ztd gw data audit list --operator-session-id <session_id>
# List the audit events for one OperatorSession
# (set OPERATOR_SESSION_ID to an ID printed by `./ztd operator list`)
./ztd gw data audit list --operator-session-id "$OPERATOR_SESSION_ID"

# Shut down the stack (preserves all local audit ledgers in .ztd/)
make down
Expand All @@ -192,12 +193,12 @@ Mutations proposed by Claude flow through the Gateway's L1–L5 pipeline. If Cla

We test ztd the way production infrastructure breaks.

In October 2026, we drove **2,000 native Operator processes** against a single Gateway instance on a modest 12-core Linux machine:
In October 2026, we drove **2,000 native Operator processes** against a single Gateway instance on a 12-CPU, 32 GiB Linux machine:

- **2,000 Operators enrolled in 54.82 seconds.**
- **Governed command fan-out to 2,001 targets completed in 3.89 seconds with 0 failures.**
- Re-tested after bouncing the Gateway: all 2,000 resumed cleanly over mTLS without session rotation.
- Gateway memory remained flat under continuous 30-second heartbeats over 6,000 concurrent TLS connections.
- A five-minute idle soak kept all 2,000 Operators active with none stale under 30-second heartbeats.

For the raw benchmarks, profiles, and the SQLite concurrency lessons learned during the test, read [From 936 to 2,000 Operators on one Gateway](https://zerotrustdata.io/build-in-public/enrolling-two-thousand-operators/).

Expand All @@ -212,13 +213,12 @@ internal/
services/
gateway/ PDP control plane, HTTP APIs, PKI CA, session routing
governance/ The five-layer pipeline (L1 Doctrine, L2 Consensus, L3 Notary, L4 Warden, L5 Actuator)
consensus/ Ed25519 quorum deliberation engine
fs/ RuntimeFileService (strictly isolated .ztd/ filesystem access)
vault/ AES-256-GCM encrypted local secret & key storage
mcp/ Native MCP server and tool registry
protocol/ Canonical Protobuf schemas (proto/ztd/) and generated Go/TS bindings
console/ React + TypeScript (Vite) web console (embedded into the Go binary)
eval/ Model evaluation fixtures, security gauntlets, and test datasets
eval/ Model evaluation fixtures, model catalogs, and rollout intake data
docs/ Complete platform architecture, developer invariants, and user guides
```

Expand All @@ -231,8 +231,8 @@ Always run test suites through `./ztd test <suite>` or the root `Makefile` (they
```bash
./ztd test unit # Fast, in-memory, parallel-safe unit tests
./ztd test integration # Real SQLite/PKI/mTLS integration tests (-race enabled)
./ztd test lint # golangci-lint, vulnerability audit, and doctrine verification
./ztd test chaos # Fault injection and network disruption tests
./ztd test lint # Go lint; make lint adds vulnerability and doctrine checks
./ztd test chaos # In-process synthetic governance fault injection

make console-test # Vitest suite for the browser console
make proto-generate # Regenerate Go and TypeScript protobuf bindings
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.1.3
v1.2.0
4 changes: 2 additions & 2 deletions console/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions console/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "@ztd/console",
"private": true,
"version": "1.1.3",
"description": "ztd Console — the Gateway-embedded browser frontend: passkey auth, approvals, Operator inventory and binding, cases, investigations, and chat.",
"version": "1.2.0",
"description": "ztd Console — the Gateway-embedded browser frontend: passkey authentication, approvals, Operator inventory, binding, deploy, and stop, and the native API reference.",
"license": "BUSL-1.1",
"type": "module",
"scripts": {
Expand Down
37 changes: 11 additions & 26 deletions console/src/generated/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,10 @@ export const EventType = Object.freeze({
OPERATOR_SHUTDOWN_REQUESTED: 'ztd.v1.operator.shutdown.requested',
OPERATOR_SLOT_INITIALIZATION_FAILED: 'ztd.v1.operator.slot.initialization.failed',
OPERATOR_STATUS_UPDATED_ACTIVE: 'ztd.v1.operator.status.updated.active',
OPERATOR_STATUS_UPDATED_AVAILABLE: 'ztd.v1.operator.status.updated.available',
OPERATOR_STATUS_UPDATED_BOUND: 'ztd.v1.operator.status.updated.bound',
OPERATOR_STATUS_UPDATED_OFFLINE: 'ztd.v1.operator.status.updated.offline',
OPERATOR_STATUS_UPDATED_STALE: 'ztd.v1.operator.status.updated.stale',
OPERATOR_STATUS_UPDATED_STOPPED: 'ztd.v1.operator.status.updated.stopped',
OPERATOR_STATUS_UPDATED_TERMINATED: 'ztd.v1.operator.status.updated.terminated',
OPERATOR_STATUS_UPDATED_UNAVAILABLE: 'ztd.v1.operator.status.updated.unavailable',
OPERATOR_TERMINAL_APPROVAL_DENIED: 'ztd.v1.operator.terminal.approval.denied',
OPERATOR_TERMINAL_AUTH_STATE_CHANGED: 'ztd.v1.operator.terminal.auth.state.changed',
OPERATOR_UNBOUND: 'ztd.v1.operator.unbound',
Expand Down Expand Up @@ -255,7 +252,7 @@ export const EventRegistry = Object.freeze({
AI_EVAL_HEARTBEAT: Object.freeze({
kind: 'fact',
producers: ['gateway'],
persistence: 'gateway.operator_docs',
persistence: 'gateway.sse_store',
}),
AI_EVAL_METRIC_AVAILABLE: Object.freeze({
kind: 'outcome',
Expand Down Expand Up @@ -362,7 +359,7 @@ export const EventRegistry = Object.freeze({
producers: ['cli', 'mcp'],
persistence: 'ephemeral',
actionType: 'A2A_CALL',
payload: 'ztd.operator.v1.A2ACallRequested',
payload: 'ztd.operator.v1.A2aCallRequested',
}),
OPERATOR_AUDIT_AI_RECORD_REQUESTED: Object.freeze({
kind: 'request',
Expand Down Expand Up @@ -1281,43 +1278,31 @@ export const EventRegistry = Object.freeze({
kind: 'fact',
transport: ['sse'],
producers: ['gateway'],
persistence: 'gateway.operator_docs',
}),
OPERATOR_STATUS_UPDATED_AVAILABLE: Object.freeze({
kind: 'fact',
producers: ['gateway'],
persistence: 'gateway.operator_docs',
}),
OPERATOR_STATUS_UPDATED_BOUND: Object.freeze({
kind: 'fact',
transport: ['sse'],
producers: ['gateway'],
persistence: 'gateway.operator_docs',
persistence: 'gateway.sse_store',
}),
OPERATOR_STATUS_UPDATED_OFFLINE: Object.freeze({
kind: 'fact',
transport: ['sse'],
producers: ['gateway'],
persistence: 'gateway.operator_docs',
persistence: 'gateway.sse_store',
}),
OPERATOR_STATUS_UPDATED_STALE: Object.freeze({
kind: 'fact',
transport: ['sse'],
producers: ['gateway'],
persistence: 'gateway.operator_docs',
persistence: 'gateway.sse_store',
}),
OPERATOR_STATUS_UPDATED_STOPPED: Object.freeze({
kind: 'fact',
transport: ['sse'],
producers: ['gateway'],
persistence: 'gateway.operator_docs',
persistence: 'gateway.sse_store',
}),
OPERATOR_STATUS_UPDATED_TERMINATED: Object.freeze({
kind: 'fact',
transport: ['sse'],
producers: ['gateway'],
persistence: 'gateway.operator_docs',
}),
OPERATOR_STATUS_UPDATED_UNAVAILABLE: Object.freeze({
kind: 'fact',
producers: ['gateway'],
persistence: 'gateway.operator_docs',
persistence: 'gateway.sse_store',
}),
OPERATOR_TERMINAL_APPROVAL_DENIED: Object.freeze({
kind: 'outcome',
Expand Down
8 changes: 5 additions & 3 deletions console/src/lib/paths.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright (c) 2026 Lateralus Labs, LLC.
// Licensed under the Business Source License 1.1 — see LICENSE for details.

// Browser-reachable Gateway routes. Values mirror internal/constants/api_paths.go;
// every route here is classified RouteAuthNone, RouteAuthWebSession, or
// RouteAuthDual in internal/services/gateway/gateway_auth.go.
// Browser-reachable Gateway routes. The canonical registry is
// protocol/constants/api_paths.json; values here mirror it, and the Go mirror
// lives in internal/constants/api_paths.go. Every route here is classified
// RouteAuthNone, RouteAuthWebSession, or RouteAuthDual in
// internal/services/gateway/gateway_auth.go.

const enc = encodeURIComponent;

Expand Down
Loading
Loading