Deep-dive treatment of the local-first boundary, data flow, signing, release verification, and subprocessors. For the concise view, see Trust and security.
Boundary answer in one table: what each surface reads, what it writes, what can leave the machine, and what stays local. Every row traces back to the sections below.
Repo files, ledger, reports, signing keys, and verification history
Local sync (dir://)
Local ledger transactions and verification history (when sync is enabled)
Signed, encrypted bundles to a local directory path you control
None — no cloud transport is involved
Bundles and encryption keys remain on the local filesystem; transport is a directory path
Opt-in telemetry (usage-metrics build)
Local aggregate top-level command-name counts, enabled features, and an anonymous UUID generated when enabled
A single JSON payload to the configured Supabase ingest endpoint
Aggregate command counts, platform/version metadata, enabled features, and an anonymous ID — only after explicit enable. The connection IP is transiently visible to the ingestion endpoint for rate limiting but is scrubbed and never stored; stored telemetry contains no IP or PII. Ingest rejects unauthenticated (when required) and over-quota traffic; clients send a non-secret bar-raising token (X-Ledgerful-Telemetry-Token); telemetry stays best-effort. Fail-closed global quotas and platform spend caps are the real controls — the embedded CLI token is not strong authentication.
Configured cloud model (Gemini / Ollama Cloud / OpenRouter)
Local sanitized, truncated impact and retrieved codebase context (only when a provider is configured and selected)
Nothing local beyond normal ledger entries
Sanitized, truncated context to the selected provider; API credentials may be read from the process environment or repository-local .env file
Raw source files beyond the sanitized retrieval window; secrets unrelated to the configured model provider
Local dashboard (loopback)
Local daemon API at http://127.0.0.1:52001 with an ephemeral session token
No persistent writes outside the local ledger / report paths
None — bind address is 127.0.0.1 only
Dashboard session, ephemeral token (in-memory, never persisted to disk), and all served data
Detailed reads / writes are listed in the “what stays on your machine” section below; the known outbound paths and their activation conditions are listed in the data-flow and release-verification sections.
Optional local context bridge (off by default, advanced/unstable). Ledgerful can expose an INTERNAL/UNSTABLE local interface — inactive unless you explicitly enable it — that passes analysis context (file paths, symbols, verify outcomes, and exported ledger and impact records) to a separate local process you run. Transport is local IPC only (a named pipe or local subprocess); Ledgerful opens no network connection for it, and it is not a supported public API. It is listed for completeness of the data-flow boundary, not as a product surface we promote.
Data flow
Five modes describe how data moves in Ledgerful. The default mode uploads nothing. Source code is never uploaded by default.
Local default
Available · Runs locally
Ledgerful reads git state and project structure locally and writes evidence to .ledgerful/. Scan, ledger, audit, verify, dashboard, and export stay on the machine by default. Local sync is separate and requires a sync-enabled build compiled with --features sync.
Local sync (dir://)
Available · Runs locally
When sync is enabled with a dir:// transport, Ledgerful writes signed, encrypted bundles to a local directory path you control. No cloud transport is involved. Bundles are signed and encrypted before leaving the engine.
Telemetry (opt-in)
Available · Runs locally
Usage metrics are excluded from the default build. A build with usage-metrics must still be enabled with ledgerful usage enable before aggregate command counts, platform/version metadata, enabled features, and an anonymous ID are sent. Ingest rejects unauthenticated (when required) and over-quota traffic; clients send a non-secret bar-raising token (X-Ledgerful-Telemetry-Token); telemetry stays best-effort. Fail-closed global quotas and platform spend caps are the real controls — the embedded CLI token is not strong authentication.
Configured cloud model
Available · Runs locally
The ask workflow can send sanitized, truncated impact and retrieved codebase context to Gemini, Ollama Cloud, or OpenRouter when a user configures and selects one of those providers. Separately, ledgerful index --fast can send code chunks to a configured Gemini model for semantic extraction instead of the local model. Neither path is active in the default local workflow.
Hosted mode (planned)
Planned · Hosted
A future hosted control plane will allow teams to share signed summaries and metadata across machines. Source code will never be uploaded by default and will require explicit consent. This mode requires a future hosted infrastructure that does not yet exist.
Local inputs
Your machine
Git repository
.ledgerful/ project directory
~/.ledgerful/keys/ signing key directory
config.toml
▼
reads · writes
Ledgerful engine
Local surfaces
CLI · daemon · dashboard
audit · verify · export
sync only in a --features sync build
▼
local outputs
Local outputs
Sync dir (dir://)
SOC 2-style evidence ZIP (local)
Optional outbound paths
ask → configured cloud model (sanitized, truncated context only)
index --fast → Gemini (code chunks for semantic extraction)
opt-in telemetry → Supabase (aggregate metrics)
None of these paths is active in the default local workflow.
Every arrow inside the Your machine box is local. Three configured paths can cross the boundary: opt-in aggregate telemetry to Supabase, sanitized, truncated context from the ask workflow to a selected cloud model, and code chunks from index --fast to a configured Gemini model for semantic extraction. None of these paths is active in the default local workflow.
Update checks
None. The CLI does not check for updates automatically. No outbound HTTP requests are made to GitHub or any external server for version checking.
Crash reporting
None. Ledgerful does not integrate a crash reporter. Panics are handled by Rust's default behavior (stderr output) and are not transmitted anywhere. No crash data is ever sent to a remote service.
Configured cloud models
Configured only. Two distinct workflows can send data to a configured cloud model. The ask command sends sanitized, truncated impact and retrieved codebase context to Gemini, Ollama Cloud, or OpenRouter when that provider is configured and selected. The index --fast flag sends code chunks to a configured Gemini model for semantic extraction instead of the local model. API credentials may be read from the process environment or repository-local .env file. Neither path is active in the default local workflow.
Three-surface boundary
Ledgerful is shipped as three local surfaces — CLI, daemon, and dashboard — plus an optional configured cloud model. The dashboard bind address is 127.0.0.1:52001; CORS is restricted to loopback origins; the session token is 256-bit random, validated in constant time, and never persisted to disk.
CLI
The ledgerful binary. It runs commands, reads project state, writes ledger entries and reports, and can launch the local dashboard. No network is required for scan, audit, ledger, verify, or the local evidence export.
Daemon
The loopback HTTP server backing the dashboard. Bound to 127.0.0.1:52001. The launch URL hands the dashboard an ephemeral ?token=<hex> once; the dashboard strips it, keeps it in memory, and authenticates API requests with Authorization: Bearer <hex>. The daemon validates it constant-time and never persists it to disk.
Dashboard
A static SPA that opens against the daemon URL with the ephemeral token. Lives in your browser. It does not call any remote service; the bind address is loopback only.
Dashboard and token model
The local dashboard is loopback-only. It is not accessible from the internet or from other machines on your network.
Step 1
Start daemon
ledgerful web start
▼
Step 2
Generate token
256-bit in memory
▼
Step 3
Open URL
127.0.0.1:52001/?token=…
▼
Step 4
Capture + strip
token held in memory
▼
Step 5
Bearer request
constant-time validate
Loopback only — bound to 127.0.0.1:52001, not reachable from your network or the internet. The launch URL is stripped; the in-memory Bearer token is never persisted to disk.
Five steps from ledgerful web start to an active loopback dashboard. The URL is stripped after the token is captured in dashboard memory; Bearer requests are validated constant-time and the token is never persisted to disk.
Bind address: The daemon binds exclusively to http://127.0.0.1:52001. CORS is restricted to localhost and 127.0.0.1 on any port — cross-origin requests from remote or hosted domains are rejected.
Token authentication: Every dashboard session starts from an ephemeral ?token=<hex> launch URL. The dashboard captures the token in memory, strips it from the address bar, and sends subsequent requests with Authorization: Bearer <hex>. The daemon validates tokens using constant-time comparison to prevent timing attacks.
Token entropy: Tokens are 256-bit cryptographically random values (32 bytes via rand::thread_rng().fill_bytes, seeded from OS entropy), hex-encoded to 64 characters. Entropy is sufficient to make loopback brute-force attacks infeasible.
Token safety rules: Tokens are per-session and never persisted to disk by the daemon. Tokens must not appear in browser logs, screenshot-based bug reports, or documentation examples. If a token is accidentally exposed, restart the daemon to generate a new one.
Signing and key management
Ledgerful uses Ed25519 signing to provide tamper-evident ledger provenance and offline-verifiable SOC 2-style evidence.
Key generation: An Ed25519 key pair is generated on first use via OsRng (OS-level entropy). The signing key and verifying key are stored as hex-encoded files at ~/.ledgerful/keys/private.key and ~/.ledgerful/keys/public.pem (Windows: %USERPROFILE%\.ledgerful\keys\). No remote key management is required by default.
Key storage at rest: Private keys are stored as plain hex files protected only by filesystem permissions. A local machine compromise — such as malware or a stolen laptop without Full Disk Encryption — could allow an attacker to extract the private key and forge signed ledger entries. Full Disk Encryption (FDE) is the primary recommended mitigation for local key security. Hardware-backed key storage (TPM, Secure Enclave) and hosted KMS are planned for enterprise features for a future control plane.
Sync bundles: When local sync is enabled, Ledgerful signs and encrypts bundles before writing them to the sync directory. Bundle contents are not readable without the encryption key.
SOC 2-style export signing: Each SOC 2-style evidence ZIP includes manifest.sig (64-byte Ed25519 signature over manifest.json) and manifest.pub (32-byte verifying key). This allows offline tamper verification without trusting a remote key server.
Key rotation and enterprise features: Key rotation is local and manual. Hardware-backed key storage, hosted KMS, and device trust management are planned for enterprise and require a future control plane. SSO / SAML / OIDC, SCIM, and RBAC are also planned for enterprise — none of these are implemented in the local daemon.
Release verification
v0.1.9 with SHA-256 checksums, SBOM, and cosign signing. The release workflow requires SHA-256 companion files for every binary archive.
Current baseline: The v0.1.9 release is publicly available on GitHub with binary archives for 4 platforms, SHA-256 checksums for each, CycloneDX SBOM (engine + MCP), cosign keyless signing (Sigstore Fulcio), SLSA build-provenance attestation, SBOM attestation, and cargo-auditable dependency embedding. Homebrew tap and Scoop bucket also resolve to 0.1.9. The steps below describe the verification process for the published release.
Download the binary archive and its companion .sha256 checksum file from the GitHub Release page for your platform (Linux, macOS, or Windows).
Run sha256sum -c ledgerful-<platform>.tar.gz.sha256 on Linux/macOS. On Windows, hash ledgerful-x86_64-pc-windows-msvc.zip with Get-FileHash -Algorithm SHA256 and compare it with the companion .zip.sha256 file.
A successful verification prints filename: OK for each file. Any FAILED output means the download is corrupt or tampered — do not use the binary.
Note: download URLs are live on the v0.1.9 GitHub Release. Windows Authenticode signing and macOS Developer ID / Gatekeeper notarization are not yet implemented — binaries may trigger OS security prompts on first launch. OS code signing is a planned enhancement. Supply chain attestation (SBOM, cosign, SLSA) shipped since v0.1.8 and continues in v0.1.9 — see the supply chain section below.
OS code signing status: Windows Authenticode signing and macOS Developer ID / Gatekeeper notarization are not yet implemented. Binaries may trigger OS security prompts on first launch. Code signing for both platforms is a separate planned enhancement. Supply chain attestation (SBOM, cosign signing, SLSA provenance) shipped since v0.1.8 and continue in v0.1.9 — see the next section.
Supply chain attestation
SBOM, cosign signing, SLSA provenance shipped with v0.1.8+ (current: v0.1.9). This is Ledgerful's own release-integrity posture — not a product feature that generates SBOMs or attestations for your repository.
Shipped since v0.1.8 (current v0.1.9): Supply-chain attestation has shipped since v0.1.8 and continues in the current v0.1.9 release: CycloneDX SBOM (engine + MCP), cosign keyless signing (Sigstore Fulcio, GitHub OIDC), SLSA build-provenance attestation (actions/attest), SBOM attestation (actions/attest-sbom), and cargo-auditable dependency embedding. Two honest SBOM gaps: the cozo git-dependency has no registry coordinate (not automatically CVE-matched), and bundled native SQLite is not enumerated as its own component. The verification commands below are actionable for the v0.1.9 release. The gh attestation verify commands require the repository to be public (it is) or on GitHub Enterprise Cloud.
What each release carries
Component
Tool
What it proves
CycloneDX SBOM
cargo cyclonedx --all-features
A per-release Software Bill of Materials generated from the Cargo lockfile. Covers the engine (all features) and the MCP npm package. Attached as a release asset alongside the binaries.
cosign keyless signing
cosign sign-blob (Sigstore Fulcio, GitHub OIDC)
Release archives and the SBOM are signed with cosign keyless signing using the GitHub Actions OIDC identity. No long-lived signing keys to manage. Verifiers check the signature against the workflow identity and Fulcio certificate.
SLSA build provenance
actions/attest (GitHub native)
Each binary carries a SLSA build-provenance attestation emitted inside the matrix build job that compiled it. Provenance binds the artifact to the runner, source commit, and build parameters that produced it. Verifiable with gh attestation verify.
SBOM attestation
actions/attest-sbom
The SBOM file carries a signed attestation bound to the built artifact digest — the distinct claim that this is the bill of materials for that binary. Distinct from build provenance, which proves where it was built.
Embedded dependency list
cargo auditable
Releases are built with cargo auditable, which embeds the dependency graph in the binary as a custom linker section. Verifiable offline with cargo audit bin or syft without needing the SBOM file.
Confirms the SBOM is the bill of materials for this release. Requires the repository to be public or on GitHub Enterprise Cloud.
Inspect embedded dependencies (offline)
cargo audit bin ledgerful
# or:
syft ledgerful
Reads the dependency list embedded in the binary by cargo auditable. Works offline without the SBOM file. Available on each target where cargo auditable succeeded.
Honest gaps
cozo git-dependency is not CVE-matched: The cozo-redux crate is a git dependency pinned by commit, not a registry package. Downstream vulnerability scanners keyed on registry coordinates will not automatically match it against published advisories. Upstream cozo advisories are tracked manually. Publishing the fork to crates.io would give it a registry coordinate but does not change this gap for the current git-pinned rev.
Bundled native SQLite is not enumerated as its own component: rusqlite uses the bundled feature, which statically links a native C SQLite library. A Rust-crate SBOM lists libsqlite3-sys as a crate component but does not enumerate the vendored C library as a separate component. This is a standard limitation of crate-level SBOM generation, not specific to the fork.
OS code signing is not yet implemented: The release pipeline signs artifacts with cosign and SLSA provenance but does not yet implement Windows Authenticode or macOS Developer ID / Gatekeeper notarization. Binaries may trigger OS security prompts on first launch. OS code signing is a planned enhancement layered on top of the existing artifact signing.
Boundary:Artifact signing and build provenance are release-pipeline metadata. They are distinct from the product's Ed25519 ledger signing basis (v2 provenance: sig_version:2 binds entity, author, risk, origin, and related fields in addition to the legacy five fields; historical v1 rows dual-verify). This track changes neither the ledger signing basis nor the no-network runtime invariant.
Telemetry
Optional build feature; disabled by default. It must be explicitly enabled.
Opt-in only: The default binary does not include the usage-metrics feature. In a build that does, enable collection with ledgerful usage enable; its state is stored in ~/.ledgerful/usage/config.toml. Telemetry is never activated without explicit user action. The payload contains the documented aggregate fields below; it does not include command arguments, source code, file paths, diff text, or query text.
Payload schema version used by the ingest validator.
anonymous_id
Random UUID generated when usage metrics are enabled; stable across repositories on the same machine and not an account identity.
client_version
Installed Ledgerful version.
platform
Operating-system family: Windows, macOS, Linux, or unknown.
sent_at
UTC timestamp for the send attempt.
window_start
Start of the aggregated reporting window.
window_end
End of the aggregated reporting window.
command_counts
Aggregate top-level command-name counts since the previous successful flush. Arguments, paths, entity names, and query text are not included.
features_enabled
Compiled-in Ledgerful feature names such as web, mcp, sync, daemon, and viz-server.
active_days_in_window
Count of distinct UTC days with at least one recorded command during the reporting window.
Command arguments, source code, file paths, diff text, query text, commit messages, and author identities are not part of this payload.
View example telemetry payload (JSON)
EXAMPLE The payload below shows the complete payload shape documented above. The endpoint is the Supabase Edge Function documented on this page and is only contacted after ledgerful usage enable.
The SOC 2-style evidence export is a ZIP file generated entirely from local data. This is not a hosted SOC 2 portal — no data leaves your machine during export.
Scope: This is a local ZIP export only. A hosted SOC 2 portal (with continuous monitoring, auditor access controls, and live attestation) is planned for enterprise and requires a future hosted control plane.
ZIP layout
File
Description
manifest.json
SHA-256 hashes and byte sizes for all other files, plus generatedAt (RFC3339) and entryCount. The files array is sorted by name for determinism. manifest.json itself is not listed in the files array.
manifest.sig
Raw 64-byte Ed25519 signature over manifest.json bytes. Proves the manifest was produced by the holder of this repo's signing key.
manifest.pub
Raw 32-byte Ed25519 verifying key (the public half of ~/.ledgerful/keys/). Used to verify manifest.sig offline without trusting a remote key server.
chain_head.json
Signed chain head binding the latest entry hash, genesis boundary, and chain length. Present when the ledger has entries; omitted for empty-state. Used by `ledgerful verify --against-export` to detect rollback or tail-truncation against an independently retained export.
ledger.csv
All committed ledger provenance records in RFC 4180 CSV format. Columns: tx_id, category, entity, change_type, summary, reason, committed_at, signed, signature, observed, prev_hash. Sorted by committed_at ascending, then tx_id ascending. The observed column carries gate-mode metadata; prev_hash links each entry to its predecessor in the chain, post-genesis only.
verification_history.csv
CI gate pass/fail records. Columns: run_timestamp, overall_pass, command, exit_code, duration_ms. Header-only when there are no verification runs.
adr/*.md
MADR-format Architectural Decision Records, one file per ADR ledger entry. Filenames are 0001-<slugified-summary>.md. Folder is omitted when no ADR entries exist.
Offline tamper verification
For each entry in manifest.json's filesarray, re-compute SHA-256 over the corresponding file's bytes from the ZIP and compare to the stored hash. A mismatch means the file was altered after the manifest was generated.
Read manifest.sig (64 raw bytes) and manifest.pub (32 raw bytes). Verify the Ed25519 signature over manifest.json bytes. A mismatch means the manifest itself was replaced.
Both checks must pass for the export to be considered unmodified. A failure in step 1 indicates file tampering; a failure in step 2 indicates manifest replacement.
View sample export manifest (illustrative — not real evidence)
The sample below shows the manifest.json structure and a few rows of ledger.csv exactly as a local export would render them. All values — timestamps, hashes, transaction ids, and signatures — are fabricated for illustration. A real export is regenerated on demand from your local ledger.
64-byte Ed25519 signature over manifest.json bytes
(raw binary; not human-readable; placeholder shown)
manifest.pub (SAMPLE)
32-byte Ed25519 verifying key
(raw binary; not human-readable; placeholder shown)
ledger.csv (SAMPLE — first 3 rows)
tx_id
category
entity
change_type
summary
committed_at
signed
0001
adr
docs/adr/0001-record-ledger-entries.md
create
Record ledger entries as MADR-format files
2026-06-12T09:14:02Z
true
0002
config
config.toml
update
Enable coverage report and signing requirements
2026-06-18T17:02:51Z
true
0003
refactor
src/verify/manifest.rs
update
Sort manifest files array by name for determinism
2026-06-25T11:38:44Z
true
What we prove and what we don't
The chain-hash feature adds a concrete claim ceiling. This section restates what the signatures and chain verify, and the known gaps that require an out-of-band check.
What we prove
Each ledger entry is Ed25519-signed.Every new committed entry is signed over the v2 provenance payload (sig_version:2): tx_id, category, summary, reason, committed_at, entity, change_type, entry_type, author, risk, is_breaking, related_tickets, and origin. Historical v1 rows remain dual-verifiable until re-sign upgrades them. When intent.trusted_public_keys is pinned, verify reports VALID (trusted) vs VALID (unknown key). (engine signing basis v2; track 0072)
The SOC 2-style export manifest is signed.Each SOC 2-style evidence ZIP includes manifest.sig, a 64-byte Ed25519 signature over the manifest.json bytes, plus manifest.pub for offline verification. (src/export/soc2.rs:300-305)
Chain hash makes order/set tampering evident.From the chain-hash adoption date, every post-genesis entry stores prev_hash and a signed chain head binds the latest entry hash, genesis, and length. Running ledgerful verify --signatures --chain walks the linkage end-to-end and detects alteration, removal, reordering, or insertion. (chain-hash decision memo §3)
verify --against-export detects rollback when the head is retained.ledgerful verify --against-export <path> compares the live chain head against a previously exported signed head. If the live chain is shorter, points to a different latest entry, or presents a mismatched head, the command fails. Detection requires the export to be kept outside the machine — for example, an auditor copy or CI artifact. (chain-hash decision memo §4)
The offline verifier is a standalone, dependency-free Node.js script.verify-soc2-sample.mjs has no dependencies and runs offline. It recomputes SHA-256 over each file and verifies the Ed25519 manifest signature with the public key included in the export.
What we don’t prove
Signer identity.manifest.pub in the export is self-asserted: it originated from the same machine that produced the ZIP. A compromised machine could replace the ledger data, the signature, and the public key together, producing a self-consistent but fraudulent export. Out-of-band verification — comparing the Ed25519 fingerprint against a copy obtained independently — is required to close that gap. (sample-soc2/index.md:93-103)
Rollback to an earlier valid state from the same machine.The chain head stored on the local machine can be rolled back alongside the database, and that earlier head will still verify. Detecting rollback requires a chain head retained independently of the machine. (chain-hash decision memo §3)
Pre-chain entries.Entries committed before chain-hash adoption (migration m51) remain order-unverifiable by design. We do not fabricate retroactive chain history. (chain-hash decision memo §6)
Ground truth of free-text provenance fields.Category, summary, reason, risk, related_tickets, and similar free-text fields are entered by the user or automation. The v2 signature proves they have not been altered since signing; it does not prove they are accurate or complete.
Full key compromise + re-sign everything.An attacker with the local private key can re-sign a rewritten ledger (ledger re-sign). Trusted-key pins distinguish foreign keys when configured, but a compromised trusted key still wins locally. Out-of-band head retention remains required against silent rewrite.
Unsigned residual metadata.verification_status, observed, outcome_notes, and prev_hash (chain layer) are outside the entry Ed25519 basis. Mutating residual columns alone does not invalidate the entry signature.
Why this matters: the chain makes tampering evident, not impossible. We do not use the words “never altered” or “unchangeable” as a guarantee anywhere on this page, and the listed gaps are intentional limits, not temporary shortcomings.
Policy as code
Offline CI merge gates over declared named rules — evaluation only, not a compliance certificate.
ledgerful policy check evaluates a flat .ledgerful/policy.toml (or a trusted --policy path) against PR/diff/ledger state and exits nonzero on violation. Built-in rule ids: require_signed_entries, no_pending_tx, verification_must_pass, max_risk_without_adr, fail_on. No expression-language DSL.
Honest limit: policy check evaluates the declared rules over the presented ledger and risk inputs. It is not a compliance verdict, certification, or proof that a change is safe. Chain continuity strengthens the presented ledger; it is still not a substitute for your org's change-management process.
Base-branch policy: In CI the enforced policy is the base branch's (or a trusted --policy path), not your PR's. Edits to .ledgerful/policy.toml in a PR branch do not change the gate until they are merged and reviewed on the base branch.
Permissions model: typical workflow needs contents: read (checkout + base policy), optional pull-requests: read / checks: write for the Action wrapper. The engine only evaluates and exits; posting stays outside the engine. Full rules, CI YAML, and machine JSON contract: /docs/policy-check.
Threat model and non-goals
Where Ledgerful provides protection today, and the categories of guarantee it does not attempt to make.
Trusted local machine assumption
Ledgerful assumes the local machine is the trust boundary. Every claim on this page — ephemeral token, signing key, local sync transport, redacted evidence export — depends on the integrity of the local OS, filesystem, and the user running the CLI.
Local compromise equals key compromise
Private keys are stored as plain hex files protected only by filesystem permissions. Malware or a stolen laptop without Full Disk Encryption (FDE) can extract the signing key and forge ledger entries. FDE is the primary recommended mitigation. Hardware-backed key storage (TPM, Secure Enclave) and hosted KMS are planned for enterprise and require a future control plane.
Local dashboard is loopback-only
The dashboard bind address is 127.0.0.1:52001; CORS is restricted to loopback origins; the session token is 256-bit random, validated in constant time, and never persisted to disk. This is not an exposure surface for an external network — it is an exposure surface for a local attacker who can read process memory.
External paths are opt-in and narrow
Opt-in telemetry sends a fixed aggregate JSON payload (no source, paths, query text, or commit messages). Two configured cloud-model workflows can send data: ask sends sanitized, truncated context, and index --fast sends code chunks to a configured Gemini model for semantic extraction. Both are opt-in (require a configured API key) and neither is active in the default local workflow.
What Ledgerful does not claim
Hosted-mode guarantees. The local-first engine does not promise the SLAs, RBAC, audit log retention, or team-scope guarantees of a hosted control plane. Hosted mode is planned and does not exist today.
We are not SOC 2 certified or SOC 2 compliant. Ledgerful generates a local SOC 2-style evidence export from your ledger; we are not a certified audit firm and do not claim third-party SOC 2 attestation.
FedRAMP, FIPS 140, or other government baselines. No claim is made about FedRAMP authorization, FIPS-validated cryptography, or comparable government certification.
Zero-network or zero-telemetry absolutes. The default build excludes telemetry; opt-in telemetry and the configured cloud-model ask and index --fast workflows are the outbound paths for project data. The optional viz command generates a local HTML file that loads the vis-network library from a public CDN when opened in a browser. Nothing here is a 'no network ever' guarantee.
Air-gap. The engine can run fully offline, but this page does not claim that every install configuration is air-gapped. Operators are responsible for their own network posture.
SSO / SAML / OIDC / SCIM / RBAC in the local daemon. None of these are implemented locally. They are planned for enterprise for a future control plane.
Reading this section: The threat model and non-goals are restated, not introduced. Each bullet traces back to the data flow, signing, telemetry, or evidence-export content above. If a future release changes the boundary (for example, by shipping a hosted control plane), this section will be updated in the same change.
Subprocessors
Default local analysis uses no subprocessors for project data. The two lists below are kept clearly separated: public-site hosting / docs infrastructure (which never touches user code) and the product / future-hosted-control-plane subprocessors.
Public-site hosting & docs infrastructure
Serves the static www.ledgerful.dev site only and never receives Ledgerful project source code, ledger data, or product data. Visitor traffic to the public site (e.g. IP addresses) is processed by Vercel as the hosting provider for the marketing site, not as a product subprocessor.
Subprocessor
Purpose
Status
Vercel
Static site hosting for this public marketing website. Hosts the public www.ledgerful.dev site only and never receives Ledgerful project source code, ledger data, or product data. Visitor traffic to the public site (e.g. IP addresses) is processed by Vercel as the hosting provider for the marketing site, not as a product subprocessor.
Available · Runs locally
Kit (waitlist)
Email capture for the /waitlist interest form. Receives the email address and an opt-in timestamp via a first-party server relay. No source code, project data, or product data is sent. Double opt-in is mandatory: adding a subscriber to a double opt-in form triggers a confirmation email that must be acted on. The Kit API key stays server-side and never ships to the browser. To request deletion of your email from the waitlist, contact hello@ledgerful.dev with the subject "Waitlist deletion request" — your email and associated data will be removed from Kit within 5 business days.
Available · Runs locally
Product & future-hosted control plane
Subprocessors scoped to the Ledgerful product runtime. “Current” rows handle data the user has explicitly chosen to send today; “planned” rows are reserved for a future hosted control plane and do not receive any data yet.
Subprocessor
Purpose
Status
Supabase (telemetry)
Opt-in usage telemetry ingest only. No source code or project data is sent. Disabled by default. Ingest rejects unauthenticated and over-quota traffic; clients send a non-secret bar-raising token (not strong authentication).
Available · Runs locally
Configured model provider
Gemini, Ollama Cloud, or OpenRouter receives sanitized, truncated context only when a user configures and selects that cloud-backed ask workflow.
Available · Runs locally
Supabase (hosted backend)
Future control-plane database, auth, and Edge Functions for the hosted team service.
Planned · Hosted
GitHub
Future GitHub App installation records and webhooks for the hosted control plane. The current self-managed GitHub Action is a separate planned path run in the customer's own repository — not publicly installable yet.
Planned · Hosted
Data deletion policies and data processing agreements will be defined when hosted mode launches. No subprocessor contract applies to local installs. Vercel is intentionally listed only under public-site infra; it does not process project data and is not part of the product / future-hosted subprocessor list.
Email capture is separate from telemetry. The /waitlist form sends your email address to Kit (listed above under public-site infrastructure) for the sole purpose of notifying you when Ledgerful launches. It is not the same as the opt-in usage telemetry documented in the telemetry section above, which sends aggregate command counts and platform metadata — never email addresses. Email capture requires its own double opt-in; telemetry requires its own explicit enable command.
Evaluate Ledgerful locally
The trust posture above is verifiable on your own machine. Install the CLI, run a scan, and inspect the local-first boundary.