Capabilities · 14. Trusting the build

Every claim in this chapter is checkable by you, without asking us. The binary is cosign-signed and carries a CycloneDX SBOM and SLSA provenance. The daemon dials nothing by default and a CI job asserts that under strace. unsafe code is forbidden workspace-wide, not merely discouraged. Every Rust source file carries a licence header because a CI gate rejects the ones that do not. And the licence itself is Apache-2.0, open source with no copyleft.

This chapter is explanation. It says why each assurance mechanism exists and what it does not cover. The mechanisms themselves are documented in the Contributing set.

14.0 In plain English

You are about to run somebody else's binary against your own memory. The reasonable question is not "is this software good" but "how would I know if it were not". This family is the set of answers that do not require you to trust anyone's word.

They come in four kinds. First, things a machine asserts on every build: that the daemon makes no outbound network connections, that no file lacks a licence header, that no crate contains unsafe code, that adding a route without classifying it fails a test. These are the strongest kind, because a human forgetting cannot bypass them. Second, things you can verify on the artefact you downloaded: a cosign signature, a bill of materials listing every dependency, and provenance saying which workflow built it. Third, things you can read: 5,969 tests, a fuzzing corpus and a mutation ratchet, all in the same repository as the code. Fourth, the licence, which is the assurance that matters over years rather than releases: what you may do, and the conditions attached to redistributing it.

It is worth being clear about the one thing this family does not give you, because the rest is strong enough that the gap deserves naming. None of this proves that the running binary on your server is the signed one. Verifying the signature is a step you take at install time, and re-verifying it later is a step you have to take deliberately. The tools are here; the discipline is yours.

The other honest note concerns the licence. Crux Daemon is Apache License, Version 2.0, open source: you can read every line, audit every claim in this documentation set against it, run it internally including commercially, modify it, redistribute it, and host it for other people. Section 14.6 quotes the operative terms rather than characterising them.

14.1 The no-phone-home guarantee, and its one exception

Status The CI gate is SHIPPED; the startup passport claim is FLAG CORECRUXD_PASSPORT_CLAIM_ON_STARTUP, default true · Reached through scripts/assert-no-phone-home.sh and the egress-probe workflow · Who it is for human

What it does. The daemon makes no outbound network connections in its default configuration, and this is asserted by a CI job rather than promised in prose. The preferred mode copies the built binary into a fresh temporary directory that is deliberately not a git checkout, boots it under strace -f -e trace=connect,sendto,sendmsg,sendmmsg with a scrubbed environment, and fails if a connection is attempted. Where strace is unavailable, a fallback boots the daemon inside a network namespace with only loopback and asserts it becomes fully ready and serves its probes. There is one exception in a default configuration: a one-shot anonymous passport claim to a public endpoint, gated by CORECRUXD_PASSPORT_CLAIM_ON_STARTUP, which defaults to true and is made idempotent by an on-disk marker (config.rs:890).

Why it works this way. "We do not phone home" is the single easiest claim in this industry to make and the hardest to believe, because it is unfalsifiable from the outside and it is broken by accident far more often than by intent: a telemetry crate, an update check, a font. Asserting it under a syscall tracer makes it falsifiable, and the choice to run the binary from a non-checkout directory is what makes the assertion honest, because the daemon's git-based update posture would otherwise have something to fetch and the test would be measuring the wrong shape. Naming the passport-claim exception rather than special-casing it in the test is the same instinct: an air-gap document that does not mention it would be wrong.

What changes for you.

  • As an operator: you can run the assertion yourself against the binary you downloaded. It needs no network, no toolchain and no daemon.
  • As an agent: nothing. This is a property of the deployment, not of the tool surface.

What it does not do.

  • It does not cover configured egress. Every outbound feature in this documentation set, sync, connectors, embedder delegation, the update check, is outbound by definition once you enable it. The guarantee is about the default, not about your configuration.
  • The netns fallback proves offline-first functionality and cannot observe egress attempts, because inside the namespace they simply fail. A pass in fallback mode is a weaker result than a pass under strace.
  • The assertion runs on the release leg, not on every pull request, because it binds fixed ports and collides with leftover daemons on shared runners.

Turn it off. Air-gapped deployments should set CORECRUXD_PASSPORT_CLAIM_ON_STARTUP=0 and disable the update check, and should do so deliberately rather than relying on the calls failing.

Where the detail lives. What the assertion covers and how to run it: contributing/09 Releases and packaging. The script: assert-no-phone-home.sh.

14.2 Required checks and the merge queue

Status SHIPPED · Reached through eleven required status checks on main, behind a merge queue · Who it is for human

