File size: 13,318 Bytes
f74bce1
 
 
 
 
 
 
 
 
 
 
6b7b99b
7098eeb
f74bce1
 
 
 
 
 
2f1532d
f74bce1
7700633
 
 
2608b33
f74bce1
 
a7f491e
f74bce1
 
52b556c
7700633
f74bce1
 
 
 
 
25cdc14
f74bce1
1a3dda6
f74bce1
 
 
 
 
 
 
 
 
 
 
6b7b99b
7098eeb
f74bce1
 
 
 
 
 
 
2f1532d
f74bce1
7700633
 
 
2608b33
f74bce1
 
a7f491e
f74bce1
 
52b556c
7700633
f74bce1
 
 
 
 
25cdc14
f74bce1
1a3dda6
f74bce1
 
 
 
 
 
 
 
d598e49
 
f74bce1
 
 
 
 
2f1532d
6b7b99b
7098eeb
f54fafa
f74bce1
f54fafa
f74bce1
 
74ee21a
f74bce1
 
f54fafa
f74bce1
 
 
f54fafa
f74bce1
 
f54fafa
f74bce1
54d801e
 
 
 
 
 
 
 
a7f491e
 
 
 
 
 
 
 
 
 
54d801e
a7f491e
 
 
f74bce1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6b7b99b
f74bce1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fc9f64b
 
 
 
 
 
 
347a4d6
f74bce1
 
 
 
 
 
74ee21a
14a02b9
 
 
 
74ee21a
 
14a02b9
 
 
fc9f64b
f74bce1
 
fc9f64b
 
 
f74bce1
 
74ee21a
14a02b9
 
 
 
74ee21a
 
14a02b9
 
 
fc9f64b
f74bce1
 
 
 
fc9f64b
f74bce1
fc9f64b
f74bce1
 
74ee21a
f74bce1
 
 
fc9f64b
f74bce1
 
 
 
 
 
 
 
 
 
 
2f1532d
6b7b99b
f54fafa
f74bce1
f54fafa
f74bce1
 
 
dadf64c
f74bce1
7700633
f74bce1
 
7700633
 
 
 
 
 
2608b33
f74bce1
1a3dda6
4e3dd84
 
 
 
 
 
 
f74bce1
 
 
 
 
 
 
4e3dd84
 
 
 
 
 
 
 
 
 
 
f74bce1
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
# Verification Runbook

Use this runbook before recording the final demo and again before Devpost submission.

## Local Checks

```bash
python3.11 -m venv .venv
. .venv/bin/activate
pip install -e ".[dev,integrations]"
python scripts/check_integrations.py
python scripts/genblaze_contract_check.py
python scripts/docker_smoke.py
ruff check .
pytest
python scripts/secret_scan.py
python scripts/claim_lint.py
python scripts/live_env_handoff.py
python scripts/final_env_wizard.py --check-only
python scripts/b2_key_scope_checklist.py
python scripts/devpost_form_kit.py
python scripts/devpost_submission_checklist.py
python scripts/judge_brief.py
python scripts/judge_crosswalk.py
python scripts/judge_decision_brief.py
python scripts/devpost_event_snapshot.py --validate-committed
python scripts/agent_handoff_check.py
python scripts/public_space_upload.py
python scripts/public_space_sync.py
python scripts/demo_storyboard.py
python scripts/demo_video_draft.py
python scripts/public_video_check.py
python scripts/sponsor_fit_audit.py
python scripts/demo_readiness.py
python scripts/recording_assets.py
python scripts/award_readiness.py --min-score 75
python scripts/final_submission_control.py
python scripts/final_closeout_status.py
python scripts/final_operator_brief.py
python scripts/final_launch_plan.py
python scripts/submission_audit.py
python scripts/devpost_submission_receipt.py
python scripts/submission_bundle.py
```

## GitHub CI

The `.github/workflows/ci.yml` workflow runs on `main`, `feature/**`, and pull requests:

