One control inventory for a DoD CUI boundary. Five NDAA-driven regimes attach as crosswalk edges, not five programs. The pipeline withholds a control rather than reporting 0 of 0 when no collector can speak. This page is how you run it, and how you point it at a real estate.
Run it in your browser — no install → A hosted demo runs the real pipeline against fixtures: one control inventory, five NDAA regimes as crosswalk edges, OSCAL O1–O5 emitted and the SPRS score derived from assertion records.“NDAA compliance” is not a program. It resolves to CMMC Level 2, DFARS 7012 incident reporting, Section 889 telecom representation, the 1260H Chinese Military Companies list, and forthcoming FY2026 harmonization — plus FASCSA sitting adjacent and routinely conflated with them. Building five parallel programs produces five populations of the same assets and no way to answer “how exposed are we.”
This repository keeps one inventory. Each regime is a crosswalk: an identifier, a confidence, and a written basis. Never framework text. The pipeline collects, loads a local DuckDB warehouse, asserts every control, and emits OSCAL O1–O5 with deterministic v5 UUIDs. Variance Frequency and Variance Duration come off the assertion history, which is what makes it a risk instrument rather than a compliance cost center. SPRS is derived from those same records — and refused when the weight table is empty.
status is lifecycle in the environment. Nothing here is operating until it is instrumented against real telemetry and observed holding.Node 22+. No Python, no warehouse product, no credentials, nothing contacts a real system. Read time for the guided setup is about fifteen minutes; the first real run is an afternoon.
0. Run it before you change anything.
git clone https://github.com/RootCawsLLC/cui-control-plane.git cd cui-control-plane npm install npm run pipeline
That collects from bundled fixtures, builds a local DuckDB warehouse, evaluates every control, and writes assertion records. You should see five controls asserted and one withheld. The withheld one is the lesson: no collector populates its source, so the tool refuses to say anything rather than reporting 0 of 0 passing.
Then walk the rest of the chain:
npm run emit -- --assertions .evidence npm run variance npm run coverage npm run demo
demo is the eight-step walkthrough: validate, coverage, SPRS against the empty real weights (it refuses), SPRS against fixture weights (arithmetic runs; the result is never called submittable), variance, policy (generates nothing while no control is operating), the 889 representation (blocked by unresolved manufacturers), and OSCAL emit. Every refusal is the point of the step.
1. Make it yours. Twelve questions, every one with a working default.
npm run init # writes gitignored ccp.config.yaml — the only file you edit npm run doctor # what is configured, what is missing, which controls will be withheld
doctor is the command you will run most. It is the answer to “am I set up yet?”
2. The three decisions only you can make.
| Decision | Default, and why |
|---|---|
| CUI boundary | Pick enclave unless leadership has funded enterprise scope. If you do not know, that is a finding, not a config value to guess. |
| Supplier master | One CSV of every supplier. Population for both 1260H and 889. You do not need an API. |
| 1260H list | This repo will not ship it. A stale copy reads as “screened” when it is not. Export the current DoD list on a calendar. |
3. Wire the first real source. Do CSV today. Drop exports in inbox/. The asset inventory needs two sources — CMDB and cloud — because the control is a reconciliation. Cloud-only reports every asset as unmanaged; CMDB-only can never find an unmanaged asset. Both look like measurements. Neither is one.
The full walkthrough — Entra, Okta, AWS Identity Center, AWS IAM, Azure — is docs/SETUP.md.
NOT REAL EVIDENCE.ccp policy generates nothing until a control is operating — observed holding, not planned. A policy for a control that is not yet holding is documented misalignment.Six controls ship as the spine, not as a finished CMMC L2 set. npm run coverage prints the backlog against 110 requirements. Adding a control is: write the YAML with a population definition from the start, write the dbt model, union it, add a stamped fixture, validate. See AGENTS.md.
You cannot press a button on this page and get a live warehouse — the tool is a CLI. What you can do is run the same fixture path the documentation claims, on your laptop, in five minutes, and get the same refusals.
operating. The command names every control it skipped and why.not-satisfied.
Fixture stamps travel into every artefact. Near-zero overlap between two sources that
claimed to describe the same estate is reported as a source error, not 81 unmanaged assets.
The full list of refusals is in the
README,
and each one is a test.