What it does. Eleven checks are required on main and merges go through a queue. Alongside the obvious ones sit four that are unusual enough to name: a licence-header gate that fails the build if any .rs file under crates/ is missing either the human-readable licence line or the SPDX identifier (check-licence-headers.sh), a typos gate, an unwrap ratchet that fails a crate for exceeding its recorded unwrap() and expect() baseline, and twelve per-crate coverage floors. Underneath all of it, unsafe_code = "forbid" is set workspace-wide (Cargo.toml:115), and forbid cannot be overridden by an inner allow, so no crate can opt back in.

Why it works this way. Ratchets were chosen over absolute thresholds because absolute thresholds on an inherited codebase are either unachievable or meaningless, whereas a ratchet makes the direction of travel enforceable from wherever you are. The licence-header gate exists because SBOM and compliance scanners cannot detect a custom licence: the SPDX line is what a scanner consumes, and a gate is the only way to keep coverage at 100% rather than at 100% minus the files added last week. forbid rather than deny on unsafe code is a deliberately absolute choice, and it means the memory-safety claim needs no per-crate audit.

What changes for you.

  • As an operator: the memory-safety and licence-metadata claims in this set are enforced by the build, not asserted by a document.
  • As an agent: an agent contributing to this repository will fail on typos, licence headers and the unwrap ratchet more often than on tests. Run those three locally first.

What it does not do.

  • Coverage floors are per crate and partial. Twelve floors is not full coverage, and a crate outside the list has no floor.
  • The unwrap ratchet bounds growth, not risk. A crate at its baseline still contains every unwrap in that baseline.
  • Any new required check must also trigger on merge_group or the queue hangs waiting for a report that never comes. This is a repeated operational trap, not a theoretical one.

Where the detail lives. Every gate, its trigger and how to run it locally: contributing/05 Quality gates and CI.

14.3 Test depth: five tiers

Status SHIPPED · Reached through cargo test, cargo fuzz, cargo mutants · Who it is for human

What it does. Testing runs at five tiers: inline unit tests, per-crate tests, integration tests with a real daemon harness, fuzzing, and a mutation-testing ratchet. The count is 5,969 test attributes across the crates, measured on 2026-07-27 by counting #[test] and #[tokio::test] attributes.

Why it works this way. Each tier catches a class the tier below cannot. Unit tests catch logic; integration tests against a real daemon catch wiring, which is where this codebase's genuinely dangerous bugs live, because most of the risk is in three-place registrations rather than in algorithms. Fuzzing catches inputs nobody thought of. The mutation ratchet is the one that answers the question the other four cannot: not "do the tests pass" but "would the tests notice if the code were wrong". It is a ratchet rather than a threshold for the same reason as §14.2.

What changes for you.

  • As an operator: the integration tier boots a real daemon, so a passing suite means the process starts and serves, not only that functions return.
  • As an agent: an agent making changes here should expect the integration tier to be the slow, informative one, and to be where a wiring mistake surfaces.

What it does not do.

  • A test count is a measure of volume, not of coverage or of quality. The published mutation score is the honest reading of test effectiveness, and it is not 100%.
  • The integration tier depends on the daemon becoming ready. A full disk trips the capacity gate in §12.6 and presents as every integration test failing identically with an empty error, which is a CI environment problem rather than a code failure.
  • Fuzz targets cover the parsers they were written for, and no more.

Where the detail lives. The five tiers, how to run each, and the current mutation ratchet: contributing/04 Testing.

14.4 Signed, SBOM'd releases

Status SHIPPED · Reached through GitHub releases, the ghcr container image and the Helm chart · Who it is for human

What it does. A release build matrix produces artefacts signed with cosign, a CycloneDX SBOM generated before packaging so the release manifest covers it, and SLSA provenance generated by the SLSA GitHub generator with the artefact digests as subjects. The container image is built locally, scanned with Trivy, and pushed only if there are no critical vulnerabilities; it is then keylessly signed and attested. Scripts gate the release on the daemon and release boundary and on the egress assertion from §14.1.

Why it works this way. The three artefacts answer three different questions and are not interchangeable. The signature answers "did CueCrux produce this". The SBOM answers "what is inside it", which is the question your vulnerability scanner asks and the only practical way to respond to a dependency advisory. The provenance answers "which workflow, from which source, produced this", which is the question that catches a compromised build pipeline rather than a compromised artefact. Generating the SBOM before packaging is a small detail with a large consequence: an SBOM produced afterwards is not covered by the manifest that gets signed.

What changes for you.

  • As an operator: your install step can verify a signature, and your vulnerability process can consume the SBOM directly rather than scanning a running container and guessing.
  • As an agent: nothing. This is a procurement and deployment surface.

What it does not do.

  • Signing proves origin and integrity, not correctness. A correctly signed release can still contain a bug.
  • Verification is your step. Nothing in the daemon checks its own signature at runtime, so a verified download that is later replaced on disk is not detected by anything here.
  • The Linux cross-compilation legs are cosign-signed but deliberately not folded into the SLSA provenance subjects yet. If you consume provenance, check that your target is one of the native legs.

