bootproof 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +873 -109
- package/dist/agent-plan.d.ts +44 -0
- package/dist/agent-plan.js +826 -0
- package/dist/agent-run.d.ts +117 -0
- package/dist/agent-run.js +459 -0
- package/dist/ai-repair.d.ts +58 -0
- package/dist/ai-repair.js +380 -0
- package/dist/cli.js +936 -38
- package/dist/diagnosis.js +114 -17
- package/dist/diff.d.ts +29 -0
- package/dist/diff.js +569 -0
- package/dist/exec.d.ts +30 -2
- package/dist/exec.js +332 -37
- package/dist/external-health.d.ts +16 -0
- package/dist/external-health.js +214 -0
- package/dist/infer.js +489 -41
- package/dist/plan.d.ts +2 -0
- package/dist/plan.js +49 -7
- package/dist/proof.d.ts +78 -2
- package/dist/proof.js +266 -13
- package/dist/receipt.d.ts +52 -0
- package/dist/receipt.js +356 -0
- package/dist/redact.d.ts +4 -0
- package/dist/redact.js +86 -2
- package/dist/registry.d.ts +82 -30
- package/dist/registry.js +355 -53
- package/dist/remote.d.ts +12 -1
- package/dist/remote.js +62 -18
- package/dist/repair-playbooks.d.ts +24 -0
- package/dist/repair-playbooks.js +593 -0
- package/dist/repair-safety.d.ts +130 -0
- package/dist/repair-safety.js +766 -0
- package/dist/repair.d.ts +142 -0
- package/dist/repair.js +1566 -0
- package/dist/run.d.ts +6 -1
- package/dist/run.js +385 -46
- package/dist/sbom.d.ts +22 -0
- package/dist/sbom.js +99 -0
- package/dist/taxonomy.d.ts +8 -2
- package/dist/taxonomy.js +428 -8
- package/dist/types.d.ts +57 -2
- package/docs/AGENT_IN_THE_LOOP.md +171 -0
- package/docs/AGENT_RUN_RECEIPTS.md +38 -0
- package/docs/CI_ACTION.md +71 -5
- package/docs/DETERMINISTIC_REPAIR_SAFETY_MODEL.md +705 -0
- package/docs/FAILURE_TAXONOMY.md +30 -1
- package/docs/HONESTY_CONTRACT.md +55 -4
- package/docs/LAUNCH_PLAYBOOK.md +232 -0
- package/docs/REAL_REPO_EVIDENCE.md +77 -0
- package/docs/REAL_WORLD_FIXTURES.md +105 -0
- package/docs/REGISTRY.md +48 -28
- package/docs/RELEASE_CHECKLIST.md +9 -1
- package/docs/REPAIR_RECEIPT.md +224 -0
- package/docs/agent-loop-gap-analysis.md +188 -0
- package/docs/examples/registry-seeds/advertised-port-mismatch.json +28 -0
- package/docs/examples/registry-seeds/airbyte-abctl-external-orchestrator.json +36 -0
- package/docs/examples/registry-seeds/go-ollama-service.json +36 -0
- package/docs/examples/registry-seeds/laravel-vite-sqlite.json +36 -0
- package/docs/examples/registry-seeds/monorepo-ambiguous-health.json +29 -0
- package/docs/examples/registry-seeds/php-composer.json +33 -0
- package/docs/examples/registry-seeds/rails-bundler.json +32 -0
- package/docs/examples/registry-seeds/sentry-devenv-direnv.json +41 -0
- package/docs/schemas/action-verdict-v1.schema.json +64 -0
- package/docs/schemas/agent-plan-v1.schema.json +148 -0
- package/docs/schemas/agent-run-receipts-v1.schema.json +192 -0
- package/docs/schemas/ai-repair-suggestion-v1.schema.json +70 -0
- package/docs/schemas/ci-context-v1.schema.json +63 -0
- package/docs/schemas/diff-result-v1.schema.json +66 -0
- package/docs/schemas/federated-receipt-v1.schema.json +51 -0
- package/docs/schemas/registry-entry-v1.schema.json +95 -0
- package/docs/schemas/registry-seed-example-v1.schema.json +102 -0
- package/docs/schemas/repair-action-v1.schema.json +136 -0
- package/docs/schemas/repair-receipt-v1.schema.json +221 -0
- package/package.json +13 -6
package/README.md
CHANGED
|
@@ -1,58 +1,378 @@
|
|
|
1
1
|
# BootProof
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/bootproof/bootproof/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/bootproof/bootproof/actions/workflows/receipt-gate.yml)
|
|
4
5
|
|
|
5
|
-
**
|
|
6
|
+
BootProof answers one question: **did this repository actually boot?** Not "did a command run?" Not "did Docker say containers are up?" Not "did an AI agent say it worked?" BootProof inspects a repo, builds an evidence-based run plan, executes only what it can justify, observes real health, and writes a signed attestation for success or failure. No proof, no green check.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## The Living Receipt: proof that travels
|
|
11
|
+
|
|
12
|
+
The Living Receipt is the same evidence as the JSON attestation, rendered as a single self-contained HTML file that re-verifies its own ed25519 signature in your browser with zero network calls. Download it, open it locally, then click **Tamper with signature** to watch the verdict collapse:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
curl -sL https://github.com/bootproof/bootproof/raw/main/assets/living-receipt.html -o proof.bootproof.html
|
|
16
|
+
open proof.bootproof.html # macOS; xdg-open on Linux; double-click on Windows
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The receipt is signed at the `local_developer_signed` trust level — it proves integrity-since-signing, not that the signer's machine was honest. The trust ladder (`local_developer_signed` → `ci_oidc_signed` → `neutral_runner_signed` → `transparency_logged`) is documented in the artifact itself. Generate your own with `npx bootproof up <repo> --receipt`.
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<a href="https://github.com/bootproof/bootproof/raw/main/assets/living-receipt.html"><img src="https://img.shields.io/badge/download%20the%20Living%20Receipt-%E2%9C%93%20real%20capture%20%C2%B7%20self--verifying-0E9D5B?style=flat-square&labelColor=16181D" alt="Download the Living Receipt"></a>
|
|
23
|
+
<sub>(right-click → Save Link As… → save as <code>.html</code> → double-click to open)</sub>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Quick start: up and verify
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cd /path/to/repository
|
|
32
|
+
npx bootproof up .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
BootProof inspects the repo and either proves it booted or explains why it refused. For explicit local execution with dependency installation:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx bootproof up . --provider local --unsafe-local --install
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Verify a signed attestation:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx bootproof verify .bootproof/attestation.json
|
|
45
|
+
npx bootproof verify . --require-known-signer # CI gating: reject unknown signers
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Receipt Gate: CI and AI agents
|
|
51
|
+
|
|
52
|
+
Receipt Gate is a GitHub Action that blocks PR merges unless BootProof observes a real boot. No proof, no merge.
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
- uses: bootproof/receipt-gate@v1
|
|
56
|
+
with:
|
|
57
|
+
path: .
|
|
58
|
+
require-health: 'true' # default: observed HTTP health required
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Gate your AI agent directly — in `.claude/settings.json`, make the agent hand you a receipt every time it claims done:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"hooks": {
|
|
66
|
+
"Stop": [{
|
|
67
|
+
"hooks": [{
|
|
68
|
+
"type": "command",
|
|
69
|
+
"command": "npx -y bootproof@0.4.0 up . --provider local --unsafe-local --json --timeout 60000 > .bootproof-last.json; node -e \"const r=require('./.bootproof-last.json'); console.log(r.booted && r.healthVerified ? '✅ RECEIPT: work boots and answers' : '❌ NO RECEIPT: ' + (r.failureClass||'boot not observed'));\""
|
|
70
|
+
}]
|
|
71
|
+
}]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
See [`bootproof/receipt-gate`](https://github.com/bootproof/receipt-gate) for the full Action and the agent-hook snippet.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Full command surface
|
|
81
|
+
|
|
82
|
+
### Boot a selected workspace
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx bootproof up . --workspace apps/studio
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Run in CI/machine mode
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx bootproof up . --ci --json
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Verify an existing service
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx bootproof verify-url http://localhost:8001/api/v1/health
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Attach external health to the current repo
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npx bootproof up . --external-health http://localhost:8001/api/v1/health
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Explain an attestation
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npx bootproof explain .bootproof/attestation.json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Static infrastructure diff
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npx bootproof diff --base main --head HEAD
|
|
116
|
+
npx bootproof diff --base main --head HEAD --json
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Export a CycloneDX SBOM
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx bootproof export-sbom .
|
|
123
|
+
npx bootproof export-sbom . --json
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Reads `package-lock.json` and writes `.bootproof/sbom.cdx.json` in CycloneDX 1.5 JSON format. Each top-level dependency in the lockfile becomes a `library` component with a `pkg:npm/{name}@{version}` purl. The application itself is recorded as the `metadata.component`. No transitive resolution is performed beyond what the lockfile already records, and no code is executed to produce the SBOM. Repositories without a `package-lock.json` are refused. The only supported `--format` value is `cyclonedx-json`.
|
|
127
|
+
|
|
128
|
+
### Deterministic repair
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx bootproof fix .
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Optional BYOK AI repair suggestion
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
OPENAI_API_KEY=... npx bootproof fix . --ai
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
or:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
ANTHROPIC_API_KEY=... BOOTPROOF_AI_PROVIDER=anthropic npx bootproof fix . --ai
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`bootproof up` remains zero-AI.
|
|
147
|
+
|
|
148
|
+
### Key rotation
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
bootproof rotate-keys # generate new key, back up old
|
|
152
|
+
bootproof rotate-keys --repo . --resign # also re-sign the latest attestation
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Demos
|
|
158
|
+
|
|
159
|
+
### Supabase-style stack, verified locally
|
|
160
|
+
|
|
161
|
+
BootProof treats a Supabase-style stack as something that must be proved, not assumed. It infers the stack, identifies the boot path, starts the services, verifies localhost health, and writes a signed attestation.
|
|
162
|
+
|
|
163
|
+
<p align="center">
|
|
164
|
+
<img src="assets/bootproof-supabase-demo.gif" alt="BootProof demo verifying a Supabase-style stack" width="900">
|
|
165
|
+
</p>
|
|
166
|
+
|
|
167
|
+
### GitLab-style repo, AI repair gated by proof
|
|
168
|
+
|
|
169
|
+
AI coding agents can suggest commands, but they should not be trusted to declare success. This demo shows the BootProof agent loop: AI suggests a repair, BootProof requires approval, runs one bounded step, reruns verification, and writes a receipt showing what changed.
|
|
6
170
|
|
|
7
171
|
<p align="center">
|
|
8
|
-
<img src="
|
|
172
|
+
<img src="assets/bootproof-gitlab-agent-demo.gif" alt="BootProof demo showing AI repair suggestions gated by proof" width="900">
|
|
9
173
|
</p>
|
|
10
174
|
|
|
11
|
-
|
|
175
|
+
### Living Receipt reproduction
|
|
176
|
+
|
|
177
|
+
The two receipts in the Living Receipt download are real captures from a real `bootproof up` run — one that boots to HTTP 200, and one that segfaults at runtime. Reproduce them:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Using the TypeScript CLI — emits the receipt natively
|
|
181
|
+
npx bootproof up <any-repo> --provider local --unsafe-local --install --receipt
|
|
182
|
+
|
|
183
|
+
# Or use the standalone MVP engine (for development/testing)
|
|
184
|
+
node scripts/bootproof_up.mjs fixtures/real-booting-app --label "real-booting-app"
|
|
185
|
+
|
|
186
|
+
# Regenerate the Living Receipt HTML from MVP captures
|
|
187
|
+
node scripts/build_living_receipt.mjs \
|
|
188
|
+
scripts/records/real-booting-app.json \
|
|
189
|
+
scripts/records/real-slop-app.json \
|
|
190
|
+
--out assets/living-receipt.html
|
|
191
|
+
|
|
192
|
+
# Run the smoke test (verifies both native and fallback paths)
|
|
193
|
+
node scripts/verify_living_receipt.mjs
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The Living Receipt carries PLG hooks: a first-time visitor banner, a "Copy markdown badge" button, a "Download this file" button, and a page-level CTA. See [`assets/bootproof-badge-template.md`](assets/bootproof-badge-template.md) for badge snippets and [`docs/LAUNCH_PLAYBOOK.md`](docs/LAUNCH_PLAYBOOK.md) for the distribution sequence.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Why BootProof exists
|
|
201
|
+
|
|
202
|
+
Every developer knows this loop:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
git clone some/repo
|
|
206
|
+
npm install
|
|
207
|
+
npm run dev
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Then reality appears.
|
|
211
|
+
|
|
212
|
+
Wrong Node version. Wrong pnpm version. Missing Java. Missing Clojure. Docker is running but the service is not healthy. Postgres exists but the role does not. Redis is missing. A migration fails. The app starts but nothing responds. A container is “up” but the product is unusable. An AI agent confidently says “done” because a process started.
|
|
213
|
+
|
|
214
|
+
That is not proof.
|
|
215
|
+
|
|
216
|
+
BootProof exists because repo onboarding should not depend on hope, terminal archaeology, or fake green checks.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## The problem
|
|
221
|
+
|
|
222
|
+
Modern repositories are no longer simple.
|
|
223
|
+
|
|
224
|
+
A repo might contain:
|
|
12
225
|
|
|
13
|
-
|
|
226
|
+
- multiple workspaces
|
|
227
|
+
- Docker Compose services
|
|
228
|
+
- frontend and backend apps
|
|
229
|
+
- hidden runtime requirements
|
|
230
|
+
- package-manager version constraints
|
|
231
|
+
- generated assets
|
|
232
|
+
- database migrations
|
|
233
|
+
- health endpoints
|
|
234
|
+
- undocumented local assumptions
|
|
235
|
+
|
|
236
|
+
A README can be useful, but it is not proof.
|
|
237
|
+
|
|
238
|
+
A terminal command can be useful, but it is not proof.
|
|
239
|
+
|
|
240
|
+
A model response can be useful, but it is not proof.
|
|
241
|
+
|
|
242
|
+
BootProof turns repo booting into an evidence trail.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## The core idea
|
|
247
|
+
|
|
248
|
+
BootProof separates **activity** from **evidence**.
|
|
249
|
+
|
|
250
|
+
| Weak signal | What BootProof wants instead |
|
|
251
|
+
|---|---|
|
|
252
|
+
| command exited | observed health |
|
|
253
|
+
| process started | reachable endpoint |
|
|
254
|
+
| container running | service actually responds |
|
|
255
|
+
| README says it works | repo evidence + runtime proof |
|
|
256
|
+
| AI says it is done | signed attestation |
|
|
257
|
+
| one workspace responded | selected app/workspace proof |
|
|
258
|
+
|
|
259
|
+
A failed run is still useful if it tells the truth.
|
|
14
260
|
|
|
15
261
|
```text
|
|
16
|
-
|
|
262
|
+
✗ NOT VERIFIED — package_manager_version_mismatch
|
|
263
|
+
|
|
264
|
+
What happened:
|
|
265
|
+
The repository requires pnpm 10.24.0, but this environment has pnpm 9.15.4.
|
|
266
|
+
|
|
267
|
+
Why BootProof refused:
|
|
268
|
+
The dependency install cannot be trusted with the wrong package manager version.
|
|
269
|
+
|
|
270
|
+
Safe next step:
|
|
271
|
+
Run corepack enable && corepack prepare pnpm@10.24.0 --activate, then rerun BootProof.
|
|
272
|
+
|
|
273
|
+
Evidence:
|
|
274
|
+
.bootproof/attestation.json
|
|
17
275
|
```
|
|
18
276
|
|
|
19
|
-
|
|
277
|
+
Predictable failure is a feature.
|
|
278
|
+
|
|
279
|
+
---
|
|
20
280
|
|
|
21
|
-
|
|
281
|
+
## Try it on a public Git repo
|
|
282
|
+
|
|
283
|
+
BootProof can inspect public HTTPS repositories from GitHub, GitLab, Bitbucket, and Codeberg.
|
|
22
284
|
|
|
23
285
|
```bash
|
|
24
|
-
bootproof up .
|
|
286
|
+
npx bootproof up https://github.com/dubinc/dub
|
|
25
287
|
```
|
|
26
288
|
|
|
27
|
-
|
|
289
|
+
Remote repositories are untrusted code, so BootProof inspects first and refuses execution until you explicitly opt in.
|
|
290
|
+
|
|
291
|
+
```text
|
|
292
|
+
Remote source: https://github.com/dubinc/dub.git
|
|
293
|
+
Clone retained at: .bootproof/remotes/github.com/dubinc/dub-*/repo
|
|
294
|
+
|
|
295
|
+
Inference
|
|
296
|
+
application: yes
|
|
297
|
+
package manager: pnpm
|
|
298
|
+
selected command: pnpm dev
|
|
299
|
+
|
|
300
|
+
✗ NOT VERIFIED — remote_code_execution_blocked
|
|
28
301
|
|
|
29
|
-
|
|
302
|
+
Why BootProof refused:
|
|
303
|
+
Remote repositories are untrusted code and require explicit consent.
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
To run remote code locally, you must say so explicitly:
|
|
30
307
|
|
|
31
308
|
```bash
|
|
32
|
-
bootproof up . --
|
|
309
|
+
npx bootproof up https://github.com/dubinc/dub --provider local --unsafe-local --install
|
|
33
310
|
```
|
|
34
311
|
|
|
35
|
-
|
|
312
|
+
BootProof never silently executes remote code.
|
|
36
313
|
|
|
37
|
-
|
|
314
|
+
---
|
|
38
315
|
|
|
39
|
-
## What
|
|
316
|
+
## What a successful run looks like
|
|
40
317
|
|
|
41
|
-
|
|
318
|
+
```text
|
|
319
|
+
✓ install: dependencies installed
|
|
320
|
+
✓ start-app: app process started and was supervised
|
|
321
|
+
✓ health: observed HTTP 200 at http://localhost:3333
|
|
322
|
+
|
|
323
|
+
✓ BOOTED — HTTP 200 at http://localhost:3333
|
|
324
|
+
|
|
325
|
+
Evidence:
|
|
326
|
+
.bootproof/attestation.json
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
A repository is only marked `BOOTED` when BootProof observes health evidence.
|
|
330
|
+
|
|
331
|
+
A process start is not enough.
|
|
332
|
+
A successful install is not enough.
|
|
333
|
+
A Docker container is not enough.
|
|
334
|
+
A command exiting is not enough.
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## What BootProof gives humans
|
|
339
|
+
|
|
340
|
+
Humans get a readable diagnosis:
|
|
42
341
|
|
|
43
342
|
```text
|
|
44
|
-
NOT VERIFIED —
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
343
|
+
NOT VERIFIED — workspace_ambiguous
|
|
344
|
+
|
|
345
|
+
BootProof detected a root command that starts multiple workspaces in parallel.
|
|
346
|
+
Choose a specific application with --workspace <dir>; one responding workspace
|
|
347
|
+
is not proof that the whole repository booted.
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Example:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
npx bootproof up . --workspace apps/studio
|
|
49
354
|
```
|
|
50
355
|
|
|
51
|
-
BootProof
|
|
356
|
+
BootProof is designed to make failures legible.
|
|
357
|
+
|
|
358
|
+
It should tell you whether the problem is:
|
|
52
359
|
|
|
53
|
-
|
|
360
|
+
- package-manager mismatch
|
|
361
|
+
- skipped install
|
|
362
|
+
- missing runtime
|
|
363
|
+
- ambiguous workspace
|
|
364
|
+
- unsupported orchestration
|
|
365
|
+
- allocated port
|
|
366
|
+
- failed service
|
|
367
|
+
- failed app start
|
|
368
|
+
- unhealthy endpoint
|
|
369
|
+
- health timeout
|
|
54
370
|
|
|
55
|
-
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## What BootProof gives machines
|
|
374
|
+
|
|
375
|
+
`--json` emits exactly one `bootproof/result/v1` object:
|
|
56
376
|
|
|
57
377
|
```json
|
|
58
378
|
{
|
|
@@ -67,112 +387,438 @@ BootProof distinguishes diagnosis from proof. Detecting Python, Flask, React, Ce
|
|
|
67
387
|
}
|
|
68
388
|
```
|
|
69
389
|
|
|
70
|
-
`--ci` disables colour and interactive
|
|
390
|
+
`--ci` disables colour and interactive prompts.
|
|
391
|
+
|
|
392
|
+
Exit codes are deterministic:
|
|
393
|
+
|
|
394
|
+
| Exit code | Meaning |
|
|
395
|
+
|---:|---|
|
|
396
|
+
| `0` | `booted === true` and `healthVerified === true` |
|
|
397
|
+
| `1` | refusal, ambiguity, install failure, app failure, service failure, or health failure |
|
|
398
|
+
|
|
399
|
+
That makes BootProof useful for CI, agent workflows, and repo-quality gates.
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Real repo evidence
|
|
404
|
+
|
|
405
|
+
BootProof has been tested against real repositories, including small apps, monorepos, large platforms, and multi-service stacks.
|
|
406
|
+
|
|
407
|
+
The point is not to turn every repo green. The point is to produce the correct verdict.
|
|
71
408
|
|
|
72
|
-
|
|
73
|
-
|
|
409
|
+
| Repository | Result | What it proved |
|
|
410
|
+
|---|---|---|
|
|
411
|
+
| `dubinc/dub` | `NOT VERIFIED — remote_code_execution_blocked` | BootProof inspected the repo but refused to execute remote code without explicit consent. |
|
|
412
|
+
| `makeplane/plane` | useful monorepo path | BootProof handled a more complex workspace-style repo and produced actionable evidence. |
|
|
413
|
+
| `airbytehq/airbyte` | refused direct orchestration, then externally verified | Airbyte required `abctl`, Kind, Helm and a documented local path. BootProof refused to pretend a normal command was enough, then verified the external health endpoint. |
|
|
414
|
+
| `gitlabhq/gitlabhq` | manual boot loop exposed hidden environment assumptions | GitLab showed why large repos need evidence trails rather than README optimism. |
|
|
415
|
+
| `metabase/metabase` | backend health reached, frontend missing | Metabase showed the difference between “backend is alive” and “full UI booted”. |
|
|
416
|
+
| `supabase/supabase` | `workspace_ambiguous`; manual Compose platform boot | BootProof correctly refused a fake monorepo-wide green check. The official Docker Compose path booted core services, proving the need for explicit full-platform compose mode. |
|
|
74
417
|
|
|
75
|
-
|
|
418
|
+
Failure is not hidden or relabelled as support.
|
|
76
419
|
|
|
77
|
-
|
|
420
|
+
Evidence stays evidence.
|
|
421
|
+
|
|
422
|
+
See [docs/REAL_REPO_EVIDENCE.md](docs/REAL_REPO_EVIDENCE.md).
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Supabase example: why honest failure matters
|
|
427
|
+
|
|
428
|
+
A fresh BootProof run against `supabase/supabase` detected:
|
|
429
|
+
|
|
430
|
+
```text
|
|
431
|
+
stack: make-driven, node-frontend, docker-compose
|
|
432
|
+
repo compose: docker/docker-compose.yml
|
|
433
|
+
workspaces: apps/studio, apps/www, apps/docs, packages/*
|
|
434
|
+
selected command: make dev
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
BootProof refused:
|
|
438
|
+
|
|
439
|
+
```text
|
|
440
|
+
✗ NOT VERIFIED — workspace_ambiguous
|
|
441
|
+
|
|
442
|
+
The root command starts multiple workspaces in parallel.
|
|
443
|
+
One responding workspace would not prove that the whole repository booted.
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
That refusal is correct.
|
|
447
|
+
|
|
448
|
+
Manual follow-up through Supabase’s official Docker route proved the platform path:
|
|
78
449
|
|
|
79
450
|
```bash
|
|
80
|
-
cd
|
|
81
|
-
|
|
451
|
+
cd docker
|
|
452
|
+
cp .env.example .env
|
|
453
|
+
docker compose up -d
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Core services such as Kong, Studio, DB, Auth, REST and Pooler reported healthy/running, and `localhost:8000` returned Kong/API responses.
|
|
457
|
+
|
|
458
|
+
The lesson:
|
|
459
|
+
|
|
460
|
+
> BootProof should not fake a monorepo-wide success just because one endpoint responds.
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Airbyte example: external verification
|
|
465
|
+
|
|
466
|
+
Airbyte correctly exceeded BootProof’s direct orchestration boundary.
|
|
467
|
+
|
|
468
|
+
BootProof refused instead of pretending a normal Gradle, Make, or Compose command was enough. The documented local path required `abctl`, Kind and Helm. A human followed that runbook and booted the application.
|
|
469
|
+
|
|
470
|
+
BootProof could then verify the external health endpoint without claiming it started Airbyte.
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
bootproof verify-url http://localhost:8001/api/v1/health
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
External verification means:
|
|
477
|
+
|
|
478
|
+
```text
|
|
479
|
+
This endpoint responded.
|
|
480
|
+
BootProof did not orchestrate the startup.
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
That distinction matters.
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
## Verifying attestations: signer tiers
|
|
488
|
+
|
|
489
|
+
Signature verification reports one of three local signer tiers:
|
|
490
|
+
|
|
491
|
+
- `this machine`: the artifact was signed by `~/.bootproof/signer.json`;
|
|
492
|
+
- `known`: the signer was explicitly pinned in `~/.bootproof/known_signers.json`;
|
|
493
|
+
- `UNKNOWN`: the signature is intact, but it proves integrity only and the signer is not trusted.
|
|
494
|
+
|
|
495
|
+
Unknown foreign signers are never pinned automatically. To deliberately trust an intact
|
|
496
|
+
foreign signer, review the printed SHA-256 SPKI fingerprint and run:
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
npx bootproof verify proof.json --trust-signer
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Use `--require-known-signer` for CI gating. When verification targets a repository directory,
|
|
503
|
+
BootProof also compares the attested commit with the repository's current `HEAD`; `--strict`
|
|
504
|
+
fails on either an unknown signer or a commit mismatch. A valid signature proves the artifact
|
|
505
|
+
was not altered after signing. It does not, by itself, prove who produced it.
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
## The agent-in-the-loop model
|
|
510
|
+
|
|
511
|
+
BootProof is built for a world where humans and AI agents both touch repositories.
|
|
512
|
+
|
|
513
|
+
The intended loop is:
|
|
514
|
+
|
|
515
|
+
```text
|
|
516
|
+
Diagnose
|
|
517
|
+
→ Classify
|
|
518
|
+
→ Plan
|
|
519
|
+
→ Risk-classify
|
|
520
|
+
→ Approve
|
|
521
|
+
→ Execute one step
|
|
522
|
+
→ Verify
|
|
523
|
+
→ Receipt
|
|
524
|
+
→ Repeat
|
|
82
525
|
```
|
|
83
526
|
|
|
84
|
-
|
|
527
|
+
AI can suggest.
|
|
528
|
+
Humans can approve.
|
|
529
|
+
BootProof proves.
|
|
530
|
+
|
|
531
|
+
The complete autonomous loop is not implemented. Today BootProof exposes four honest modes.
|
|
532
|
+
|
|
533
|
+
### 1. Direct orchestration
|
|
85
534
|
|
|
86
535
|
```bash
|
|
87
|
-
|
|
536
|
+
bootproof up .
|
|
88
537
|
```
|
|
89
538
|
|
|
90
|
-
|
|
539
|
+
BootProof infers a supported local run path, executes it within the selected safety boundary, observes health, and writes an attestation.
|
|
540
|
+
|
|
541
|
+
Unsupported or ambiguous orchestration is refused.
|
|
542
|
+
|
|
543
|
+
### 2. External verification
|
|
91
544
|
|
|
92
545
|
```bash
|
|
93
|
-
|
|
546
|
+
bootproof verify-url http://localhost:8001/api/v1/health
|
|
94
547
|
```
|
|
95
548
|
|
|
96
|
-
|
|
549
|
+
BootProof observes a service started outside BootProof. Successful evidence is classified as externally verified and never claims BootProof started the app.
|
|
550
|
+
|
|
551
|
+
### 3. Agent planning
|
|
97
552
|
|
|
98
553
|
```bash
|
|
99
|
-
|
|
100
|
-
npx bootproof verify .bootproof/attestation.json
|
|
554
|
+
bootproof plan-agent .
|
|
101
555
|
```
|
|
102
556
|
|
|
103
|
-
|
|
557
|
+
BootProof writes a deterministic, risk-classified plan and a redacted local receipt chain. It does not execute candidate actions, and planning never counts as success.
|
|
558
|
+
|
|
559
|
+
### 4. Deterministic repair
|
|
104
560
|
|
|
105
561
|
```bash
|
|
106
|
-
|
|
562
|
+
bootproof fix .
|
|
107
563
|
```
|
|
108
564
|
|
|
109
|
-
BootProof
|
|
565
|
+
BootProof maps exact known failures to deterministic repair actions. Mutating commands and patches require explicit approval. Verification decides whether the failure progressed or the application booted.
|
|
566
|
+
|
|
567
|
+
See:
|
|
568
|
+
|
|
569
|
+
- [docs/AGENT_IN_THE_LOOP.md](docs/AGENT_IN_THE_LOOP.md)
|
|
570
|
+
- [docs/AGENT_RUN_RECEIPTS.md](docs/AGENT_RUN_RECEIPTS.md)
|
|
571
|
+
- [docs/DETERMINISTIC_REPAIR_SAFETY_MODEL.md](docs/DETERMINISTIC_REPAIR_SAFETY_MODEL.md)
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
## Deterministic repair
|
|
576
|
+
|
|
577
|
+
`bootproof fix` reads the latest signature-valid classified failure and maps exact known failures to deterministic actions.
|
|
110
578
|
|
|
111
579
|
```bash
|
|
112
|
-
|
|
580
|
+
bootproof fix .
|
|
113
581
|
```
|
|
114
582
|
|
|
115
|
-
|
|
583
|
+
Host and service commands show the exact command, scope and risk. They run only when the user gives explicit approval. JSON and CI modes never approve commands.
|
|
584
|
+
|
|
585
|
+
Repair receipts distinguish:
|
|
586
|
+
|
|
587
|
+
- declined
|
|
588
|
+
- failed
|
|
589
|
+
- progressed
|
|
590
|
+
- verified
|
|
116
591
|
|
|
117
|
-
|
|
592
|
+
Machine mode:
|
|
118
593
|
|
|
119
|
-
|
|
594
|
+
```bash
|
|
595
|
+
bootproof fix . --json
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
It emits one `bootproof/repair-result/v1` object and exits `0` only when a verified receipt exists.
|
|
120
599
|
|
|
121
|
-
|
|
600
|
+
`fix` never applies file patches directly. To explicitly apply a signature-valid file repair to a local working tree:
|
|
601
|
+
|
|
602
|
+
```bash
|
|
603
|
+
bootproof apply-repair .
|
|
604
|
+
```
|
|
122
605
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
606
|
+
Application checks the receipt signature, allowed file scope, signed content hashes, and exact current preimages before writing.
|
|
607
|
+
|
|
608
|
+
See [docs/REPAIR_RECEIPT.md](docs/REPAIR_RECEIPT.md).
|
|
609
|
+
|
|
610
|
+
---
|
|
611
|
+
|
|
612
|
+
## Optional BYOK AI
|
|
613
|
+
|
|
614
|
+
AI suggestions are optional and are only available after no deterministic repair is known.
|
|
615
|
+
|
|
616
|
+
```bash
|
|
617
|
+
OPENAI_API_KEY=... bootproof fix . --ai
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
or:
|
|
621
|
+
|
|
622
|
+
```bash
|
|
623
|
+
ANTHROPIC_API_KEY=... BOOTPROOF_AI_PROVIDER=anthropic bootproof fix . --ai
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
BootProof asks before contacting the provider, sends only redacted structured failure evidence, validates the strict `bootproof/ai-repair-suggestion/v1` response through the shared safety model, and asks again before any command or patch is tested.
|
|
627
|
+
|
|
628
|
+
AI suggestions are recorded as `ai_suggested`.
|
|
629
|
+
|
|
630
|
+
They never enter the deterministic registry automatically.
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
## Static infrastructure diff
|
|
635
|
+
|
|
636
|
+
```bash
|
|
637
|
+
bootproof diff --base main --head feature-branch
|
|
638
|
+
bootproof diff --base main --head HEAD --json
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
`diff` reads committed Git objects and performs static analysis only.
|
|
642
|
+
|
|
643
|
+
It does not:
|
|
644
|
+
|
|
645
|
+
- check out either ref
|
|
646
|
+
- execute repository code
|
|
647
|
+
- install dependencies
|
|
648
|
+
- read protected `.env` contents
|
|
649
|
+
- upload data
|
|
650
|
+
|
|
651
|
+
It reports supported drift in:
|
|
652
|
+
|
|
653
|
+
- dependency manifests and lockfiles
|
|
654
|
+
- Compose services and ports
|
|
655
|
+
- environment variable names
|
|
656
|
+
- start commands
|
|
657
|
+
- package managers
|
|
658
|
+
- runtime markers
|
|
659
|
+
- detectable health routes
|
|
660
|
+
|
|
661
|
+
A diff can require fresh proof, but it never claims the head revision boots. Run `bootproof up` against the intended revision to establish that with observed health evidence.
|
|
662
|
+
|
|
663
|
+
---
|
|
664
|
+
|
|
665
|
+
## Honesty contract
|
|
666
|
+
|
|
667
|
+
BootProof is constrained on purpose.
|
|
668
|
+
|
|
669
|
+
It will not:
|
|
670
|
+
|
|
671
|
+
- mark a repo `BOOTED` without observed health
|
|
672
|
+
- execute remote code without explicit consent
|
|
673
|
+
- fall back from Docker to host execution silently
|
|
674
|
+
- render skipped steps as success
|
|
675
|
+
- invent secrets
|
|
676
|
+
- write protected `.env` files
|
|
677
|
+
- silently patch project code
|
|
678
|
+
- guess a workspace when the repo is ambiguous
|
|
679
|
+
- claim generated scaffolding exists unless it was written
|
|
680
|
+
- upload telemetry or hidden evidence
|
|
681
|
+
|
|
682
|
+
It will:
|
|
683
|
+
|
|
684
|
+
- sign successful attestations
|
|
685
|
+
- sign failed attestations
|
|
686
|
+
- preserve local evidence
|
|
687
|
+
- classify known failures
|
|
688
|
+
- refuse unsupported paths clearly
|
|
133
689
|
|
|
134
690
|
See [docs/HONESTY_CONTRACT.md](docs/HONESTY_CONTRACT.md).
|
|
135
691
|
|
|
136
|
-
|
|
692
|
+
---
|
|
693
|
+
|
|
694
|
+
## Safety model
|
|
695
|
+
|
|
696
|
+
### Execution isolation (read this before running on a repo you don't trust)
|
|
697
|
+
|
|
698
|
+
BootProof's execution model is **honest by default, not isolated by default**. There is no general-purpose container sandbox in the current release. Here is exactly what happens when you run `bootproof up`:
|
|
699
|
+
|
|
700
|
+
- **Default (`--provider docker`)**: BootProof will only execute inside Docker for **source-built Compose applications** (repos with a `docker-compose.yml` where the app service is built from source). For every other repo — plain Node, Python, Rust, Go — the Docker provider **refuses to run** with `orchestration_not_supported` rather than silently falling back to the host. This is intentional: the default is fail-closed, not silent host execution.
|
|
701
|
+
- **`--provider local --unsafe-local`**: runs install and start commands **directly on your host machine** using `spawn(command, { shell: true })`. There is no container, no network restriction, no read-only filesystem. The `--unsafe-local` flag is the explicit consent gate — you are acknowledging that you have reviewed the inferred commands and accept that the repo's code (including `postinstall` scripts, `prestart` hooks, and anything the start command does) will run on your machine with your privileges.
|
|
702
|
+
- **Remote repos** (`bootproof up https://github.com/...`): BootProof clones for inspection but **refuses to execute** without `--provider local --unsafe-local`. Inspection is safe; execution requires consent.
|
|
703
|
+
|
|
704
|
+
**Before running `bootproof up --provider local --unsafe-local` on a repo you didn't write:**
|
|
705
|
+
1. Run `bootproof up <repo> --dry-run` first to see the inferred commands without executing them.
|
|
706
|
+
2. Read the plan. The install command and start command will run on your host.
|
|
707
|
+
3. Only then add `--unsafe-local --install` to actually execute.
|
|
708
|
+
|
|
709
|
+
This is the current truth. General-purpose Docker isolation for non-Compose repos is on the roadmap but is not in this release. If that's a blocker for your use case, do not use BootProof on untrusted repos yet.
|
|
710
|
+
|
|
711
|
+
### Repair safety
|
|
712
|
+
|
|
713
|
+
BootProof treats repair actions as executable risk.
|
|
714
|
+
|
|
715
|
+
The repair safety model blocks or escalates dangerous commands before they run.
|
|
716
|
+
|
|
717
|
+
Blocked examples include:
|
|
718
|
+
|
|
719
|
+
- `sudo`
|
|
720
|
+
- shell interpreters
|
|
721
|
+
- pipe-to-shell downloads such as `curl | sh`
|
|
722
|
+
- inline arbitrary execution such as `node -e`, `python -c`, `ruby -e`
|
|
723
|
+
- recursive world-writable chmod
|
|
724
|
+
- raw disk writes
|
|
725
|
+
- destructive database drops
|
|
726
|
+
- protected `.env` writes
|
|
727
|
+
- secret exfiltration patterns
|
|
728
|
+
|
|
729
|
+
High-risk actions require explicit approval and can never be downgraded by AI-provided risk labels.
|
|
730
|
+
|
|
731
|
+
See [docs/DETERMINISTIC_REPAIR_SAFETY_MODEL.md](docs/DETERMINISTIC_REPAIR_SAFETY_MODEL.md).
|
|
732
|
+
|
|
733
|
+
---
|
|
734
|
+
|
|
735
|
+
## Current capabilities
|
|
137
736
|
|
|
138
737
|
BootProof currently provides:
|
|
139
738
|
|
|
140
739
|
- Node package-manager and start-command inference
|
|
141
|
-
- Python/Flask and Go/Node hybrid detection
|
|
142
740
|
- monorepo candidate ranking
|
|
143
|
-
- Docker service dependency detection
|
|
144
|
-
-
|
|
741
|
+
- Docker service dependency detection
|
|
742
|
+
- repository Compose detection
|
|
743
|
+
- conservative Go main-package execution
|
|
744
|
+
- Rails `bin/rails` entrypoint detection
|
|
745
|
+
- explicit Make run-target execution
|
|
746
|
+
- Python/Flask and Go/Node hybrid detection
|
|
747
|
+
- localhost health-candidate discovery from repo evidence and app logs
|
|
145
748
|
- classified failures
|
|
146
749
|
- signed Ed25519 attestations
|
|
147
750
|
- strict JSON and fail-closed CI output
|
|
148
751
|
- redacted registry-entry export
|
|
752
|
+
- deterministic sandboxed repairs for registered failure classes
|
|
753
|
+
- explicit repair application with signature, scope and stale-preimage checks
|
|
754
|
+
- static infrastructure diff
|
|
755
|
+
|
|
756
|
+
Detection is broader than orchestration. BootProof may detect a stack and still refuse to run it if the proof boundary is not safe or clear.
|
|
757
|
+
|
|
758
|
+
---
|
|
759
|
+
|
|
760
|
+
## Supported entrypoints
|
|
761
|
+
|
|
762
|
+
Supported execution paths are deliberately narrow.
|
|
763
|
+
|
|
764
|
+
| Type | Supported path |
|
|
765
|
+
|---|---|
|
|
766
|
+
| Node | package manager + selected start/dev script |
|
|
767
|
+
| Go | exactly one `main.go` or `cmd/*/main.go` |
|
|
768
|
+
| Ruby/Rails | `Gemfile` plus `bin/rails` |
|
|
769
|
+
| Make | explicit `run`, `serve`, `server`, `start`, or `dev` target |
|
|
770
|
+
| Compose | repository-local build context with published HTTP port |
|
|
771
|
+
|
|
772
|
+
Each path still requires observed health.
|
|
773
|
+
|
|
774
|
+
A successful `docker compose up -d`, process spawn, or command exit is not a green result by itself.
|
|
775
|
+
|
|
776
|
+
---
|
|
777
|
+
|
|
778
|
+
## Failure taxonomy
|
|
779
|
+
|
|
780
|
+
Common failure classes include:
|
|
781
|
+
|
|
782
|
+
- `not_an_application`
|
|
783
|
+
- `workspace_ambiguous`
|
|
784
|
+
- `dependency_install_skipped`
|
|
785
|
+
- `package_manager_version_mismatch`
|
|
786
|
+
- `python_flask_setup_required`
|
|
787
|
+
- `service_port_allocated`
|
|
788
|
+
- `postgres_auth_env_missing`
|
|
789
|
+
- `health_http_error`
|
|
790
|
+
- `health_check_timeout`
|
|
791
|
+
- `remote_code_execution_blocked`
|
|
792
|
+
- `unknown_failure`
|
|
793
|
+
|
|
794
|
+
Unknown failures remain unknown, with evidence preserved for the next detector.
|
|
149
795
|
|
|
150
|
-
|
|
796
|
+
See [docs/FAILURE_TAXONOMY.md](docs/FAILURE_TAXONOMY.md).
|
|
151
797
|
|
|
152
|
-
|
|
153
|
-
- Grafana-like Go/Node hybrids are detected without pretending a frontend watcher is the whole application.
|
|
154
|
-
- Parallel monorepo root commands are refused until a specific workspace is selected.
|
|
798
|
+
---
|
|
155
799
|
|
|
156
|
-
## Files
|
|
800
|
+
## Files BootProof may write
|
|
157
801
|
|
|
158
|
-
Depending on the observed plan, BootProof may write:
|
|
802
|
+
Depending on the command and observed plan, BootProof may write:
|
|
159
803
|
|
|
160
804
|
```text
|
|
161
805
|
.bootproof/attestation.json
|
|
162
806
|
.bootproof/registry-entry.json
|
|
807
|
+
.bootproof/registry/<timestamp>-<hash>.json
|
|
808
|
+
.bootproof/runtime/
|
|
163
809
|
docker-compose.bootproof.yml
|
|
164
810
|
.env.bootproof.example
|
|
165
811
|
```
|
|
166
812
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Docker and env guidance files are listed in proof only when BootProof actually generated them.
|
|
813
|
+
Registry artifacts are written only by explicit export commands.
|
|
170
814
|
|
|
171
815
|
Protected application env files remain untouched.
|
|
172
816
|
|
|
173
|
-
|
|
817
|
+
---
|
|
174
818
|
|
|
175
|
-
|
|
819
|
+
## Attestation trust
|
|
820
|
+
|
|
821
|
+
Local attestations (the default) contain:
|
|
176
822
|
|
|
177
823
|
```json
|
|
178
824
|
{
|
|
@@ -184,67 +830,181 @@ Current attestations contain:
|
|
|
184
830
|
}
|
|
185
831
|
```
|
|
186
832
|
|
|
187
|
-
|
|
833
|
+
The embedded trust value is an attested claim, not an external identity proof. Local
|
|
834
|
+
verification separately classifies the signer as this machine, explicitly known, or unknown
|
|
835
|
+
foreign. Repair receipts and registry entries use the same signer tiers.
|
|
188
836
|
|
|
189
|
-
|
|
837
|
+
Local attestations are useful evidence. CI/OIDC attestations are stronger supply-chain proof.
|
|
838
|
+
Cryptographic authorship binding through keyless/OIDC is intentionally deferred to the
|
|
839
|
+
CI/Action work. BootProof does not pretend local laptop proof is enterprise CI proof.
|
|
190
840
|
|
|
191
|
-
|
|
841
|
+
### CI OIDC signing
|
|
192
842
|
|
|
193
|
-
|
|
843
|
+
Inside GitHub Actions with `permissions: id-token: write`, pass `--ci-oidc` to fetch the runner's OIDC token and embed its claims in the attestation:
|
|
194
844
|
|
|
195
|
-
|
|
196
|
-
-
|
|
197
|
-
|
|
198
|
-
- `package_manager_version_mismatch`
|
|
199
|
-
- `python_flask_setup_required`
|
|
200
|
-
- `service_port_allocated`
|
|
201
|
-
- `postgres_auth_env_missing`
|
|
202
|
-
- `health_http_error`
|
|
203
|
-
- `health_check_timeout`
|
|
204
|
-
- `unknown_failure`
|
|
845
|
+
```bash
|
|
846
|
+
bootproof up . --provider local --unsafe-local --ci-oidc
|
|
847
|
+
```
|
|
205
848
|
|
|
206
|
-
|
|
849
|
+
The attestation then carries `ci_oidc_signed` trust with the OIDC claims:
|
|
207
850
|
|
|
208
|
-
|
|
851
|
+
```json
|
|
852
|
+
{
|
|
853
|
+
"trust": {
|
|
854
|
+
"level": "ci_oidc_signed",
|
|
855
|
+
"signer": "local_ed25519",
|
|
856
|
+
"oidc": {
|
|
857
|
+
"iss": "https://token.actions.githubusercontent.com",
|
|
858
|
+
"sub": "repo:bootproof/bootproof:ref:refs/heads/main",
|
|
859
|
+
"repository": "bootproof/bootproof",
|
|
860
|
+
"run_id": "123456",
|
|
861
|
+
"workflow": "CI",
|
|
862
|
+
"job_workflow_ref": "bootproof/bootproof/.github/workflows/ci.yml@refs/heads/main"
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
```
|
|
209
867
|
|
|
210
|
-
|
|
868
|
+
The ed25519 signature still provides integrity; the OIDC evidence provides CI provenance. A verifier can independently validate both the signature and the OIDC claims. The `neutral_runner_signed` and `transparency_logged` levels remain on the roadmap.
|
|
211
869
|
|
|
212
|
-
|
|
870
|
+
### Key rotation
|
|
213
871
|
|
|
214
|
-
|
|
872
|
+
The local signing key can be rotated without invalidating existing attestations (each carries its public key inline and verifies independently):
|
|
873
|
+
|
|
874
|
+
```bash
|
|
875
|
+
bootproof rotate-keys # generate new key, back up old
|
|
876
|
+
bootproof rotate-keys --repo . --resign # also re-sign the latest attestation
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
Old keys are archived to `~/.bootproof/archived-keys/` so existing attestations remain verifiable.
|
|
880
|
+
|
|
881
|
+
### What the local key does and does not protect
|
|
882
|
+
|
|
883
|
+
The local signing key lives at `~/.bootproof/signer.json` (0600 permissions; the `~/.bootproof/` directory is 0700). Pinned foreign signers are stored in `~/.bootproof/known_signers.json` (also 0600). Archived keys from rotation are stored in `~/.bootproof/archived-keys/` (0600).
|
|
884
|
+
|
|
885
|
+
The key protects **integrity**: a valid ed25519 signature proves the attestation was not altered after signing. It does not protect **authorship**: anyone who obtains this key file can sign attestations that will verify as "this machine." If the key is compromised, `bootproof rotate-keys` generates a new keypair and archives the old one — but existing attestations signed by the compromised key will still verify as intact (they carry the old public key inline). Rotation prevents future compromise; it does not revoke past signatures.
|
|
886
|
+
|
|
887
|
+
`local_developer_signed` has **no revocation mechanism**. There is no key revocation server, no CRL, no OCSP responder. The trust ladder (`local_developer_signed` → `ci_oidc_signed` → `neutral_runner_signed` → `transparency_logged`) is the mitigation, not a hidden feature: higher rungs bind signatures to external identities (OIDC, neutral runners, transparency logs) that are harder to forge than a local key file. A verifier who requires `--require-known-signer` rejects any signer not explicitly pinned, which limits the blast radius of a compromised key to the set of pinned keys.
|
|
888
|
+
|
|
889
|
+
---
|
|
890
|
+
|
|
891
|
+
## CI and registry
|
|
215
892
|
|
|
216
|
-
|
|
893
|
+
BootProof does not upload attestations.
|
|
217
894
|
|
|
218
|
-
|
|
895
|
+
A project can deliberately export a redacted local registry entry or federated public-candidate receipt and review it before committing it.
|
|
219
896
|
|
|
220
|
-
|
|
897
|
+
```bash
|
|
898
|
+
bootproof registry export .
|
|
899
|
+
bootproof attest export .
|
|
900
|
+
bootproof registry export . --federated
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
Public crawler, private cloud upload, and OIDC-backed trust are future integrations, not deployed services in this repository.
|
|
904
|
+
|
|
905
|
+
See:
|
|
221
906
|
|
|
222
907
|
- [docs/CI_ACTION.md](docs/CI_ACTION.md)
|
|
223
908
|
- [docs/REGISTRY.md](docs/REGISTRY.md)
|
|
224
909
|
|
|
225
|
-
|
|
910
|
+
---
|
|
226
911
|
|
|
227
|
-
|
|
912
|
+
## Open-source boundary
|
|
228
913
|
|
|
229
|
-
|
|
914
|
+
This repository contains the local trust layer:
|
|
230
915
|
|
|
231
|
-
|
|
916
|
+
- local diagnosis
|
|
917
|
+
- local planning
|
|
918
|
+
- local receipts
|
|
919
|
+
- local approvals
|
|
920
|
+
- optional BYOK AI suggestions
|
|
921
|
+
- deterministic repair safety
|
|
922
|
+
- no telemetry
|
|
923
|
+
- no automatic upload
|
|
232
924
|
|
|
233
|
-
|
|
925
|
+
The OSS engine works offline and does not require BootProof Cloud.
|
|
234
926
|
|
|
235
|
-
|
|
927
|
+
---
|
|
236
928
|
|
|
237
|
-
|
|
929
|
+
## Cloud boundary
|
|
238
930
|
|
|
239
|
-
|
|
240
|
-
|
|
931
|
+
BootProof Cloud belongs in a separate private repository.
|
|
932
|
+
|
|
933
|
+
Its boundary includes future hosted capabilities such as:
|
|
934
|
+
|
|
935
|
+
- hosted AI
|
|
936
|
+
- shared registry
|
|
937
|
+
- team approval workflows
|
|
938
|
+
- GitHub App
|
|
939
|
+
- SSO/RBAC
|
|
940
|
+
- policy
|
|
941
|
+
- fleet dashboards
|
|
942
|
+
- audit retention
|
|
943
|
+
|
|
944
|
+
These are product boundaries, not claims that those services are implemented in this public repository.
|
|
945
|
+
|
|
946
|
+
No Cloud/SaaS code is included here.
|
|
947
|
+
|
|
948
|
+
---
|
|
949
|
+
|
|
950
|
+
## Release packaging
|
|
951
|
+
|
|
952
|
+
The npm package contains the compiled CLI, license, README and docs.
|
|
953
|
+
|
|
954
|
+
`dist/` is required at runtime, generated by `npm run build` during `prepack`, and intentionally not committed.
|
|
955
|
+
|
|
956
|
+
Run:
|
|
957
|
+
|
|
958
|
+
```bash
|
|
959
|
+
npm run pack:check
|
|
241
960
|
```
|
|
242
961
|
|
|
243
|
-
|
|
962
|
+
This packs BootProof, installs the tarball in an isolated temporary directory, and exercises the installed CLI.
|
|
963
|
+
|
|
964
|
+
See [docs/RELEASE_CHECKLIST.md](docs/RELEASE_CHECKLIST.md).
|
|
965
|
+
|
|
966
|
+
---
|
|
244
967
|
|
|
245
|
-
|
|
968
|
+
## Development
|
|
246
969
|
|
|
247
|
-
|
|
970
|
+
For contributors working from source:
|
|
971
|
+
|
|
972
|
+
```bash
|
|
973
|
+
git clone https://github.com/bootproof/bootproof.git
|
|
974
|
+
cd bootproof
|
|
975
|
+
npm ci
|
|
976
|
+
npm run build
|
|
977
|
+
npm test
|
|
978
|
+
npm link
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
Then from another repository:
|
|
982
|
+
|
|
983
|
+
```bash
|
|
984
|
+
bootproof up .
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
Generated files such as `dist/`, `node_modules/`, and `.DS_Store` are ignored and not committed.
|
|
988
|
+
|
|
989
|
+
---
|
|
990
|
+
|
|
991
|
+
## What BootProof is not
|
|
992
|
+
|
|
993
|
+
BootProof is not:
|
|
994
|
+
|
|
995
|
+
- a deployment platform
|
|
996
|
+
- a general CI replacement
|
|
997
|
+
- a magic environment fixer
|
|
998
|
+
- an AI coding agent
|
|
999
|
+
- a guarantee that every repo can be run automatically
|
|
1000
|
+
- a cloud product hidden inside an OSS repo
|
|
1001
|
+
- a sandbox or container runtime — `--provider local` runs code on your host; `--provider docker` only isolates source-built Compose apps
|
|
1002
|
+
|
|
1003
|
+
BootProof is the honest run button for repos.
|
|
1004
|
+
|
|
1005
|
+
It runs what it can, refuses what it cannot prove, signs both success and failure, and gives humans and machines the same evidence.
|
|
1006
|
+
|
|
1007
|
+
---
|
|
248
1008
|
|
|
249
1009
|
## Status
|
|
250
1010
|
|
|
@@ -252,14 +1012,18 @@ BootProof is early alpha.
|
|
|
252
1012
|
|
|
253
1013
|
Near-term work includes:
|
|
254
1014
|
|
|
255
|
-
-
|
|
256
|
-
- stronger multi-service
|
|
257
|
-
- broader
|
|
1015
|
+
- explicit full-platform Compose mode
|
|
1016
|
+
- stronger multi-service health modelling
|
|
1017
|
+
- broader deterministic remediation coverage
|
|
1018
|
+
- more Python, Go, Ruby and Make entrypoints
|
|
258
1019
|
- CI/OIDC-backed signing
|
|
259
|
-
- proof-linked badges
|
|
1020
|
+
- proof-linked badges
|
|
1021
|
+
- verified public evidence index
|
|
260
1022
|
|
|
261
1023
|
Unsupported paths should fail clearly, not magically.
|
|
262
1024
|
|
|
1025
|
+
---
|
|
1026
|
+
|
|
263
1027
|
## License
|
|
264
1028
|
|
|
265
1029
|
Apache-2.0
|