The tool is a command line program that runs on your own machine and reads files out of a folder you point it at.
Here is the whole path a document takes, in order.
You point the ingest command at a package directory. It opens the PDFs in place, pulls the text layer with page and coordinate positions, segments the text by CSI MasterFormat section numbering, and locates scope markers by pattern matching. There is no model call anywhere in this step. It is text extraction and regular expressions.
The result is one JSON file, written where you tell it to write it. Your original PDFs are not moved, not copied, and not modified.
The run command reads that JSON file plus the rule packs, evaluates the rules, runs the validators, and writes the register, the bill of materials and the report into an output directory you choose. No model call, no network call. The parts of the system that decide and compute are structurally forbidden from reaching a model client, and a test asserts the import graph in both directions.
There is one command that can make an outbound call: the chat command, which answers questions out of the run artifacts. This is the only place in the entire program where anything can leave the machine, and section 03 below is about exactly what it sends and what has to happen first.
It can also be run sealed, which answers only from responses already recorded on your machine and cannot make a call at all.
The output artifacts land in a directory you name, on your disk. Nothing sweeps them up, uploads them, or reports on them. There is no telemetry in this program: the source contains no HTTP client, no socket use and no server. The only module in the whole codebase that can open a network connection is the one that constructs a model vendor's own SDK client, and only the chat command calls it.
Where the model-call cache lives, and why it lives there
Model responses are cached so a run can be replayed. A cached response holds verbatim text out of your documents, which makes the cache a copy of your material and therefore something whose location has to be decided rather than defaulted.
Every real package's cache lives beside that package, at <package>/out/cache/, outside the tool's own working tree. That is a written project requirement, not a convention.
The reason is specific. A cache entry holds a model's response, and a response holds verbatim source text. A cache recorded against a real bid package and then committed into the tool's repository would put a district's specification text into a source repository, which is the exact thing this project forbids, arriving through a door nobody was watching. Cache entries that ship with the tool may only be recorded from the project's own invented test fixtures.
- One human-readable JSON file per call. It holds the vendor, the model identifier, the prompt version, a hash of the request, and the response. You can open it and read it.
- It holds no API key. The key never passes through this code at all: each vendor's SDK reads its own environment variable when the client is constructed, so the value never enters the frame that could write it down. It is never placed in a request payload, never stored in a cache entry, and never interpolated into an error message, not even a prefix of one.
- Writes are atomic. Written to a temporary file in the same directory, flushed to disk, then renamed, so an interrupted run cannot leave a half-written entry that a later read accepts as valid.
- Deleting it is safe. It is a replay cache. Removing the directory removes the copies; the tool records again the next time it is asked to, and asks you again first.
- Sealed mode never writes and never calls. A sealed cache is read-only. It refuses to record, refuses to compute, and reports a miss by name rather than quietly reaching the network.
What leaves the machine, who receives it, and what has to happen first
Which vendor receives text
Today, exactly one: Anthropic, and only through the chat command. Anthropic's SDK is the only model SDK in the tool's dependency list. The vendor table in the code also names OpenAI, so that a second reader can be added later, but no command reaches it and its SDK is not a declared dependency. If a second vendor is ever wired in, it is a change to the disclosure, and the consent gate below re-asks on exactly that change.
What is actually sent
Not your PDFs. On the chat command, the material is the question you typed plus the specific records that deterministic retrieval selected out of the run artifacts. Each record goes as an id, its text, and the quoted source sentence it carries. Page numbers and document names are deliberately left out of the request, because a model that was shown a page number could type one back, and citations are looked up in your own artifacts by code afterwards instead.
The disclosure, before the first call
Before anything is sent for a package, a block prints on your terminal naming each vendor, the full dated model identifier that will receive the material, and each file by name. Not a family name like "the latest model", because that does not say what actually ran. Not a generic "this tool uses AI" banner, because a reader cannot act on one. The point is that you can take that list to your counsel or to your district contact and get a yes or a no on the facts.
That is the shape of the block, with the package, vendor and model identifiers standing in for the real ones. Where two files share a name, the colliding entries take one more folder from the left, so an addendum folder's drawings file and another addendum folder's drawings file are told apart in the terms the district itself issued them.
The consent record
If you answer yes, a record is written to your package's own output directory. It holds four things and nothing else: which package, which vendors, which model identifiers, and a hash of the exact material that was approved. No API key, no fragment of one, no timestamp.
- When the contents change. The hash is over the bytes of every file, not their names. A revised addendum that keeps its filename produces a different hash and re-asks. Consent to send version one is not consent to send version two, and the file name staying the same is exactly the case a name-only check would miss.
- When the recipients change. Approving one vendor is not approving that vendor plus a second party. The vendors, the model identifiers and the file list are disclosed together as one statement, and a gate that watched one third of what it showed would not have re-asked about a disclosure that changed.
- When anything about the record cannot be read. Missing file, unreadable file, invalid JSON, wrong type, missing field, mismatched hash: all of it means ask again. It fails closed on purpose. A false alarm costs you one keystroke. The other kind of error is a client's bid package leaving your machine without anyone being asked.
- Not when the file order changes. The hash is order independent, so a folder listing files in a different order on a different machine does not re-ask. A prompt that fires for no reason is a prompt people learn to click through, and a disclosure that gets clicked through has stopped disclosing anything.
There is no way to turn it off
No flag, no environment variable, no yes-to-everything switch. The project's own words for why, from the amendment that requires the disclosure:
There is no flag to suppress the prompt, because suppressing it is the first thing anyone scripts.
Two consequences worth stating. Declining is a correct outcome, not a crash: the estimator who reads the file list and decides a district's package does not leave their machine has used the feature correctly, and the error message is written for them. And a script with no terminal attached is treated as having declined, because no answer is not a yes and defaulting the other way would transmit a package because a pipeline had no input attached.
The one place the prompt does not appear is a sealed run, which cannot make a call at all and therefore has nothing to disclose. A prompt that fires where no transmission is possible is the kind people learn to click through, so it is not shown there.
The gate is also re-checked at the point of use rather than trusted from the command that ran it. A caller that could hand down a bare "already approved" would be the suppression flag the amendment says must not exist, so what gets handed down is the consent record and the hash, and the only way past is a disclosure that happened and still covers this exact material.
There is no hosted service, and that is stated as a fact rather than as a promise
No document is uploaded to a server run by this product, because there is no server run by this product.
This is not a policy commitment that could be revised. It is a description of what exists. The source contains no web framework, no task queue, no upload endpoint, no API server and no storage bucket. There is nothing to upload a document to. The plan viewer is a static export that renders one built-in example fixture; it has no upload, no run selector and no connection to a running engine.
A hosted version is described in the project's own plan as a later phase, and it has not been built. Saying so is a stronger privacy position than any promise a hosted service could make, and it is worth more to you than a certification badge would be, so it is here in plain words instead.
If that ever changes, this page changes before it ships, not after.
One honest caveat about scope. This page describes what the software does. It does not describe your machine, your backups, your file sync, or your own network. A bid package sitting in a synced folder is in that sync provider's hands regardless of what any tool does with it, and that is your call to make and not something this program can make for you.
The model vendor question, answered without overstating it
If text from your package goes to a model API, that vendor is a subcontractor in your chain of custody whether or not anyone calls it that. Here is what their published policies say, and here is exactly how far that gets you.
This project has no contract with either vendor covering your material. The account is yours, the key is yours, and the terms are between you and them. Nothing on this page is a contractual term offered by this product, because there is no arrangement in place that could make one.
Published policy, quoted
"By default, we will not use your inputs or outputs from our commercial products (e.g. Claude for Work, Anthropic API, Claude Gov, etc.) to train our models."
The same page states an exception: if you explicitly report feedback or bugs, or otherwise choose to allow it, your material may be used for training. Nothing in this tool submits feedback on your behalf.
privacy.claude.com, data usage for the commercial API
Quoted as published, checked 10 August 2026.
Published policy, quoted
"data sent to the OpenAI API is not used to train or improve OpenAI models (unless you explicitly opt in to share data with us)."
The same documentation describes abuse monitoring logs retained for up to 30 days unless longer retention is required by law or is reasonably necessary to protect their services or a third party, and separate retention rules that vary by endpoint.
developers.openai.com, API data usage and retention
Quoted as published, checked 10 August 2026. Named in the code as a possible second reader; no command reaches it today.
What those quotes do not settle, and what you have to do
Published policies are not your contract. They change, they differ by account type, and an enterprise agreement, a zero-retention arrangement or a reseller in the middle can all change the answer for your account specifically. Retention is a separate question from training, and abuse-monitoring retention applies even where training does not.
It is the operator's responsibility to check their own account terms before sending a client's package. That is not a disclaimer to move the risk. It is the only accurate description of who is in a position to know: the account is yours, and this project cannot see your terms.
If your NDA or your district's terms will not permit it, the answer is straightforward. Do not run the chat command, or run it sealed. Reading the package and running the engine make no outbound call, and that is the majority of what the tool does.
So nobody has to guess whether the data is the product
Blueprint Risk Engine is sold as a licensed tool that runs on the buyer's own machine, and the revenue is the license.
There is no data product. Nothing you process is collected, aggregated, resold, used to train anything, or turned into a benchmark. That is not a promise about restraint. Under section 04 there is no server to collect it to, and under section 01 nothing in the program sends it anywhere.
Even the measurement program is built the same way. The benchmark dataset that does not exist yet is specified to hold manifests only: the bid number, the district, the public source link, the retrieval date and the derived annotations. Source bid documents, drawings and client material are never committed to it. Anyone checking the published results retrieves the originals from the citation themselves, which means the measurement can be audited without this project ever holding anyone's package.
One person builds and sells this. There is no separate data team, no advertising arrangement, and nothing downstream that would make your documents worth more to this project than the license is.