Where the detail lives. The release matrix, what is signed and how to verify it: contributing/09 Releases and packaging. Deploying and upgrading a verified artefact: daemon/17 Operations.

14.5 Contract-drift tests, and the three-place wiring rule

Status SHIPPED · Reached through cargo test -p corecruxd · Who it is for both

What it does. Adding a route without also declaring it in the manifest and classifying it in the authorisation contract fails a test, or fails closed with 403 at runtime (route_spec_drift.rs). The same three-place rule applies to on-disk artefact types, which must be added to the storage allowlist, the projection registry and the load-at-startup path together.

Why it works this way. This is the mechanism that makes the published route reference trustworthy, and it deserves to be understood as a documentation guarantee rather than as a testing detail. The failure it prevents is the ordinary one: someone adds a route, the reference is regenerated from a manifest the route is not in, and the documentation is quietly wrong. Making the manifest a test dependency means the documentation cannot drift from the code without a red build. Fail-closed at runtime is the belt to that braces: a route that somehow escapes classification is denied rather than served unauthorised. The artefact-type variant exists because missing one of its three places produces a quarantine-on-restart bug that is hard to diagnose and easy to create.

What changes for you.

  • As an operator: the route reference you are reading is enforced against the code, which is why route tables in the reference set can be relied on and route counts in this set can be quoted.
  • As an agent: an agent adding a route to this codebase must touch three places. Touching one produces a test failure that names the omission.

What it does not do.

  • It checks that a route is declared and classified. It does not check that the classification is the right one, so a route classified too permissively passes.
  • The console HTML routes are outside the matrix, and the completeness test does not parse them. They are open under the default shadow posture and would 403 under enforce.
  • Contract-drift tests cover routes and artefact types. They do not cover response-body drift.

Where the detail lives. The three-place rule with worked examples: contributing/06 Recipes. What the manifest and the route contract are: api/00 API index.

14.6 The licence, and the open-closed line

Status SHIPPED · Reached through LICENSE, NOTICE, SECURITY.md, TRUST-CONTRACT.md, CITATION.cff · Who it is for human

What it does. The daemon is licensed under the Apache License, Version 2.0, the unmodified upstream text (LICENSE). It grants broad rights including running the software for any purpose, reading and auditing the source to confirm the integrity of the behaviour claimed in documents like this one, modifying it, redistributing it, and hosting it as a service. This replaced the CueCrux Community Licence (CCL v1.0), a source-available, BSL-style licence that prohibited exactly that: redistribution inside a competing product and third-party hosting outright. Redistribution under Apache-2.0 is not prohibited, it is conditioned, on four requirements from the Redistribution clause (LICENSE:89):

  1. Include a copy of the licence with any distribution.
  2. State what you changed, in modified files.
  3. Retain the copyright, patent, trademark, and attribution notices you copied.
  4. Pass on the NOTICE attribution text.

Why it works this way. The licence is trying to hold one position, not balance two: everything must be readable and reusable, because a system that asks you to trust its receipts and its tenant isolation cannot also ask you to take those on faith or ask permission to build on. The relicense from CCL v1.0 removed the restrictions that a source-available licence needs and an open-source one does not — the competing-product and third-party-hosting prohibitions are gone, not merely time-limited. The CCL already named Apache-2.0 as its eventual Change Licence; the relicense brought that conversion forward immediately for all versions rather than waiting out each release's own three-year clock.

What changes for you.

  • As an operator: running it for your own fleet, and offering it to your customers as a hosted service, are both licensed now. The redistribution conditions above still apply if you ship a modified build.
  • As an agent: the audit right is not merely explicit, it is unconditional. An agent may read this source to verify any claim made in this documentation set, and doing so is a use the licence names.

What it does not do.

  • It does not cover everything in the estate. Crux Engine and CoreCrux are closed: their contracts and behaviour are published, their mechanism is not. The content/ directory is under a separate content licence (content/LICENCE-CONTENT.md).
  • It grants no trademark rights (LICENSE:138). "CueCrux", "Crux", and "CROWN" remain trade names of CueCrux Ltd regardless of what you build on the code.
  • Contribution carries a licence grant. Contributing code is inbound=outbound: it is licensed under Apache-2.0 on the same terms as the rest of the work, per the Submission of Contributions clause (LICENSE:130). There is no separate CLA to sign.

Where the detail lives. The licence, the security-disclosure route, the trust contract and the governance position: contributing/08 Licence, security and governance.


Each explainer above carries its own grounding in its final block. Statuses in this chapter reconcile against the daemon feature inventory taken at 93b41a7d9735c4f7d1186c7a57b861d746273366; the complete status table for all 119 capabilities is chapter 15.