- install `.[dev,integrations]`
- `python scripts/check_integrations.py`
- `python scripts/genblaze_contract_check.py`
- `python scripts/docker_smoke.py`
- `ruff check .`
- `pytest`
- `python scripts/api_smoke.py --base-url http://127.0.0.1:8088`
- `python scripts/secret_scan.py`
- `python scripts/claim_lint.py`
- `python scripts/live_env_handoff.py`
- `python scripts/final_env_wizard.py --check-only`
- `python scripts/b2_key_scope_checklist.py`
- `python scripts/devpost_form_kit.py`
- `python scripts/devpost_submission_checklist.py`
- `python scripts/judge_brief.py`
- `python scripts/judge_crosswalk.py`
- `python scripts/judge_decision_brief.py`
- `python scripts/devpost_event_snapshot.py --validate-committed`
- `python scripts/agent_handoff_check.py`
- `python scripts/public_space_upload.py`
- `python scripts/public_space_sync.py`
- `python scripts/demo_storyboard.py`
- `python scripts/demo_video_draft.py`
- `python scripts/public_video_check.py`
- `python scripts/sponsor_fit_audit.py`
- `python scripts/demo_readiness.py`
- `python scripts/recording_assets.py`
- `python scripts/award_readiness.py --min-score 75`
- `python scripts/final_submission_control.py`
- `python scripts/final_closeout_status.py`
- `python scripts/final_operator_brief.py`
- `python scripts/final_launch_plan.py`
- `python scripts/submission_audit.py`
- `python scripts/devpost_submission_receipt.py`
- `python scripts/submission_bundle.py`

Use the CI result as public repo evidence for the non-secret local gate. It does not replace T020/T021 live sponsor proof because those require private credentials.

Evidence files written by `scripts/api_smoke.py --evidence-out` are checked before writing and fail closed if they contain secret-like field names, bearer tokens, signed URL parameters, or GMI-style key values.

`python scripts/final_env_wizard.py --check-only` is intentionally safe to run in CI and locally. In CI it proves the target env file is git-ignored; locally it also reports `.env.final.local` presence, chmod `0600`, missing required variable names, placeholder names, B2 region derivation, and `ready_for_live_entry` without printing credential values.

The final sponsor proof has a preflight wrapper:

```bash
. .venv/bin/activate
python scripts/final_env_wizard.py --prefill-non-secret --output .env.final.local
python scripts/b2_key_scope_checklist.py
python scripts/genblaze_contract_check.py
python scripts/docker_smoke.py
python scripts/final_env_wizard.py --output .env.final.local --missing-only --force
python scripts/live_env_handoff.py --env-file .env.final.local
python scripts/post_credential_live_proof.py
python scripts/live_proof.py --preflight-only
python scripts/run_final_live_proof.py --env-file .env.final.local --preflight-only
python scripts/run_final_live_proof.py --env-file .env.final.local --genblaze-provider local --genblaze-image-model local-svg-v1 --preflight-only
```

When B2 and Genblaze env/packages are complete, use the post-credential runner:

```bash
. .venv/bin/activate
python scripts/post_credential_live_proof.py --env-file .env.final.local --execute --update-tasks
```

The runner first runs the B2-only proof with mock generation, validates `docs/assets/b2-live-proof-evidence.json`, and only then marks T020 when `--update-tasks` is set. It then runs the final B2 plus Genblaze proof, validates `docs/assets/final-live-proof-evidence.json`, and only then marks T021. Both validators require the expected backend/provider fields, nonempty checksum/object-key fields, and no secret-like keys, bearer tokens, signed URL parameters, or GMI-style key values. Server logs stay under `var/live-proof/`, which is ignored by git.

After the post-credential runner succeeds, sync the public Space before recording or sharing the final proof:

```bash
python scripts/public_space_upload.py --execute --commit-message "Sync ProofFrame public Space after live proof"
python scripts/public_space_sync.py --wait-attempts 5 --wait-seconds 30
python scripts/api_smoke.py --base-url https://adjcjh-backblaze-proofframe.hf.space
```

Before refreshing the public Hugging Face Space, run the upload helper in dry-run mode:

```bash
python scripts/public_space_upload.py
```

Only after the dry-run reports no included sensitive files, execute the upload and immediately verify the public Space:

```bash
python scripts/public_space_upload.py --execute --commit-message "Sync ProofFrame public Space"
python scripts/public_space_sync.py --wait-attempts 5 --wait-seconds 30
python scripts/api_smoke.py --base-url https://adjcjh-backblaze-proofframe.hf.space
```

If the app is already running with those env vars, use:

```bash
python scripts/live_proof.py \
  --base-url http://127.0.0.1:8088 \
  --evidence-out docs/assets/final-live-proof-evidence.json
```

This wrapper does not print credential values. It checks required modes, env presence, package availability, and then delegates evidence writing to `scripts/api_smoke.py`.

## Local App Smoke

In one terminal:

```bash
. .venv/bin/activate
uvicorn proofframe.app:app --host 127.0.0.1 --port 8088
```

In another terminal:

```bash
. .venv/bin/activate
python scripts/api_smoke.py --base-url http://127.0.0.1:8088
```

The JSON output should include `ok: true`, one generated asset checksum, one exported manifest checksum, nonzero `packet_bytes`, and a `judge_demo_campaign_id`.

## Docker Smoke

```bash
docker build -t proofframe:local .
docker run --rm -p 8089:8088 proofframe:local
python3 scripts/api_smoke.py --base-url http://127.0.0.1:8089
```

The default Docker image is optimized for the credential-free public mock demo and installs the core app only. For a B2/Genblaze-capable image, build with:

```bash
docker build --build-arg INSTALL_EXTRAS=integrations -t proofframe:integrations .
```

## B2 Live Proof

Required environment:

```bash
PROOFFRAME_STORAGE_BACKEND=b2
B2_ENDPOINT_URL=
B2_BUCKET=
B2_KEY_ID=
B2_APPLICATION_KEY=
B2_PUBLIC_BASE_URL=
```

Run:

```bash
. .venv/bin/activate
python scripts/check_integrations.py
python scripts/genblaze_contract_check.py
python scripts/run_b2_live_proof.py --env-file .env.final.local --preflight-only
uvicorn proofframe.app:app --host 127.0.0.1 --port 8088
python scripts/live_proof.py \
  --base-url http://127.0.0.1:8088 \
  --require-storage-backend b2 \
  --require-generation-backend mock \
  --evidence-out docs/assets/b2-live-proof-evidence.json
```

Fallback command:

```bash
python scripts/run_b2_live_proof.py --env-file .env.final.local \
  --evidence-out docs/assets/b2-live-proof-evidence.json
```

Fallback against an already running app:

```bash
python scripts/api_smoke.py \
  --base-url http://127.0.0.1:8088 \
  --require-storage-backend b2 \
  --evidence-out docs/assets/b2-live-proof-evidence.json
```

Evidence to save after T020:

- sanitized B2 object key for the generated asset
- sanitized B2 object key for the manifest
- asset checksum
- manifest checksum
- no raw keys, cookies, signed URLs, or private account ids

## Genblaze Live Proof

Required environment:

```bash
PROOFFRAME_GENERATION_BACKEND=genblaze
PROOFFRAME_STORAGE_BACKEND=b2
B2_ENDPOINT_URL=
B2_BUCKET=
B2_KEY_ID=
B2_APPLICATION_KEY=
# Optional if B2_ENDPOINT_URL is a standard Backblaze endpoint.
B2_REGION=
GENBLAZE_PROVIDER=gmicloud
GMI_API_KEY=
GENBLAZE_IMAGE_MODEL=seedream-5.0-lite
GENBLAZE_ASPECT_RATIO=16:9
GENBLAZE_TIMEOUT_SECONDS=180
```

For the no-recharge fallback path, keep B2 values in `.env.final.local` and use the credential-free local Genblaze Pipeline provider:

```bash
python scripts/run_final_live_proof.py \
  --env-file .env.final.local \
  --genblaze-provider local \
  --genblaze-image-model local-svg-v1 \
  --preflight-only
```

Run the final combined app smoke command so Genblaze output uses the official B2 sink before ProofFrame exports its packet evidence:

```bash
python scripts/run_final_live_proof.py \
  --env-file .env.final.local \
  --evidence-out docs/assets/final-live-proof-evidence.json
```

Local Genblaze Pipeline fallback command after preflight is green:

```bash
python scripts/run_final_live_proof.py \
  --env-file .env.final.local \
  --genblaze-provider local \
  --genblaze-image-model local-svg-v1 \
  --evidence-out docs/assets/final-live-proof-evidence.json
```

Fallback against an already running app:

```bash
python scripts/api_smoke.py \
  --base-url http://127.0.0.1:8088 \
  --require-storage-backend b2 \
  --require-generation-backend genblaze \
  --evidence-out docs/assets/final-live-proof-evidence.json
```

- provider `genblaze/gmicloud-image`, `genblaze/openai-image`, or `genblaze/local-image`
- model name
- Genblaze run id
- Genblaze manifest hash
- Genblaze B2 sink enabled
- ProofFrame asset checksum
- no provider key or raw temporary provider URL

## Final Submission Gate

Before Devpost submit:

```bash
python scripts/secret_scan.py
python scripts/claim_lint.py
python scripts/final_env_wizard.py --prefill-non-secret --output .env.final.local
python scripts/b2_key_scope_checklist.py
python scripts/genblaze_contract_check.py
python scripts/final_env_wizard.py --output .env.final.local --missing-only --force
python scripts/live_env_handoff.py --env-file .env.final.local
python scripts/post_credential_live_proof.py --env-file .env.final.local --execute --update-tasks
python scripts/agent_handoff_check.py --check-bus
python scripts/public_space_sync.py
python scripts/devpost_event_snapshot.py --fetch-live
export PROOFFRAME_PUBLIC_VIDEO_URL="https://..."  # YouTube, Vimeo, or Youku only
python scripts/demo_storyboard.py --strict-final
python scripts/public_video_check.py --video-url "$PROOFFRAME_PUBLIC_VIDEO_URL" --verify-url --strict-final
python scripts/demo_readiness.py --strict-final
python scripts/recording_assets.py --verify-public --strict-final
python scripts/secret_scan.py
python scripts/devpost_packet.py --post-live --video-url "$PROOFFRAME_PUBLIC_VIDEO_URL"
python scripts/devpost_form_kit.py --strict-final
python scripts/devpost_submission_checklist.py --strict-final
python scripts/judge_brief.py
python scripts/judge_crosswalk.py
python scripts/judge_decision_brief.py
python scripts/final_operator_brief.py
python scripts/final_launch_plan.py
python scripts/submission_bundle.py
python scripts/submission_audit.py
python scripts/final_submission_control.py
python scripts/final_closeout_status.py

# Submit in Devpost only after the web checklist is green and the real video URL is accepted.

# After Devpost accepts the project:
export PROOFFRAME_DEVPOST_PROJECT_URL="https://devpost.com/software/..."
export PROOFFRAME_DEVPOST_SUBMITTED_AT="2026-08-03T21:00:00Z"
python scripts/devpost_submission_receipt.py \
  --project-url "$PROOFFRAME_DEVPOST_PROJECT_URL" \
  --submitted-at "$PROOFFRAME_DEVPOST_SUBMITTED_AT" \
  --confirmation-note "Devpost accepted/submitted the ProofFrame project."
python scripts/task.py done T042 --note "Devpost accepted/submitted the ProofFrame project and receipt report was captured."
python scripts/secret_scan.py
python scripts/task.py done T041A --note "Final post-receipt secret scan is clear."
python scripts/submission_audit.py --strict-final
python scripts/task.py done T041 --note "Final post-receipt submission audit passed."
python scripts/judge_decision_brief.py
python scripts/final_video_publish_kit.py
python scripts/final_submission_control.py --strict-final
python scripts/devpost_submission_preview.py
python scripts/final_closeout_status.py --strict-final
python scripts/submission_bundle.py --strict-final
python scripts/task.py list --status doing
python scripts/task.py list --status blocked
python scripts/task.py list --status todo
git status --short --branch
```

Final submission remains blocked until T020, T021, T040, T041, T041A, and T042 are complete.