From e609ff86028c81bd149839e03d1ffc0eb2ee9e4a Mon Sep 17 00:00:00 2001 From: Ellie Melton Date: Fri, 10 Jul 2026 18:52:52 +1000 Subject: [PATCH 1/4] Upgrade Codex review workflows and repository validation --- .dockerignore | 3 +- .gitignore | 5 +- AGENTS.md | 25 +- CHANGELOG.md | 12 + README.md | 9 +- SECURITY.md | 2 +- cmd/simclient/client.go | 21 +- cmd/simclient/config.go | 2 + cmd/simclient/desktop_recorder.go | 5 +- cmd/simclient/flow.go | 34 +++ cmd/simclient/main.go | 12 +- cmd/simclient/main_test.go | 68 ++++- codex/README.md | 45 +++- .../2026-05-23-public-repo-sanity-check.md | 3 + codex/prompts/60-simulator-maintenance.md | 66 +++-- ...81-backlog-drafts-structure-and-hygiene.md | 6 +- .../85-create-github-issues-from-drafts.md | 3 +- ...=> 95-validate-technical-review-report.md} | 110 ++++++-- docs/architecture.md | 15 +- docs/cluster-backup-restore-runbook.md | 4 +- docs/cluster-safe-upload-semantics.md | 58 ++--- docs/contact-key-sharing-grants.md | 23 +- docs/contacts-and-viewer-replacement.md | 6 +- docs/development.md | 17 +- docs/getting-started.md | 7 +- docs/production-cluster-scope.md | 25 +- docs/reports/README.md | 13 +- ...ase-0-codex-technical-review-preflight.md} | 187 +++++++++++--- ...w.md => phase-1-codex-technical-review.md} | 237 +++++++++++++----- docs/simulator.md | 23 +- docs/v1-preview-direction.md | 9 +- internal/httpapi/admin_web_session.go | 4 - internal/httpapi/auth_test.go | 6 +- internal/httpapi/main_rate_limit.go | 28 +-- internal/incidents/wrapped_keys.go | 9 - internal/postgresdb/wrapped_keys.go | 9 - 36 files changed, 790 insertions(+), 321 deletions(-) rename codex/prompts/{95-validate-deep-research-report.md => 95-validate-technical-review-report.md} (58%) rename docs/reports/prompts/{phase-0-deep-research-preflight.md => phase-0-codex-technical-review-preflight.md} (63%) rename docs/reports/prompts/{phase-1-deep-research-technical-review.md => phase-1-codex-technical-review.md} (57%) diff --git a/.dockerignore b/.dockerignore index 4e48111..7da0268 100644 --- a/.dockerignore +++ b/.dockerignore @@ -57,9 +57,10 @@ Thumbs.db .vscode/ .idea/ -# Local issue/review drafts and helper scripts. +# Local issue/review/technical-review drafts and helper scripts. .backlog-drafts/ .issue-review-drafts/ +.technical-review-drafts/ .deep-research-drafts/ scripts/ .*-review/ diff --git a/.gitignore b/.gitignore index 3f0f95a..cfd8274 100644 --- a/.gitignore +++ b/.gitignore @@ -57,10 +57,13 @@ Thumbs.db .vscode/ .idea/ -# Codex generated issues / issue review drafts / generated review directories +# Codex generated issues / issue review drafts / technical review drafts / +# generated review directories # Scripts directory should be local and ignored .backlog-drafts/ .issue-review-drafts/ +.technical-review-drafts/ +# Legacy local output from the former ChatGPT Deep Research workflow. .deep-research-drafts/ scripts/ .*-review/ diff --git a/AGENTS.md b/AGENTS.md index f5684d8..e4c3dd5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -63,14 +63,31 @@ - Media streams can be marked `open`, `complete`, or `failed`. - Completed streams and incidents can be downloaded as encrypted ZIP evidence bundles. - Simulator CLI exists for incident upload/check-in/encryption test flows. -- The current simulator encryption envelope is development/test oriented. +- The simulator produces the accepted post-quantum payload envelope by default; + its local key handling and decrypt verification remain development/test tools, + not a production client key-custody model. - Future product scope includes emergency incidents, non-emergency interaction records, timed safety checks, and evidence notes. - The current backend implements local username/password accounts, main `/v1` account/session authentication, admin account management routes, and owner/admin incident authorization. - The current backend implements optional incident mode, capture profile, escalation policy, and sharing state metadata fields on private incident create/read routes, but these fields do not grant access, send notifications, change retention, change key custody, expose trusted-contact workflows, or change public viewer and bundle behavior. - The current backend implements private owner-scoped and admin-global incident deletion routes, deletion tombstones, retryable blob deletion, and optional closed-incident retention through a background worker. -- The current backend does not yet implement mode-driven access, trusted-contact accounts, dead-man switch notifications, public account workflows, or a complete public `/v1` product deployment model beyond local account sessions, optional browser cookie sessions, and route-class limits. -- Planned production-cluster scope may add cluster-safe idempotent upload semantics and operation-level use of coordination. These additions must not remove SQLite, optional PostgreSQL metadata, local filesystem support, the optional S3-compatible blob backend, or the optional Valkey/Redis-compatible coordination backend. -- Regional stream-ingress relay work is planning-only unless explicitly scoped for implementation; any future relay must stay upload-only, temporary, ciphertext-only, and subordinate to the core API for authorization, idempotency, durable blob commits, and metadata. +- The current backend implements account/device recipient-key metadata, + account-to-account trusted-contact relationships, contact public-key metadata, + sharing grants, wrapped-key storage, and authenticated grant-scoped + trusted-contact wrapped-key reads. It does not yet implement mode-driven + access, trusted-contact incident reads or decrypt UX, dead-man switch + notifications, public account workflows, or a complete public `/v1` product + deployment model. +- Complete chunk uploads implement durable idempotency records and optional + short-lived Valkey/Redis-compatible coordination leases. Resumable or partial + upload sessions remain planning-only. These paths must preserve SQLite, + optional PostgreSQL metadata, local filesystem support, the optional + S3-compatible blob backend, and the optional Valkey/Redis-compatible + coordination backend. +- The regional stream-ingress relay implements a bounded complete encrypted + chunk upload, temporary staging, core preflight/commit, and optimistic + encrypted fanout surface. It must remain upload-only, temporary, + ciphertext-only, and subordinate to the core API for authorization, + idempotency, durable blob commits, and metadata. - Future encryption direction should be a hybrid key custody model. - Docker and GitHub Actions/GHCR publishing exist, but deployment expansion should not be added unless explicitly requested. diff --git a/CHANGELOG.md b/CHANGELOG.md index 595f702..098d6b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,18 @@ preview readiness claim. non-goals, and validation expectations in `docs/private-admin-web-scope.md`. +- Migrated the public technical-review workflow to Codex maximum-reasoning + prompts while preserving an independent Phase 2 validation pass. + +- Consolidated duplicate key-metadata rate-limit classification, removed + unreachable internal helpers, and reconciled current implementation docs for + complete-upload coordination, the regional relay, trusted-contact wrapped-key + delivery, and the accepted post-quantum envelope. + +- Updated the simulator for active-TOTP session verification through a + short-lived environment value that is never printed, and refreshed its + desktop-recorder, poor-network, and disposable-smoke guidance. + - Fixed active email challenge 2FA session enforcement so fresh primary-login sessions must complete an email challenge before product-route or private admin operator access alongside the existing TOTP and WebAuthn session gates. diff --git a/README.md b/README.md index 645f265..10c0795 100644 --- a/README.md +++ b/README.md @@ -447,7 +447,8 @@ In another terminal, run the simulator: ```bash PROOFLINE_SIM_USERNAME=admin \ PROOFLINE_SIM_PASSWORD='replace-with-a-long-local-password' \ -go run ./cmd/simclient --chunks 5 --interval 1s --download-bundle +go run ./cmd/simclient --chunks 5 --interval 1s --download-bundle \ + --setup-totp-second-factor ``` The simulator creates an incident, creates a viewer token without printing the @@ -459,6 +460,12 @@ desktop-recorder mode, local file input, ffmpeg segment capture, and poor-network retry controls, and simulator-only contact-wrapped key metadata artifacts. +The setup flag above is for a fresh disposable local account and does not print +or persist the generated TOTP seed. For an established account with active +TOTP, provide the current short-lived code through +`PROOFLINE_SIM_TOTP_CODE`; `simclient` verifies the session without printing the +code. + ## Docker Build from the repository root: diff --git a/SECURITY.md b/SECURITY.md index e250503..ec480ff 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -75,7 +75,7 @@ Reports are in scope when they affect the current backend, documentation, or dep The following are generally out of scope unless they demonstrate a concrete vulnerability in this repository: -- missing features already documented as absent, such as public account workflows, OAuth, JWT, SMS, push notifications, trusted-contact accounts, Android/iOS clients, web-client implementation in this server repository, mode-driven escalation behavior, or a public admin dashboard +- missing features already documented as absent, such as public account workflows, OAuth, JWT, SMS, push notifications, trusted-contact incident reads or decrypt UX, Android/iOS clients, web-client implementation in this server repository, mode-driven escalation behavior, or a public admin dashboard - lack of production hardening already documented as a known limitation, without a new exploit path - reports requiring unreviewed broad public exposure of main `/v1` route groups contrary to documented deployment guidance - denial-of-service reports based only on unrealistic local access or unbounded physical access diff --git a/cmd/simclient/client.go b/cmd/simclient/client.go index c0fffa6..9e1c704 100644 --- a/cmd/simclient/client.go +++ b/cmd/simclient/client.go @@ -30,7 +30,8 @@ type createIncidentResponse struct { } type loginResponse struct { - Token string `json:"token"` + Token string `json:"token"` + SecondFactorVerificationRequired bool `json:"second_factor_verification_required"` } type totpEnrollmentResponse struct { @@ -141,19 +142,19 @@ func (c client) createIncident(ctx context.Context) (string, error) { return response.IncidentID, nil } -func (c client) login(ctx context.Context, username, password string) (string, error) { +func (c client) login(ctx context.Context, username, password string) (loginResponse, error) { request := map[string]string{ "username": username, "password": password, } var response loginResponse if err := c.postJSON(ctx, "/v1/auth/login", request, http.StatusCreated, &response); err != nil { - return "", fmt.Errorf("login: %w", err) + return loginResponse{}, fmt.Errorf("login: %w", err) } if response.Token == "" { - return "", fmt.Errorf("login: empty token in response") + return loginResponse{}, fmt.Errorf("login: empty token in response") } - return response.Token, nil + return response, nil } func (c client) setupTOTPSecondFactor(ctx context.Context) error { @@ -174,6 +175,16 @@ func (c client) setupTOTPSecondFactor(ctx context.Context) error { return nil } +func (c client) verifyTOTPSecondFactor(ctx context.Context, code string) error { + if strings.TrimSpace(code) == "" { + return fmt.Errorf("verify TOTP second factor: code is required") + } + if err := c.postJSON(ctx, "/v1/account/second-factor/totp/verify", map[string]string{"code": code}, http.StatusOK, nil); err != nil { + return fmt.Errorf("verify TOTP second factor: %w", err) + } + return nil +} + func (c client) createIncidentToken(ctx context.Context, incidentID string) (string, error) { request := map[string]string{"label": "simclient"} var response createIncidentTokenResponse diff --git a/cmd/simclient/config.go b/cmd/simclient/config.go index 5557795..458c345 100644 --- a/cmd/simclient/config.go +++ b/cmd/simclient/config.go @@ -18,6 +18,7 @@ type config struct { uploadMode string username string password string + totpCode string chunks int interval time.Duration mediaType string @@ -75,6 +76,7 @@ func parseConfig(args []string) (config, error) { fs.StringVar(&cfg.relayBase, "relay-url", "", "Stream-ingress relay base URL when --upload-mode=relay") fs.StringVar(&cfg.username, "username", os.Getenv("PROOFLINE_SIM_USERNAME"), "Proofline account username") fs.StringVar(&cfg.password, "password", os.Getenv("PROOFLINE_SIM_PASSWORD"), "Proofline account password") + cfg.totpCode = strings.TrimSpace(os.Getenv("PROOFLINE_SIM_TOTP_CODE")) fs.IntVar(&cfg.chunks, "chunks", defaultChunks, "Number of chunks to upload") fs.DurationVar(&cfg.interval, "interval", defaultInterval, "Delay between chunk uploads") fs.StringVar(&cfg.mediaType, "media-type", defaultMediaType, "Media type to upload") diff --git a/cmd/simclient/desktop_recorder.go b/cmd/simclient/desktop_recorder.go index f4b43a5..8e74e3f 100644 --- a/cmd/simclient/desktop_recorder.go +++ b/cmd/simclient/desktop_recorder.go @@ -28,12 +28,9 @@ func runDesktopRecorder(ctx context.Context, out io.Writer, cfg config) error { viewerBase: cfg.viewerBase, } - fmt.Fprintln(out, "Logging in...") - sessionToken, err := sim.login(ctx, cfg.username, cfg.password) - if err != nil { + if err := authenticateSimulatorSession(ctx, out, &sim, cfg); err != nil { return err } - sim.sessionToken = sessionToken manifest, err := prepareDesktopStage(ctx, out, sim, cfg, stage, encryption) if err != nil { diff --git a/cmd/simclient/flow.go b/cmd/simclient/flow.go index ca042b7..72af9fa 100644 --- a/cmd/simclient/flow.go +++ b/cmd/simclient/flow.go @@ -34,6 +34,40 @@ func prepareEncryption(out io.Writer, cfg config) (simulatorEncryption, error) { return encryption, nil } +func authenticateSimulatorSession(ctx context.Context, out io.Writer, sim *client, cfg config) error { + fmt.Fprintln(out, "Logging in...") + login, err := sim.login(ctx, cfg.username, cfg.password) + if err != nil { + return err + } + sim.sessionToken = login.Token + + if cfg.setupTOTPSecondFactor { + if login.SecondFactorVerificationRequired { + return fmt.Errorf("--setup-totp-second-factor cannot be used when an active factor already requires verification") + } + fmt.Fprintln(out, "Setting up TOTP second factor...") + if err := sim.setupTOTPSecondFactor(ctx); err != nil { + return err + } + fmt.Fprintln(out, "TOTP second factor verified.") + return nil + } + + if !login.SecondFactorVerificationRequired { + return nil + } + if cfg.totpCode == "" { + return fmt.Errorf("account session requires second-factor verification; set the current TOTP code through PROOFLINE_SIM_TOTP_CODE") + } + fmt.Fprintln(out, "Verifying TOTP second factor...") + if err := sim.verifyTOTPSecondFactor(ctx, cfg.totpCode); err != nil { + return err + } + fmt.Fprintln(out, "TOTP second factor verified.") + return nil +} + func uploadChunks(ctx context.Context, out io.Writer, sim client, cfg config, incidentID, streamID string, encryption simulatorEncryption, relaySession relaySession) error { startedAt := time.Now().UTC() for i := 1; i <= cfg.chunks; i++ { diff --git a/cmd/simclient/main.go b/cmd/simclient/main.go index 7f7ec53..8d42980 100644 --- a/cmd/simclient/main.go +++ b/cmd/simclient/main.go @@ -38,19 +38,9 @@ func run(ctx context.Context, out io.Writer, args []string) error { relayBase: cfg.relayBase, } - fmt.Fprintln(out, "Logging in...") - sessionToken, err := sim.login(ctx, cfg.username, cfg.password) - if err != nil { + if err := authenticateSimulatorSession(ctx, out, &sim, cfg); err != nil { return err } - sim.sessionToken = sessionToken - if cfg.setupTOTPSecondFactor { - fmt.Fprintln(out, "Setting up TOTP second factor...") - if err := sim.setupTOTPSecondFactor(ctx); err != nil { - return err - } - fmt.Fprintln(out, "TOTP second factor verified.") - } fmt.Fprintln(out, "Creating incident...") incidentID, err := sim.createIncident(ctx) diff --git a/cmd/simclient/main_test.go b/cmd/simclient/main_test.go index 211c790..f281af4 100644 --- a/cmd/simclient/main_test.go +++ b/cmd/simclient/main_test.go @@ -112,11 +112,11 @@ func TestClientWriteRoutesUseMainAPIBase(t *testing.T) { } ctx := context.Background() - sessionToken, err := sim.login(ctx, "test-admin", "test-password") + login, err := sim.login(ctx, "test-admin", "test-password") if err != nil { t.Fatalf("login returned error: %v", err) } - sim.sessionToken = sessionToken + sim.sessionToken = login.Token incidentID, err := sim.createIncident(ctx) if err != nil { t.Fatalf("createIncident returned error: %v", err) @@ -914,6 +914,70 @@ func TestSetupTOTPSecondFactor(t *testing.T) { } } +func TestAuthenticateSimulatorSessionVerifiesRequiredTOTP(t *testing.T) { + const code = "123456" + var gotPaths []string + httpClient := &http.Client{Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) { + gotPaths = append(gotPaths, r.Method+" "+r.URL.Path) + switch r.URL.Path { + case "/v1/auth/login": + return testResponse(http.StatusCreated, "application/json", `{"token":"session-token","second_factor_verification_required":true}`), nil + case "/v1/account/second-factor/totp/verify": + if r.Header.Get("Authorization") != "Bearer session-token" { + t.Fatal("TOTP verification omitted session Authorization header") + } + var request struct { + Code string `json:"code"` + } + if err := json.NewDecoder(r.Body).Decode(&request); err != nil { + t.Fatalf("decode TOTP verification request: %v", err) + } + if request.Code != code { + t.Fatalf("TOTP code = %q, want supplied code", request.Code) + } + return testResponse(http.StatusOK, "application/json", `{"status":"verified"}`), nil + default: + return testResponse(http.StatusNotFound, "application/json", `{"error":{"code":"not_found"}}`), nil + } + })} + sim := client{httpClient: httpClient, apiBase: "http://api.example"} + var output bytes.Buffer + + err := authenticateSimulatorSession(context.Background(), &output, &sim, config{ + username: "admin", + password: "password", + totpCode: code, + }) + if err != nil { + t.Fatalf("authenticateSimulatorSession returned error: %v", err) + } + if sim.sessionToken != "session-token" { + t.Fatal("session token was not retained after login") + } + if got := strings.Join(gotPaths, "\n"); got != "POST /v1/auth/login\nPOST /v1/account/second-factor/totp/verify" { + t.Fatalf("paths = %q", got) + } + if strings.Contains(output.String(), code) || strings.Contains(output.String(), "session-token") { + t.Fatalf("authentication output exposed a verification credential: %s", output.String()) + } +} + +func TestAuthenticateSimulatorSessionRequiresTOTPCode(t *testing.T) { + httpClient := &http.Client{Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) { + return testResponse(http.StatusCreated, "application/json", `{"token":"session-token","second_factor_verification_required":true}`), nil + })} + sim := client{httpClient: httpClient, apiBase: "http://api.example"} + var output bytes.Buffer + + err := authenticateSimulatorSession(context.Background(), &output, &sim, config{username: "admin", password: "password"}) + if err == nil || !strings.Contains(err.Error(), "PROOFLINE_SIM_TOTP_CODE") { + t.Fatalf("error = %v, want TOTP environment guidance", err) + } + if strings.Contains(err.Error(), "session-token") || strings.Contains(output.String(), "session-token") { + t.Fatal("missing-code error exposed the session token") + } +} + func TestPostJSONUnexpectedStatusOmitsTokenBearingBody(t *testing.T) { httpClient := &http.Client{Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) { return testResponse(http.StatusOK, "application/json", `{"token":"raw-session-token","other":"raw-viewer-token"}`), nil diff --git a/codex/README.md b/codex/README.md index 0033ebb..14a171a 100644 --- a/codex/README.md +++ b/codex/README.md @@ -82,6 +82,8 @@ Generated local artifacts should not be placed under `codex/`. Current generated artifact locations: +- `.technical-review-drafts/` for source-cited Codex Phase 1 report drafts that + still require independent Phase 2 validation before publication - `.backlog-drafts/YYYY-MM-DD//` or `.backlog-drafts/current//` for backlog issue drafts - `.issue-review-drafts/YYYY-MM-DD//` or `.issue-review-drafts/current//` for open-issue review drafts - `scripts/create-backlog-issues.sh` only when explicitly generated from reviewed backlog drafts @@ -130,7 +132,7 @@ Use prompts in this rough order: ### Release workflow 22. `90-release-check.md` -23. `95-validate-deep-research-report.md`, for Phase 2 validation of public technical review reports +23. `95-validate-technical-review-report.md`, for independent Phase 2 validation of public technical review reports For any `v1 preview`, `v1.0.0`, or real-user evidence-upload readiness claim, run [docs/v1-preview-readiness-checklist.md](../docs/v1-preview-readiness-checklist.md) @@ -179,9 +181,11 @@ Core constraints: ## When To Update Prompts -Treat current code and source-of-truth docs as project truth. Reusable prompts are workflow helpers, Deep Research prompts are report-generation and validation helpers, and historical prompts are reference-only. +Treat current code and source-of-truth docs as project truth. Reusable prompts +are workflow helpers, Codex technical-review prompts are report-generation and +validation helpers, and historical prompts are reference-only. -When project scope, architecture, security posture, or workflow changes, update implementation or design docs first. Then update `README.md`, `AGENTS.md`, `SECURITY.md`, and relevant `docs/` files as needed. Update reusable Codex prompts only when their assumptions, guardrails, or repeated workflow steps have changed. Update Deep Research prompts when report scope, citation policy, source policy, or recurring validation failures change. Leave historical prompts untouched unless the maintainer explicitly requests otherwise. +When project scope, architecture, security posture, or workflow changes, update implementation or design docs first. Then update `README.md`, `AGENTS.md`, `SECURITY.md`, and relevant `docs/` files as needed. Update reusable Codex prompts only when their assumptions, guardrails, or repeated workflow steps have changed. Update Codex technical-review prompts when report scope, citation policy, source policy, execution-evidence policy, or recurring validation failures change. Leave historical prompts untouched unless the maintainer explicitly requests otherwise. | Project change | Prompt/doc action | |---|---| @@ -191,17 +195,25 @@ When project scope, architecture, security posture, or workflow changes, update | New API routes or listener exposure | Review `AGENTS.md`, `docs/api.md`, security/threat docs, and relevant review prompts. | | Private `/v1` exposure or authentication model changes | Review `AGENTS.md`, `docs/deployment.md`, `docs/security-model.md`, `docs/threat-model.md`, and every reusable prompt that references private/public route separation. | | Logging behavior, startup/config error logs, request logs, or worker/operator logs | Review `docs/logging-requirements.md`, `docs/security-model.md`, `docs/threat-model.md`, and relevant review prompts. | -| Encryption envelope changes | Update `docs/encryption.md`, `docs/post-quantum-envelope.md`, `docs/simulator.md`, `60-simulator-maintenance.md`, `30-security-review.md`, and Deep Research review scope. | +| Encryption envelope changes | Update `docs/encryption.md`, `docs/post-quantum-envelope.md`, `docs/simulator.md`, `60-simulator-maintenance.md`, `30-security-review.md`, and the Codex technical-review scope. | | Key custody, browser decryption, break-glass, or dead-man-switch design changes | Use or update the key-custody prompts and update threat model, security model, encryption docs, incident-mode docs, and operational guidance. | -| Bundle, storage, schema, or manifest changes | Update API docs, code-map docs, simulator docs/prompts, and Deep Research scope. | +| Bundle, storage, schema, or manifest changes | Update API docs, code-map docs, simulator docs/prompts, and the Codex technical-review scope. | | CI/CD, Docker, GHCR, or release workflow changes | Update release/development docs and release/report prompts. | | New repeated Codex workflow | Add one reusable `NN-short-kebab-title.md` prompt and list it in this README. | | One-off implementation, refactor, or work order | Add a dated historical prompt under `archive/` or `work-orders/`. | -| Validated Deep Research report finds a recurring false-positive pattern | Update the Deep Research Phase 1 and/or Codex Phase 2 validation prompts so the same mistake is less likely to recur. | +| Validated technical review finds a recurring false-positive pattern | Update the Codex Phase 1 and/or independent Phase 2 validation prompts so the same mistake is less likely to recur. | Key custody guardrails need special care. Preserve the current backend ciphertext-only implementation unless the task explicitly concerns key custody, emergency access, or decryption design. Do not turn "no server keys ever" into a permanent absolute rule, and do not introduce backend decryption, browser decryption, raw server-held keys, key escrow, or key-sharing behaviour incidentally. Explicit key custody or decryption work must update the threat model, security model, encryption docs, tests, and operational guidance before or alongside implementation. -For the public-safe report workflow, review Deep Research Phase 1 and Codex Phase 2 validation together when report workflow changes. Phase 1 lives in `docs/reports/prompts/phase-1-deep-research-technical-review.md`. Codex Phase 2 validation lives in `codex/prompts/95-validate-deep-research-report.md`. Keep portable citation keys, pin repository citations to reviewed commits, do not allow ChatGPT internal citation tokens in public reports, and add newly discovered recurring false positives to the Phase 2 checklist. +For the public-safe report workflow, review the Codex Phase 0 preflight, Codex +Phase 1 draft, and independent Codex Phase 2 validation prompts together when +the workflow changes. Phase 0 lives in +`docs/reports/prompts/phase-0-codex-technical-review-preflight.md`, Phase 1 lives +in `docs/reports/prompts/phase-1-codex-technical-review.md`, and Phase 2 lives in +`codex/prompts/95-validate-technical-review-report.md`. Keep portable citation +keys, pin repository citations to reviewed commits, remove internal renderer or +tool citation identifiers from public reports, and add newly discovered +recurring false positives to the Phase 2 checklist. Do not add a reusable prompt for every one-off idea. Add reusable prompts only for repeated workflows. One-off prompts belong in `archive/` or `work-orders/`, and generated local artifacts belong outside `codex/`. @@ -235,9 +247,22 @@ Use `38-break-glass-and-dead-mans-switch-key-access-design.md` for server escrow ## Technical review report workflow -Use `docs/reports/prompts/phase-1-deep-research-technical-review.md` outside Codex to draft a source-cited public technical review report. - -Use `95-validate-deep-research-report.md` in Codex to verify repository claims, remove draft-only material, pin repository citations, check public-safety constraints, and produce a cleaned report under `docs/reports/`. +Use `docs/reports/prompts/phase-0-codex-technical-review-preflight.md` in Codex +Max for a focused single-agent preflight, or Ultra when meaningful independent +read-only lanes justify subagent delegation. Load the governing Phase 1 prompt, +prepare the source and execution plan, and stop for maintainer approval. + +After approval, use `docs/reports/prompts/phase-1-codex-technical-review.md` in +Codex Max for a focused review, or Ultra when the review has meaningful +independent research lanes. Create a source-cited draft under the ignored +`.technical-review-drafts/` directory. Phase 1 may directly execute safe +validation commands, but its Source Registry must record the exact command, +context, result, and limitations. + +Use `95-validate-technical-review-report.md` as an independent Phase 2 pass to +verify repository and execution-evidence claims, remove draft-only material, +pin repository citations, check public-safety constraints, and publish the +cleaned report under `docs/reports/`. ## Validation diff --git a/codex/archive/2026-05-23-public-repo-sanity-check.md b/codex/archive/2026-05-23-public-repo-sanity-check.md index 2c29a77..edf960a 100644 --- a/codex/archive/2026-05-23-public-repo-sanity-check.md +++ b/codex/archive/2026-05-23-public-repo-sanity-check.md @@ -1,5 +1,8 @@ # Codex Prompt: Pre-Public Repository Sanity Check +> Historical reference only. This prompt records the pre-public repository +> context at the time and is not a current reusable workflow. + Run sanity checks before making the repository public. The purpose is low-visibility public access to avoid private-repository limits, not advertising. diff --git a/codex/prompts/60-simulator-maintenance.md b/codex/prompts/60-simulator-maintenance.md index f5311d1..e1f3ee8 100644 --- a/codex/prompts/60-simulator-maintenance.md +++ b/codex/prompts/60-simulator-maintenance.md @@ -46,20 +46,17 @@ Do not rely on stale assumptions from this prompt if the repository has changed. The simulator acts as a local backend reference client for current and future recorder flows. -The current `cmd/simclient` uploads fake chunks through the private API and can -verify encrypted bundle downloads locally. A future local desktop recorder -simulator client may extend this simulator boundary, but it should remain a -simulator, not a production desktop app or replacement for planned mobile -clients. - -The future desktop simulator should support adjustable poor-network simulation -for latency, jitter, request timeouts, bandwidth ceilings, intermittent offline -windows, upload failure rates, and process restart or resume drills. +The current `cmd/simclient` uploads generated or local test chunks through the +authenticated main API and can verify encrypted bundle downloads locally. Its +desktop recorder mode supports durable encrypted staging, generated, file, and +ffmpeg sources, complete-chunk retry/resume, and adjustable poor-network +simulation. It must remain a simulator, not a production desktop app or a +replacement for planned mobile clients. It should use the current local account/session flow for private `/v1` authentication. Simulator maintenance must not add OAuth, JWT, broad public -`/v1` exposure, trusted-contact accounts, public account workflows, or extra -account-management routes incidentally. +`/v1` exposure, public account workflows, new trusted-contact/key-delivery +behavior, or extra account-management routes incidentally. It should exercise: @@ -74,8 +71,10 @@ It should exercise: - checkins - stream completion - optional failure/retry behaviour -- adjustable poor-network simulation for future desktop recorder flows, when - that simulator exists +- durable encrypted desktop staging and restart/resume drills +- adjustable poor-network simulation for desktop recorder flows +- optional direct or regional-relay complete-chunk uploads +- optional duplicate reconciliation and conflict verification - optional encrypted bundle download verification - local decrypt verification of downloaded bundles when encryption is enabled @@ -83,8 +82,9 @@ It should exercise: Check that the simulator: -- uses the private API base URL for `/v1` routes -- uses the public viewer base URL for printed incident viewer links +- uses the authenticated main API base URL for `/v1` routes +- uses the viewer base URL only for viewer bundle requests and omits + token-bearing viewer URLs from terminal output - creates a media stream before uploading chunks - uploads chunks with `stream_id` - keeps streamed chunk indexes unique per `(incident_id, stream_id, chunk_index)` @@ -92,21 +92,22 @@ Check that the simulator: - encrypts fake chunks by default - supports `--encrypt=false` only for development compatibility - supports `--key-file` without printing the key -- does not print raw keys or plaintext +- does not print raw keys, TOTP codes, verification credentials, or plaintext - sends checkins during simulation - completes the stream by default unless configured otherwise - can simulate bad-hash failure and retry -- can simulate poor network conditions through adjustable controls when working - on the future desktop recorder simulator +- can simulate poor network conditions through adjustable desktop-recorder + controls - can optionally download a completed encrypted bundle - can decrypt-verify downloaded encrypted chunks locally - prints readable progress output - does not require public auth - does not assume playable media exists -- keeps near-term account support local or fixture-only until explicit account - and access-control backend work exists -- does not add resumable uploads, upload leases, or server-visible queue - summary routes just to support simulator work unless explicitly requested +- uses the implemented local account/session and required second-factor setup + flow without expanding account-management or public product behavior +- does not add resumable uploads, partial-upload leases, or server-visible + queue summary routes just to support simulator work unless explicitly + requested ## Tests @@ -127,7 +128,14 @@ go vet ./... git diff --check ``` -Manual smoke test. Prefer TOML for repeatable smoke: +Manual smoke tests must use a disposable local data directory, SQLite path, +loopback ports, and synthetic credentials. Do not reuse an existing local +database, inherited deployment configuration, stored credentials, or live +listeners. Prefer a minimal explicit TOML file or an equally explicit clean +environment, remove the bootstrap secret after account creation where the +smoke lifecycle permits, and stop the disposable processes after validation. + +Example TOML shape: ```toml [auth] @@ -149,14 +157,22 @@ curl -sS -X POST http://127.0.0.1:8081/admin/bootstrap \ --data-urlencode 'password=replace-with-a-long-local-password' ``` -Then run the simulator with account credentials: +Then run the simulator with the synthetic account credentials. On a fresh +database, include `--setup-totp-second-factor` so the new account completes its +required setup before product-route calls: ```bash PROOFLINE_SIM_USERNAME='admin' \ PROOFLINE_SIM_PASSWORD='replace-with-a-long-local-password' \ -go run ./cmd/simclient --chunks 5 --interval 1s --download-bundle +go run ./cmd/simclient --chunks 5 --interval 1s --download-bundle \ + --setup-totp-second-factor ``` +For an established local account with active TOTP, supply only the current +short-lived code through `PROOFLINE_SIM_TOTP_CODE`; never print or persist it in +the repository. Do not weaken second-factor enforcement to make a smoke test +pass. + ## Output Summarize: diff --git a/codex/prompts/81-backlog-drafts-structure-and-hygiene.md b/codex/prompts/81-backlog-drafts-structure-and-hygiene.md index 2d84ff6..cf183c3 100644 --- a/codex/prompts/81-backlog-drafts-structure-and-hygiene.md +++ b/codex/prompts/81-backlog-drafts-structure-and-hygiene.md @@ -30,7 +30,7 @@ Read: - `codex/prompts/80-backlog-scan-issue-drafts.md` - `codex/prompts/85-create-github-issues-from-drafts.md` - `codex/prompts/82-review-open-issues-for-stale-or-fixed.md`, if present -- `codex/prompts/95-validate-deep-research-report.md`, if present +- `codex/prompts/95-validate-technical-review-report.md`, if present - `.backlog-drafts/`, if present - `scripts/create-backlog-issues.sh`, if present - `.gitignore` @@ -191,7 +191,7 @@ Check: - whether any issue creation script points to stale flat paths - whether `80-backlog-scan-issue-drafts.md` enforces branch-scoped output and required metadata - whether `85-create-github-issues-from-drafts.md` selects a branch-scoped draft directory, preserves branch scope in issue bodies, and passes labels to `gh issue create` -- whether `95-validate-deep-research-report.md` creates branch-scoped report issue drafts with priority and labels +- whether `95-validate-technical-review-report.md` creates branch-scoped report issue drafts with priority and labels - whether any draft contains raw tokens, secrets, private deployment info, exploit details, or user safety data ## Permitted changes @@ -202,7 +202,7 @@ Allowed when implementation is requested: - update `codex/prompts/80-backlog-scan-issue-drafts.md` - update `codex/prompts/85-create-github-issues-from-drafts.md` -- update `codex/prompts/95-validate-deep-research-report.md` +- update `codex/prompts/95-validate-technical-review-report.md` - update `codex/README.md` - update `docs/codex-change-control.md` - update `.gitignore` diff --git a/codex/prompts/85-create-github-issues-from-drafts.md b/codex/prompts/85-create-github-issues-from-drafts.md index b64d577..6ab2332 100644 --- a/codex/prompts/85-create-github-issues-from-drafts.md +++ b/codex/prompts/85-create-github-issues-from-drafts.md @@ -26,7 +26,8 @@ open-proofline/server ## Draft directory -Backlog drafts are normally created by `80-backlog-scan-issue-drafts.md` or `95-validate-deep-research-report.md`. +Backlog drafts are normally created by `80-backlog-scan-issue-drafts.md` or the +independent Phase 2 `95-validate-technical-review-report.md` workflow. They should live under a branch-scoped timestamped directory such as: diff --git a/codex/prompts/95-validate-deep-research-report.md b/codex/prompts/95-validate-technical-review-report.md similarity index 58% rename from codex/prompts/95-validate-deep-research-report.md rename to codex/prompts/95-validate-technical-review-report.md index 34481ee..0acfaea 100644 --- a/codex/prompts/95-validate-deep-research-report.md +++ b/codex/prompts/95-validate-technical-review-report.md @@ -1,8 +1,15 @@ -# Codex Prompt: Validate Deep Research Technical Review Report +# Codex Prompt: Validate Technical Review Report -Validate, clean, and public-harden a Deep Research technical review report for this repository. +Validate, clean, and public-harden a Codex technical review report for this repository. -This is the Phase 2 workflow after a source-cited Deep Research draft. Phase 1 produces a broad report and portable source registry. Phase 2 checks the report against the reviewed repository commit, converts citations into public-safe Markdown, separates future design from implemented behavior, and scopes any generated draft issues to the current branch. +This is an independent Phase 2 workflow after a source-cited Codex Phase 1 +draft. Phase 1 produces a broad report and portable source registry and may +directly execute validation commands when it records exact evidence. Phase 2 +independently checks the draft against the reviewed repository commit, +converts citations into public-safe Markdown, separates future design from +implemented behavior, and scopes any generated draft issues to the current +branch. Do not accept Phase 1 execution claims without checking the recorded +command, context, and result. ## Inputs @@ -27,7 +34,7 @@ Reviewed commit SHA: Report path: ```text - +.technical-review-drafts/-proofline--technical-review-draft.md ``` Target release / version: @@ -51,7 +58,8 @@ drafts_only Allowed values: - `drafts_only`: create or update local branch-scoped issue drafts only -- `create_issues`: create GitHub issues only when the maintainer explicitly requested it +- `create_issues`: create sanitized non-vulnerability GitHub issues only when + the maintainer explicitly requested it - `none`: do not create issue drafts or GitHub issues ## Product Context @@ -64,20 +72,48 @@ reusable README baseline guidance, and source-of-truth mapping. Report wording that summarizes project-wide public posture should use those website source documents rather than inventing a server-local governance claim. -Proofline's planned product scope includes emergency incidents, non-emergency interaction records, timed safety checks, and evidence notes. The current backend stores generic incidents by default; optional incident-mode, capture-profile, escalation-policy, and sharing-state metadata are labels only unless the reviewed tree explicitly implements first-class behavior for them. The post-quantum envelope is a v1 preview requirement, but it is not current runtime behavior unless implementation files prove it. Any report claim that Proofline is ready for `v1 preview`, `v1.0.0`, or real-user evidence upload must be checked against `docs/v1-preview-readiness-checklist.md`. +Proofline's planned product scope includes emergency incidents, non-emergency interaction records, timed safety checks, and evidence notes. The current backend stores generic incidents by default; optional incident-mode, capture-profile, escalation-policy, and sharing-state metadata are labels only unless the reviewed tree explicitly implements first-class behavior for them. Recipient-key, trusted-contact, sharing-grant, wrapped-key, and post-quantum envelope status is commit-specific: preserve implemented server or simulator behavior that code and tests prove without overstating it as completed production key custody, browser/client decryption, or cross-repository conformance. Any report claim that Proofline is ready for `v1 preview`, `v1.0.0`, or real-user evidence upload must be checked against `docs/v1-preview-readiness-checklist.md`. ## Rules -- Use the current checked-out branch. +- Use the current checked-out branch as the Phase 2 editing workspace, not as + automatic evidence for ``. +- Confirm `` resolves to ``. Ground + reviewed-tree facts in commit-addressed reads or a clean isolated copy of that + commit. Never attribute dirty working-tree or different-`HEAD` results to the + reviewed commit. - Pin repository citations and report metadata to ``, not to a moving branch name. - Keep changes scoped to report validation, citation cleanup, and branch-scoped draft issues if requested. - Do not change application code, CI behavior, repository settings, or GitHub issues unless explicitly requested. - Keep the report and any issue drafts public-safe according to `SECURITY.md`. +- Remove raw viewer, incident, session, or future token-like values; secrets; + Authorization headers; request bodies; uploaded file bytes; plaintext; raw + keys; wrapped-key ciphertext; private deployment details; stored paths; + object keys; exploit payloads; and user-safety data. - Do not weaken security warnings. - Do not claim production readiness, platform-store approval, legal review, compliance certification, penetration test, or formal audit. - Do not treat absence of future-design features as a defect when source-of-truth docs mark them out of scope. - Preserve the current backend ciphertext-only implementation boundary unless the report identifies implemented behavior that contradicts it. +- Preserve separate main API/viewer and private-admin listener groups and muxes, + read-only public viewer paths, and the rule that public edges do not route + private write or admin surfaces. +- Preserve that completed evidence bundles are encrypted chunk bundles with + server-controlled ZIP entry names, not decrypted or playable media exports. - Treat future incident-mode, web/iOS/Android client, key-custody, browser-decryption, break-glass, and post-quantum envelope documents as planning or future preview requirements unless implementation files exist in the reviewed tree. +- Treat Phase 1 command output as review evidence, not as a substitute for + independent Phase 2 verification. Record which commands Phase 2 reruns and + which Phase 1 evidence it only inspects. +- Do not claim that Phase 1 or Phase 2 ran a command unless the report or current + validation record includes the exact command, relevant ref or environment, + and result. +- Independently safety-review every command from the Phase 1 draft before + execution. Do not access private or production services, inherit deployment + credentials or endpoints, or run secret-dependent checks. Run + reviewed-commit tests/builds only in an approved clean isolated temporary + copy; treat dirty-workspace results as current-workspace evidence only. +- Route suspected or unresolved vulnerabilities through `SECURITY.md` and + GitHub private vulnerability reporting. Do not create public issue drafts, + public GitHub issues, or public report details that disclose them. ## First Steps @@ -87,6 +123,8 @@ Check repository state: git status --short --branch --untracked-files=all git branch --show-current git rev-parse HEAD +git rev-parse '^{commit}' +git cat-file -e '^{commit}' git log --oneline -5 ``` @@ -125,12 +163,26 @@ replacement reports overflow visibly. These source-of-truth documents can grow between report-validation runs, and silent truncation can miss new v1 direction or post-quantum envelope requirements. +The working-tree reads above establish current publication guidance. Inspect +every material claim about the reviewed tree with a commit-addressed read such +as `git show :`, or in an approved clean isolated +copy of the reviewed commit. If current guidance and reviewed-commit behavior +differ, record that distinction instead of pinning a working-tree observation +to the reviewed SHA. + Read the report: ```bash -sed -n '1,420p' +cat ``` +Review the Phase 1 validation evidence in the Source Registry. For each command +reported as executed, identify the exact command, reviewed ref or commit, +relevant environment, result, and any retained output or summary. Re-run safe, +relevant validation when needed to verify a material report claim, and record +whether Phase 2 independently executed the command or inspected Phase 1 +evidence only. + Before editing, summarize: 1. reviewed branch/ref and reviewed commit SHA @@ -141,8 +193,9 @@ Before editing, summarize: 6. whether future-planning docs are separated from implemented behavior 7. whether Proofline naming and compatibility-name notes are represented correctly 8. whether incident-mode planning is represented as planning unless implemented -9. whether issue drafts should be created and what branch scope they should use -10. likely files to update and docs-review checks +9. whether Phase 1 execution claims have exact evidence and which checks Phase 2 should rerun +10. whether issue drafts should be created and what branch scope they should use +11. likely files to update and docs-review checks ## Branch-Scoped Issue Drafts @@ -164,6 +217,11 @@ Every public issue draft should include priority, type, labels, branch scope, su Use only existing labels. If a good topic label does not exist, use the closest existing label and note the mismatch. +Do not create public issue drafts or public GitHub issues for suspected or +unresolved vulnerabilities. Follow `SECURITY.md` and GitHub private +vulnerability reporting. Public issue handling is limited to sanitized +non-vulnerability hardening or documentation follow-up. + ## Report Validation Checklist Check and fix, if needed: @@ -175,18 +233,35 @@ Check and fix, if needed: incident-mode, capture-profile, escalation-policy, and sharing-state metadata may be described as implemented labels only when the reviewed tree supports them. +- Recipient-key, trusted-contact, sharing-grant, and wrapped-key metadata or API + behavior proved at the reviewed commit is not removed as wholly future, and + is not overstated as completed production key custody or client decryption. +- Post-quantum behavior is classified component by component from code and tests + at the reviewed commit; implemented server or simulator behavior is neither + erased nor treated as proof of complete cross-repository preview readiness. - Current `/v1` private boundary and public incident-viewer separation remain clear. +- Main API/viewer and private-admin routes remain on separate listener groups + and muxes; public viewer paths remain read-only; public edges do not route + private write or admin surfaces. - Current backend ciphertext-only behavior is represented accurately. +- Completed evidence bundles remain encrypted chunk bundles with + server-controlled entry names and are not described as decrypted or playable + exports. - V1 preview, v1.0.0, and real-user evidence-upload readiness claims are checked against `docs/v1-preview-readiness-checklist.md`; if any hard blocker remains incomplete, the report must use pre-v1 or experimental language instead of preview-ready language. - Historical report names are not rewritten as if they used the new product name at the time. -- ChatGPT internal citation tokens are removed or converted to portable citation keys. +- Internal renderer or tool citation identifiers are removed or converted to portable citation keys. +- The report and issue drafts contain none of the prohibited sensitive-data + categories listed in Rules. - Remove informal or conversational draft language, including humour, mascot references, assistant/meta commentary, and chat-only tone, unless it is quoted as reviewed evidence. - Source Registry entries support material claims. - External-source omissions are disclosed and affected claims are marked not independently verified. -- The report does not invent a no-network, no-web, or no-external-source constraint when Phase 1 only restricted claims about executing local commands, tests, builds, containers, or simulator smoke tests. +- Phase 1 execution claims identify the exact command, relevant ref or + environment, result, and limitations; Phase 2 separately records whether it + reran the command or inspected the supplied evidence only. +- The report does not invent a no-network, no-web, or no-external-source constraint unless the maintainer explicitly imposed one. - Missing external sources are treated as verification limitations, not as supporting evidence for findings. ## Common False Positives To Remove Or Downgrade @@ -201,6 +276,12 @@ Check and fix, if needed: escalation policies, sharing-state behavior, or dead-man switch when docs mark them as future work. - Missing browser decryption, production key custody, or break-glass behavior when docs mark them as future work. +- Implemented recipient-key, trusted-contact, sharing-grant, or wrapped-key + metadata and API surfaces treated as wholly absent or future, or overstated as + completed production key custody or client-side review. +- Implemented post-quantum server or simulator behavior treated as wholly + future, or partial behavior overstated as complete web-client, key-custody, + decryption, and cross-repository conformance. - Preserved protocol, data-layout, route-alias, or migration compatibility names treated as stale after the repository/module/artifact rename. - Interaction-record planning treated as current implementation. - Backend decryption or server-held keys assumed from future design docs. @@ -236,5 +317,6 @@ Summarize: 4. issue drafts created, if any 5. citation and public-safety cleanup performed 6. Proofline naming and incident-mode boundary corrections made -7. validation/docs-review commands run -8. follow-up work +7. Phase 1 execution evidence reviewed and Phase 2 checks independently run +8. validation/docs-review commands run +9. follow-up work diff --git a/docs/architecture.md b/docs/architecture.md index e30540b..24a4d3b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -46,11 +46,13 @@ viewer-link, retry, suppression, opt-out, rate-limit, and audit boundaries are documented in [notification-boundary.md](notification-boundary.md). The repository does not contain an iOS app, Android app, web-client -implementation, protocol package, production recording client, production client key storage, key -sharing, browser/client-side decryption, server-assisted break-glass key access, -notification system, trusted-contact delivery model, future public product API, -future separately bound private admin API, OAuth/JWT identity integration, or -playable media export. The Go simulator defaults to the accepted PQ payload +implementation, protocol package, production recording client, production +client key storage or decryption UX, server-assisted break-glass key access, +notification system, trusted-contact incident viewer, public product API +deployment, OAuth/JWT identity integration, or playable media export. The +implemented private-admin API and web surface remain separately bound, and the +implemented trusted-contact surface is limited to authenticated grant-scoped +wrapped-key delivery. The Go simulator defaults to the accepted PQ payload envelope for development and test flows, can use the older v1 AES-GCM envelope only through explicit compatibility flags, and can produce local desktop-recorder test segments. Future key custody and emergency access design @@ -73,7 +75,8 @@ flowchart LR Store --> Files[(Encrypted chunk files)] MainAPI --> Coord["Optional coordination
Valkey/Redis counters + upload leases"] MainAPI --> Token["Viewer token creation"] - Contact["Trusted contact"] --> Viewer["Public incident viewer
/i/{token}"] + TokenHolder["Viewer-token holder"] --> Viewer["Public incident viewer
/i/{token}"] + Contact["Signed-in trusted contact"] -->|"grant-scoped wrapped-key read"| MainAPI Viewer --> Repo Viewer --> Store Viewer --> Bundle["Encrypted ZIP evidence bundles"] diff --git a/docs/cluster-backup-restore-runbook.md b/docs/cluster-backup-restore-runbook.md index b4f8639..51443d8 100644 --- a/docs/cluster-backup-restore-runbook.md +++ b/docs/cluster-backup-restore-runbook.md @@ -184,7 +184,7 @@ main `/v1` routes publicly without a reviewed deployment boundary. - For restore drills that do not need coordination, use `SAFE_COORDINATION_BACKEND=none` only when that accurately represents the deployment shape being tested. - - Future operation-level coordination loss should be handled as retryable + - Complete-upload coordination loss should be handled as retryable operational failure, not as evidence loss, because durable state belongs in PostgreSQL and committed blob storage. @@ -285,7 +285,7 @@ startup: operator intentionally chooses a private local-first shape and documents the operational impact. -If future operation-level coordination is unavailable after startup: +If complete-upload coordination is unavailable after startup: - Return retryable operational errors for affected operations. - Rely on PostgreSQL constraints, immutable blob commits, and client retries to diff --git a/docs/cluster-safe-upload-semantics.md b/docs/cluster-safe-upload-semantics.md index 791405e..4310b05 100644 --- a/docs/cluster-safe-upload-semantics.md +++ b/docs/cluster-safe-upload-semantics.md @@ -187,8 +187,8 @@ The implemented `upload_operations` table tracks: - timestamps for creation and last update Future cluster work may add staging, blob-committed, failed, ownership-proof, -expiry, and cleanup fields when operation-level staging or leases are -implemented. +expiry, and cleanup fields if operation-level object staging or orphan +reconciliation is implemented. Completed chunk metadata remains the durable evidence index. Idempotency rows may support a retry window or operational audit trail, but expiring an @@ -345,33 +345,27 @@ This document focuses on the commit and confirmation semantics once an upload attempt has enough data to compute the ciphertext hash and decide whether a final chunk can be committed. -## Required Future Work - -API documentation: - -- document reverse-proxy, tracing, metrics, and error-reporting redaction for - raw idempotency keys -- document the relationship between duplicate reconciliation and idempotent - retry success - -Backend tests: - -- HTTP tests for same chunk identity with different ciphertext -- cleanup tests proving future staging cleanup does not delete committed - evidence -- race tests for upload versus incident close and stream completion - -Simulator changes: - -- retry an upload after simulated ambiguous response loss -- verify conflict behavior for same chunk identity with different ciphertext -- keep the existing hash-mismatch and bundle verification flows - -Backend-specific work: - -- extend the blob-store boundary for operation-specific staging and conditional - final object commit -- decide how Valkey/Redis-compatible coordination should be used for leases or - reducing duplicate in-progress work -- update deployment, backup, restore, security, threat-model, retention, and - code-map docs before recommending production cluster deployment +## Validation Coverage And Remaining Work + +Current API and deployment docs require redaction of raw idempotency keys and +distinguish idempotent retry from duplicate reconciliation. HTTP tests cover +equivalent replay, conflicting key reuse, and the existing no-key duplicate +behavior. Storage cleanup tests prove that conservative local staging cleanup +does not delete a committed blob. The simulator exercises stable retry keys, +ambiguous-response replay, reconciliation conflict, hash mismatch, and bundle +verification. Local and S3-compatible blob backends use server-controlled +immutable final identities, with conditional no-overwrite commit for S3, and +optional Valkey/Redis-compatible coordination now supplies short-lived +complete-upload leases. + +Remaining work includes: + +- concurrency and race coverage for upload versus incident close and stream + completion across optional backends +- live reverse-proxy, tracing, metrics, and error-sink validation proving raw + idempotency keys stay redacted in the deployed stack +- any future operation-owned object staging, orphan reconciliation, or expiry + policy needed by a reviewed multi-node deployment +- the separately scoped resumable and partial-upload protocol, if accepted +- deployment, backup, restore, observability, security, retention, and threat + review before recommending a production cluster deployment diff --git a/docs/contact-key-sharing-grants.md b/docs/contact-key-sharing-grants.md index 02552a8..05986be 100644 --- a/docs/contact-key-sharing-grants.md +++ b/docs/contact-key-sharing-grants.md @@ -39,7 +39,8 @@ client key, or another explicit future decryption capability. ## Model -The future model should keep these concepts separate: +The implemented metadata model and future client/custody work should keep these +concepts separate: | Concept | Purpose | Security treatment | |---|---|---| @@ -203,19 +204,19 @@ Server-stored wrapped-key records must not include: - request bodies, uploaded bytes, stored paths, staging paths, object keys, or private deployment details -The first production wrapping format for v1 preview is the accepted -post-quantum profile in [post-quantum-envelope.md](post-quantum-envelope.md). -Future runtime code should store profile records through the existing fields -with: +The accepted wrapping format for v1 preview is the post-quantum profile in +[post-quantum-envelope.md](post-quantum-envelope.md). Current runtime code +validates profile records stored through the existing fields with: ```text wrapping_algorithm = proofline-pq-mlkem768-hkdfsha384-aes256gcm wrapping_algorithm_version = 1 ``` -The current routes remain generic metadata storage and delivery routes until -runtime implementation adds profile validation. They must not be described as -cryptographic validators merely because they can already store those strings. +The current routes validate the accepted public wrapping profile and frame +shape before storing or delivering metadata. This is not decryption, proof of +recipient private-key possession, production client key custody, or a complete +cryptographic protocol implementation. The wrapping format must use stable, documented cryptographic libraries or platform APIs. Do not implement custom public-key encryption, KDF, AEAD, @@ -358,8 +359,10 @@ Implementation should stay split into narrow issues: explicitly reviewed. 8. Future: optionally add grant-scoped bundle manifests only after a separate design and tests prove unauthorized actors do not receive wrapped-key records. -9. Update simulator/client tooling to generate production-shaped wrapped-key - records using a reviewed wrapping profile. +9. Implemented for the reference runtime: validate the accepted PQ wrapped-key + profile on the server and keep the simulator's older local age-wrapped + artifact behind explicit v1 compatibility mode. Production companion-client + generation and key custody remain future work. 10. Update deployment, security, threat-model, API, and retention docs before any public-authenticated contact route is exposed. diff --git a/docs/contacts-and-viewer-replacement.md b/docs/contacts-and-viewer-replacement.md index 83d9e56..9f7046a 100644 --- a/docs/contacts-and-viewer-replacement.md +++ b/docs/contacts-and-viewer-replacement.md @@ -477,8 +477,10 @@ encrypted access and reviewed grants. ## Regional Stream Ingress Relay Boundary -The planned regional stream-ingress relay remains planning-only and must be -treated as an ingress/forwarding surface, not a GPS-inspection service. +The implemented regional stream-ingress relay must remain an +ingress/forwarding surface, not a GPS-inspection service. Its current bounded +surface is documented in +[regional-stream-ingress-relay.md](regional-stream-ingress-relay.md). Preferred relay model: diff --git a/docs/development.md b/docs/development.md index b15bace..89fd467 100644 --- a/docs/development.md +++ b/docs/development.md @@ -43,11 +43,18 @@ AI-assisted engineering review artifacts reviewed by the maintainer, not formal security audits, penetration tests, compliance certifications, or production readiness endorsements. -Use the Phase 1 prompt in -[reports/prompts/phase-1-deep-research-technical-review.md](reports/prompts/phase-1-deep-research-technical-review.md) -to create a source-cited draft outside Codex. Use -[../codex/prompts/95-validate-deep-research-report.md](../codex/prompts/95-validate-deep-research-report.md) -for the Phase 2 Codex cleanup and public-safety validation pass. +Use the +[Phase 0 preflight](reports/prompts/phase-0-codex-technical-review-preflight.md) +in Codex Max for a focused single-agent plan, or Ultra when meaningful +independent read-only lanes justify delegation. Load the governing prompt, +plan the review, and stop for maintainer approval. After approval, use the +[Phase 1 technical review](reports/prompts/phase-1-codex-technical-review.md) to +create a source-cited draft under the ignored `.technical-review-drafts/` +directory. Phase 1 may directly run safe validation commands when it records +the exact command, context, result, and limitations. Use the +[Phase 2 validation prompt](../codex/prompts/95-validate-technical-review-report.md) +for an independent cleanup, evidence check, and public-safety pass before +publishing the cleaned report under `docs/reports/`. ## Commands diff --git a/docs/getting-started.md b/docs/getting-started.md index 881c031..d8252ae 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -85,16 +85,21 @@ curl -sS -X POST http://127.0.0.1:8081/admin/bootstrap \ Then restart the server without the bootstrap secret in TOML, the environment, or the secret mount. Complete second-factor setup for the bootstrapped admin before running private admin actions or simulator flows that depend on admin -account access. +account access. For an established account with active TOTP, provide the current +short-lived code to the simulator through `PROOFLINE_SIM_TOTP_CODE`; the code is +used only to verify the new session and is not printed. ## Run The Simulator In another terminal from the repository root: ```bash +read -rsp 'Current simulator TOTP code: ' PROOFLINE_SIM_TOTP_CODE +export PROOFLINE_SIM_TOTP_CODE PROOFLINE_SIM_USERNAME=admin \ PROOFLINE_SIM_PASSWORD='replace-with-a-long-local-password' \ go run ./cmd/simclient --chunks 5 --interval 1s --download-bundle +unset PROOFLINE_SIM_TOTP_CODE ``` The simulator: diff --git a/docs/production-cluster-scope.md b/docs/production-cluster-scope.md index 22e19cd..c762249 100644 --- a/docs/production-cluster-scope.md +++ b/docs/production-cluster-scope.md @@ -3,12 +3,12 @@ This document records the production-cluster expansion path for Proofline Server. It is a planning and scope document for cluster-related work. Optional -PostgreSQL metadata, optional S3-compatible object storage, and optional -Valkey/Redis-compatible coordination startup checks, and local `/v1` -account/session authentication are implemented, but public product API -authentication, public account workflows, cloud deployment automation, -production hardening, and upload-operation use of coordination are not -implemented. +PostgreSQL metadata, optional S3-compatible object storage, optional +Valkey/Redis-compatible coordination for startup checks, route-class counters, +and short-lived complete-upload leases, and local `/v1` account/session +authentication are implemented. Public product API deployment, public account +workflows, cloud deployment automation, production hardening, and resumable or +partial upload sessions are not implemented. ## Current Local-First Scope @@ -76,8 +76,8 @@ PostgreSQL stores: - local account and session metadata - upload operation and idempotency state for complete chunk uploads - incident deletion decisions and retry state -- future trusted-contact, device, and broader access-control metadata, after - that design exists +- account/device recipient-key, trusted-contact relationship, contact-key, + sharing-grant, and wrapped-key metadata PostgreSQL support includes: @@ -162,15 +162,16 @@ no-overwrite behavior must still protect committed state from duplicates. ## Upload Operation Semantics -Future cluster upload handling should move toward explicit upload operations. -The detailed planning design is +Complete chunk uploads now use explicit durable upload operations when clients +supply `Idempotency-Key`, with optional short-lived coordination leases. The +detailed design and implemented boundary are documented in [Cluster-safe upload operation semantics](cluster-safe-upload-semantics.md). Resumable upload and partial-upload lease behavior is planned separately in [Resumable upload and upload lease protocol](resumable-upload-lease-protocol.md); that design keeps the local desktop recorder simulator on complete encrypted chunk retries while deferring resumable uploads and partial-upload sessions. -A safe cluster upload flow should be designed around these steps: +The implemented complete-upload path follows these steps: 1. Reserve or identify the upload operation using stable incident, stream, chunk index, media type, and idempotency metadata. 2. Stage encrypted bytes while enforcing staging pressure limits and computing SHA-256 over the uploaded ciphertext. @@ -268,6 +269,6 @@ Implementation PRs for this scope should update source-of-truth docs together, a - `docs/threat-model.md` - `docs/retention-backup-deletion.md` - `docs/code-map.md` -- release and Deep Research report prompts when review scope changes +- release and Codex technical-review prompts when review scope changes Backlog issues should be created or updated for each backend and cluster-safety milestone before implementation work starts. diff --git a/docs/reports/README.md b/docs/reports/README.md index dbd6404..8e3889b 100644 --- a/docs/reports/README.md +++ b/docs/reports/README.md @@ -19,10 +19,15 @@ Historical reports keep their original `Safety Recorder` titles, filenames, and ## Report Prompts -The source prompt for the first-pass Deep Research review lives in -[prompts/phase-1-deep-research-technical-review.md](prompts/phase-1-deep-research-technical-review.md). -The Phase 2 Codex validation workflow lives in -[../../codex/prompts/95-validate-deep-research-report.md](../../codex/prompts/95-validate-deep-research-report.md). +Run the +[Phase 0 preflight](prompts/phase-0-codex-technical-review-preflight.md) in Codex +Max for a focused single-agent plan, or Ultra when meaningful independent +read-only lanes justify delegation, and obtain maintainer approval before running the +[Phase 1 technical review](prompts/phase-1-codex-technical-review.md). Phase 1 +writes its source-cited report under the ignored `.technical-review-drafts/` +directory and records exact evidence for commands it executes. The independent +[Phase 2 Codex validation workflow](../../codex/prompts/95-validate-technical-review-report.md) +checks the draft and publishes the cleaned report under `docs/reports/`. Report prompts and reports must remain public-safe. Do not include raw tokens, secrets, private deployment details, exploit payloads, raw keys, plaintext media, diff --git a/docs/reports/prompts/phase-0-deep-research-preflight.md b/docs/reports/prompts/phase-0-codex-technical-review-preflight.md similarity index 63% rename from docs/reports/prompts/phase-0-deep-research-preflight.md rename to docs/reports/prompts/phase-0-codex-technical-review-preflight.md index c5f7a40..a14708e 100644 --- a/docs/reports/prompts/phase-0-deep-research-preflight.md +++ b/docs/reports/prompts/phase-0-codex-technical-review-preflight.md @@ -1,9 +1,16 @@ -# Phase 0 Deep Research Prompt: Load Report Instructions And Plan Research +# Phase 0 Codex Prompt: Load Report Instructions And Plan Research -Use this prompt in ChatGPT Deep Research before running the Phase 1 technical review report. +Use this prompt in Codex Max when the preflight is best handled as one focused +task. Use Ultra when the plan has meaningful independent read-only research +lanes that benefit from subagent delegation. Run it before the Phase 1 +technical review report. Do **not** produce the technical review report in this Phase 0 step. +Phase 0 is read-only. Do **not** edit files, generate issue drafts, create or +modify GitHub issues, change repository settings, switch branches, create +commits, or run destructive commands. + This prompt exists because the Phase 1 report prompt is strict. Phase 0 should load the current Phase 1 prompt from the repository, restate the governing rules, and produce a research plan for maintainer approval before the actual report is generated. ## Repository @@ -52,16 +59,22 @@ Review date: Phase 1 prompt path: ```text -docs/reports/prompts/phase-1-deep-research-technical-review.md +docs/reports/prompts/phase-1-codex-technical-review.md ``` Expected Phase 2 validation prompt path: ```text -codex/prompts/95-validate-deep-research-report.md +codex/prompts/95-validate-technical-review-report.md ``` -Target report path, if known: +Phase 1 draft output path: + +```text +.technical-review-drafts/-proofline--technical-review-draft.md +``` + +Expected Phase 2 final report path: ```text docs/reports/-proofline--technical-review.md @@ -70,12 +83,14 @@ docs/reports/-proofline--technical-review Model / tool disclosure: ```text -OpenAI ChatGPT Deep Research using +OpenAI Codex using with ``` ## Goal -Load and internalize the current Phase 1 prompt from the reviewed repository branch/ref or reviewed commit, then produce a research plan that follows that prompt. +Load and internalize the current Phase 1 prompt from the exact reviewed commit, +confirm the reviewed ref and commit context, then produce a research and +validation plan that follows that prompt. Phase 0 should make sure the actual Phase 1 report run will follow: @@ -92,17 +107,38 @@ Phase 0 should make sure the actual Phase 1 report run will follow: ## Required Preflight Steps -1. Open and read the current Phase 1 prompt from the reviewed branch/ref or commit: +1. Confirm that Codex is running with Max effort or Ultra mode, and record the + actual model, reasoning mode, and available tools or connectors. Do not imply + that an unavailable mode or tool was used. + +2. Inspect repository state with read-only commands: + + ```bash + git status --short --branch --untracked-files=all + git branch --show-current + git rev-parse HEAD + ``` + +3. Confirm that the reviewed branch/ref and full commit SHA inputs are complete. + Resolve the ref and confirm that it identifies ``. If the + commit is unavailable or the ref resolves to a different commit, stop and + report the mismatch instead of silently reviewing the current checkout. + +4. Open and read the current Phase 1 prompt from the exact reviewed commit with + a non-mutating read such as `git show`, unless the maintainer explicitly + supplies and approves a separate prompt-source ref: ```text - docs/reports/prompts/phase-1-deep-research-technical-review.md + docs/reports/prompts/phase-1-codex-technical-review.md ``` -2. Confirm the Phase 1 prompt path and source used. +5. Confirm the Phase 1 prompt path, prompt-source ref and commit, reviewed ref, + and reviewed commit used. Do not substitute the working-tree copy without + disclosing and obtaining approval for that different source. -3. Summarize the governing Phase 1 requirements in your own words. +6. Summarize the governing Phase 1 requirements in your own words. -4. Identify required repository files and directories to inspect, including: +7. Identify required repository files and directories to inspect, including: ```text README.md @@ -119,7 +155,7 @@ Phase 0 should make sure the actual Phase 1 report run will follow: .dockerignore ``` -5. Identify future-design and planning documents that must be reviewed when present, including but not limited to: +8. Identify future-design and planning documents that must be reviewed when present, including but not limited to: ```text docs/incident-modes.md @@ -129,27 +165,41 @@ Phase 0 should make sure the actual Phase 1 report run will follow: docs/ios-local-recorder-prototype.md ``` -6. Identify the authoritative external source categories required by the Phase 1 prompt, including the v0.8.0 optional backend-support areas: +9. Identify the authoritative external source categories required by the Phase + 1 prompt, including optional backend-support areas present in the reviewed + tree or claimed for the target release: - PostgreSQL metadata backend support - S3-compatible blob/object storage backend support - Valkey/Redis-compatible short-lived coordination backend support - exact Go client package documentation on `pkg.go.dev` when package behavior is discussed -7. Identify public governance posture, public voice, README baseline, +10. Identify public governance posture, public voice, README baseline, Apple/iOS/Swift, Android, web-client, protocol, legal-adjacent, or App Store/Play Store claims that would need primary sources if the report discusses them. -8. Identify the required Source Registry sections and what each section must contain. +11. Identify the required Source Registry sections and what each section must contain. -9. Identify the citation requirements, including repository citation pinning to ``. +12. Identify the citation requirements, including repository citation pinning to ``. -10. Identify the validation evidence policy, especially that Deep Research cannot run tests, containers, Docker builds, local shell commands, or simulator smoke tests, while still allowing authoritative external source consultation when available. +13. Identify safe, relevant validation commands that Phase 1 Codex should run + when the environment and task scope permit. Plan how Phase 1 will record the + exact command, result, reviewed commit context, limitations, and whether the + evidence came from this Codex run or was supplied separately. Do not execute + the Phase 1 validation plan during this Phase 0 preflight. If the current + checkout is dirty or does not exactly match ``, plan + repository inspection with `git show` and execution in a clean isolated + temporary copy of the reviewed commit. Do not plan to attribute current + working-tree results to the reviewed commit. -11. Identify public-safety restrictions, including prohibited raw tokens, secrets, request bodies, uploaded bytes, plaintext, raw keys, private deployment details, exploit payloads, and user-safety data. +14. Identify public-safety restrictions, including prohibited raw viewer or + incident tokens, secrets, request bodies, uploaded file bytes, Authorization + headers, plaintext, raw keys, wrapped-key ciphertext, private deployment + details, stored paths, object keys, exploit payloads, user-safety data, and + future token-like values. -12. Identify common false-positive patterns the Phase 1 report should avoid, including: +15. Identify common false-positive patterns the Phase 1 report should avoid, including: - treating documented future work as current defects - treating compatibility names as stale when docs explicitly preserve them @@ -157,9 +207,11 @@ Phase 0 should make sure the actual Phase 1 report run will follow: - treating interaction records as police-specific surveillance features - treating preserved compatibility identifiers as stale after the repository/module/artifact rename -13. Produce a proposed research plan. +16. Produce a proposed research and validation plan. Distinguish checks that are + safe and available, checks that require maintainer-supplied evidence or + additional authorization, and checks that are unavailable. -14. Stop and wait for maintainer approval before running the actual Phase 1 report. +17. Stop and wait for maintainer approval before running the actual Phase 1 report. ## Important Constraints @@ -167,13 +219,25 @@ Do **not** produce the technical review report in Phase 0. Do **not** treat this preflight as the Phase 1 report. -Do **not** claim tests, containers, Docker builds, local shell commands, GitHub repository settings, or simulator smoke tests were run unless supplied validation evidence proves that. +Do **not** change files, issue drafts, GitHub issues, repository settings, +branches, commits, tags, or the reviewed checkout during Phase 0. + +Do **not** claim tests, containers, Docker builds, local shell commands, live +service checks, GitHub repository settings, or simulator smoke tests were run +unless actual evidence from this Codex session or separately supplied evidence +proves that. A workflow definition or source-code inspection is not execution +evidence. -Do **not** use ChatGPT-rendered citations as final public Markdown citations. +Do **not** use tool-internal, renderer-only, or conversation-local citation IDs +as final public Markdown citations. This includes raw identifiers such as +`turnXfileY`, `turnXviewY`, `turnXsearchY`, `turnXfetchY`, or `turnXopenY`. Do **not** rely on repository-only evidence for external standards, platform, security, CI/CD, Docker, SQLite, dependency, license, Apple/iOS, Android, Swift, web-client, protocol, or legal-adjacent claims when the Phase 1 prompt requires authoritative external sources. -Do **not** include raw tokens, secrets, request bodies, uploaded bytes, plaintext, raw keys, private deployment details, exploit payloads, or user-safety data. +Do **not** include raw viewer or incident tokens, secrets, request bodies, +uploaded file bytes, Authorization headers, plaintext, raw keys, wrapped-key +ciphertext, private deployment details, stored paths, object keys, exploit +payloads, user-safety data, or future token-like values. Do **not** claim production readiness. @@ -228,7 +292,8 @@ open-proofline/website/docs/governance-and-political-alignment.md open-proofline/website/docs/repository-readme-baseline.md ``` -For the v0.8.0 optional backend-support review, also plan repository inspection for: +For optional backend-support areas present in the reviewed tree or claimed for +the target release, also plan repository inspection for: - PostgreSQL metadata backend implementation and documentation, including configuration, connection setup, migrations, schema behavior, transaction and constraint behavior, fallback/default behavior, tests or workflows, dependency declarations, and package usage - S3-compatible blob/object storage implementation and documentation, including configuration, connection setup, object key construction, upload/download behavior, immutability assumptions, hash/checksum handling, fallback/default behavior, tests or workflows, dependency declarations, and package usage @@ -312,14 +377,15 @@ Use specific documentation pages rather than broad homepages. For the optional b ### Validation Evidence -Identify validation evidence that was supplied or missing, such as: +Identify validation evidence that Phase 1 Codex can produce safely, that was +supplied separately, or that will remain missing, such as: ```text GitHub Actions run URLs local command output Codex command output uploaded validation summaries -gofmt output +non-mutating formatting-check output go test output go vet output Docker build output @@ -330,7 +396,18 @@ Valkey/Redis-compatible coordination test, smoke-test, or TTL behavior evidence attestation verification output ``` -If validation evidence is not supplied, the Phase 1 report must say the command or backend path was not independently executed or verified by Deep Research. For optional PostgreSQL metadata, S3-compatible storage, and Valkey/Redis-compatible coordination, distinguish code/docs review from live disposable-service execution or supplied smoke-test evidence. +The plan should name the safe commands Phase 1 Codex will attempt and the +conditions required to run them. Prefer non-mutating checks and disposable, +non-secret local test configuration. Do not plan commands that write to +production services, expose secrets or private deployment details, or modify +the reviewed source tree. Phase 1 should check repository state before and +after validation and report any unexpected change. + +If validation evidence is not produced or supplied, the Phase 1 report must say +that the command or backend path was not independently executed or verified by +Phase 1 Codex. For optional PostgreSQL metadata, S3-compatible storage, and +Valkey/Redis-compatible coordination, distinguish code/docs review from live +disposable-service execution or supplied smoke-test evidence. ## Source Registry Planning @@ -354,6 +431,10 @@ The plan should include the required registry sections from Phase 1: Every registry entry should include source ID, source type, location, commit/ref/date, review purpose, status, limitations, and related finding IDs or report sections where applicable. +The generated-artifacts section should record the Phase 1 draft path under +`.technical-review-drafts/` and the expected Phase 2 final report path under +`docs/reports/`. Phase 1 must not write directly to the final report path. + For optional backend-support areas, the plan should include example `S-*` keys for required authoritative sources. These are examples only; Phase 1 should use exact source keys for the specific sources actually consulted: ```text @@ -374,7 +455,9 @@ S-GO-VALKEY-CLIENT ## Citation Planning -The Phase 0 plan must restate that final public citations are handled through portable citation keys, not ChatGPT UI citation tokens. +The Phase 0 plan must restate that final public citations are handled through +portable citation keys, not tool-internal, renderer-only, or +conversation-local citation IDs. Portable key families: @@ -387,7 +470,9 @@ V-* for validation evidence Repository URLs must be pinned to ``, not `main`, `develop`, or a moving release branch. -If ChatGPT-rendered citations appear in the Phase 1 draft, the plan must instruct Phase 2 Codex validation to convert or replace them using the Source Registry. +If tool-internal or renderer-only citations appear in the Phase 1 draft, the +plan must instruct Phase 2 Codex validation to convert or replace them using the +Source Registry. ## Branch And Issue-Scope Planning @@ -401,6 +486,11 @@ The plan should require follow-up issue suggestions to distinguish: - planning-only findings - sensitive items that should not become public issues +Suspected or unresolved vulnerabilities must follow `SECURITY.md` and GitHub +private vulnerability reporting. Do not plan public issue drafts or public +GitHub issues for them. Public issues are limited to sanitized, non-vulnerability +hardening or documentation follow-up. + Any Phase 2-generated public issue drafts must include: ```text @@ -417,24 +507,34 @@ The Phase 0 plan should map the Phase 1 report to these broad areas: 1. Documentation consistency, Proofline naming, and compatibility-name notes 2. Current implementation versus future incident-mode planning 3. Go backend structure and idiomatic implementation -4. HTTP API behavior and private/public route separation +4. HTTP API behavior; separate main API/viewer and private-admin listener groups + and muxes; read-only public viewer paths; and private/public route separation 5. Viewer/incident token generation, hashing, storage, expiry, redaction, and viewer behavior 6. Logging, metrics, proxy examples, and sensitive data exposure 7. Upload handling, hash verification, immutable storage, upload limits, and stream-scoped chunk identity 8. SQLite and PostgreSQL metadata backend support, including configuration, schema/migrations, transactions, constraints, parity with SQLite where claimed, data-integrity boundaries, and validation-evidence limits 9. Local and S3-compatible blob/object storage support, including object key construction, upload/download behavior, immutability assumptions, hash/checksum handling, local-vs-object-store parity where claimed, path/key traversal risks, and fail-closed behavior 10. Optional Valkey/Redis-compatible coordination, including key expiry, short-lived coordination semantics, lock/session assumptions, failure behavior, fallback behavior, and avoiding persistence or security overclaiming -11. ZIP bundle generation, manifest completeness, fail-closed behavior, and path traversal handling +11. Encrypted ZIP chunk-bundle generation, manifest completeness, fail-closed + behavior, server-controlled entry names, no playable/decrypted-export + overclaiming, and path traversal handling 12. Crypto-adjacent simulator envelope and ciphertext-only backend boundary -13. Future key custody, browser/client-side decryption, break-glass, trusted-contact access, and server escrow boundaries -14. Future web/iOS/Android/protocol/client planning and platform assumptions +13. Recipient-key, trusted-contact, sharing-grant, and wrapped-key behavior + implemented at the reviewed commit, plus future production key custody, + browser/client-side decryption, trusted-contact review, break-glass, and + server escrow boundaries +14. Web-client companion status and scope applicable to the reviewed commit, + future iOS/Android/protocol/client planning, and platform assumptions 15. Deployment guidance, Traefik examples, WireGuard/private boundary, and rate limiting 16. Docker/GHCR/GitHub Actions/supply-chain hygiene 17. Public issue/report safety ## Risks, Ambiguities, And Maintainer Decisions Planning -The Phase 0 plan should identify maintainer decisions needed before Phase 1, including whether PostgreSQL metadata, S3-compatible object storage, and Valkey/Redis-compatible coordination should be treated as release-blocking v0.8.0 review areas or optional backend-support review areas. +The Phase 0 plan should identify maintainer decisions needed before Phase 1, +including whether PostgreSQL metadata, S3-compatible object storage, and +Valkey/Redis-compatible coordination should be treated as release-blocking +areas for the target release or optional backend-support review areas. The plan should also identify whether validation evidence exists for those backend paths. Absence of supplied validation evidence must be recorded as a limitation rather than guessed around. @@ -443,18 +543,23 @@ The plan should also identify whether validation evidence exists for those backe Return only a Phase 0 preflight response with this structure: ```markdown -# Phase 0 Deep Research Preflight +# Phase 0 Codex Technical Review Preflight ## Loaded prompt - Repository: - Product name / compatibility-name notes: +- Codex model and actual reasoning mode: +- Available tools and connectors: +- Current branch and HEAD: - Reviewed branch/ref: - Reviewed commit SHA: - Target release/version: - Phase 1 prompt path: +- Phase 1 prompt source ref and commit: - Phase 1 prompt source used: -- Target report path: +- Phase 1 draft output path: +- Expected Phase 2 final report path: ## Summary of governing Phase 1 rules @@ -492,14 +597,16 @@ Do not continue into Phase 1 until the maintainer explicitly approves the plan. After Phase 0 returns the plan, the maintainer may approve it with a short instruction such as: ```text -Approved. Run Phase 1 using the loaded `docs/reports/prompts/phase-1-deep-research-technical-review.md` as the governing prompt. +Approved. Run Phase 1 using the loaded `docs/reports/prompts/phase-1-codex-technical-review.md` as the governing prompt in Max, or in Ultra when meaningful independent research lanes justify delegation. Reviewed branch/ref: `` Reviewed commit SHA: `` Target release/version: `` Review date: `` +Phase 1 draft output path: `.technical-review-drafts/-proofline--technical-review-draft.md` +Expected Phase 2 final report path: `docs/reports/-proofline--technical-review.md` Follow the Source Registry, citation, validation-evidence, branch-scope, and public-safety rules from the loaded Phase 1 prompt. ``` -Only after that approval should Deep Research produce the Phase 1 technical review report. +Only after that approval should Codex produce the Phase 1 technical review draft. diff --git a/docs/reports/prompts/phase-1-deep-research-technical-review.md b/docs/reports/prompts/phase-1-codex-technical-review.md similarity index 57% rename from docs/reports/prompts/phase-1-deep-research-technical-review.md rename to docs/reports/prompts/phase-1-codex-technical-review.md index 00801f4..7c6f9f5 100644 --- a/docs/reports/prompts/phase-1-deep-research-technical-review.md +++ b/docs/reports/prompts/phase-1-codex-technical-review.md @@ -1,8 +1,15 @@ -# Phase 1 Deep Research Prompt: Public Technical Review Report +# Phase 1 Codex Prompt: Public Technical Review Report -Use this prompt in ChatGPT Deep Research, not in Codex. +Run this prompt in Codex Max when the review is best handled as one focused +task. Run it in Codex Ultra when the review has meaningful independent research +lanes that benefit from subagent delegation. Max applies maximum reasoning to +one task; Ultra adds coordinated subagent delegation. Do not use a lower-effort +mode, and do not create artificial parallel work merely to use Ultra. -This prompt creates the first-pass source-cited technical review report. The output must be validated and cleaned by the Phase 2 Codex workflow before publication. +This prompt creates the Phase 1 source-cited technical review draft. A separate +Phase 2 Codex workflow must validate, clean, and public-harden the draft before +publication. Phase 1 must not write the final report in place of that independent +validation pass. ## Inputs @@ -36,18 +43,27 @@ Review date: ``` -Target report path, if known: +Phase 1 draft report path: + +```text +.technical-review-drafts/-proofline--technical-review-draft.md +``` + +Final Phase 2 report path: ```text docs/reports/-proofline--technical-review.md ``` -Model / tool disclosure: +Model / Codex mode disclosure: ```text -OpenAI ChatGPT Deep Research using +OpenAI Codex using in ``` +Replace both placeholders with the model and mode actually used. Do not report +an intended model or mode that was not active for the Phase 1 run. + ## Repository Context Proofline is an experimental Go backend for private encrypted incident capture. @@ -75,71 +91,129 @@ The long-term product direction is broader than emergency-only recording. Planne Core project boundaries: - The main `/v1` API uses local account sessions but is not a public product API; it must stay behind the reviewed deployment boundary, and public edges must not route `/admin/api/...`. +- The main API/viewer routes and private `/admin` routes must remain on separate + listener groups and separate muxes. Public incident-viewer paths remain + read-only; public edges must not route private write or admin surfaces. - The current backend treats uploaded bytes as opaque ciphertext. +- Completed evidence bundles are encrypted chunk bundles, not decrypted or + playable media exports. ZIP entry names remain server-controlled. - The current backend must not be described as production-ready public infrastructure. - Current backend incidents are generic by default. Optional incident-mode, capture-profile, escalation-policy, and sharing-state metadata are labels only unless the reviewed tree implements first-class behavior for them. - Backend decryption, browser decryption, production key custody, break-glass - access, trusted-contact accounts, public account portals, OAuth/JWT, push - notifications, SMS, Messenger, production web/iOS/Android client behavior, - and first-class escalation policies are future or out-of-scope items unless - explicitly implemented in the reviewed tree. -- The post-quantum envelope is documented as a v1 preview requirement, but it - is not shipped runtime behavior unless implementation files prove it. + access, public account portals, OAuth/JWT, push notifications, SMS, + Messenger, production web/iOS/Android client behavior, and first-class + escalation policies are future or out-of-scope items unless explicitly + implemented in the reviewed tree. +- Recipient-key metadata, trusted-contact relationships, sharing grants, + wrapped-key storage or delivery, and related account behavior must be + described from code and tests at ``. Do not describe + those surfaces as wholly future when the reviewed commit implements them, + and do not infer production client decryption or complete key custody merely + from implemented metadata or API routes. +- The reviewed commit may implement some or all of the accepted post-quantum + envelope for server-side validation, wrapped-key profile validation, bundle + hints, or simulator reference flows. Verify each claimed component against + code and tests at ``; do not treat server or simulator + implementation as proof of completed web-client upload, review, decryption, + key custody, or cross-repository conformance. - V1 preview, v1.0.0, or real-user evidence-upload readiness claims must be checked against `docs/v1-preview-readiness-checklist.md` when that file is present. Passing ordinary tests is not enough to support preview-ready language if checklist hard blockers remain incomplete. -- Future key custody, browser decryption, break-glass, incident-mode, v1 - direction, post-quantum envelope, and client prototype documents are - design/planning guardrails or future preview requirements, not shipped - implementation. -- `open-proofline/web-client` may exist as a current experimental companion - repository. Do not treat that repository as absent when the project map - identifies it, and do not treat its existence as implemented server behavior - or production web-client readiness. +- Key custody, browser decryption, break-glass, incident-mode, v1 direction, + post-quantum envelope, and client documents may combine implemented behavior, + accepted design constraints, and future preview requirements. Classify each + claim from repository evidence at `` instead of treating + an entire document as either shipped implementation or future planning. +- Determine `open-proofline/web-client` status from the project map and + companion-repository evidence applicable to the reviewed commit. Do not call + it absent when those sources identify a current experimental companion, and + do not treat its existence as implemented server behavior or production + web-client readiness. - Do not treat documented future work as a current defect merely because it is not implemented. -## Validation Evidence Policy - -Deep Research cannot run repository tests, containers, Docker builds, local shell commands, or simulator smoke tests. - -This policy restricts claims about executing commands, tests, builds, containers, and smoke tests. It does not prohibit authoritative external web or source-document consultation. Deep Research may and should consult authoritative external documentation when available, as required by the Source Policy below. - -Do not write that review constraints prohibited network calls, web access, or external source consultation unless the maintainer explicitly imposed a no-network constraint for this review. - -Do not claim that Deep Research personally ran tests, built containers, executed Go commands, started the API server, ran the simulator, inspected live GitHub repository settings, or validated a Docker image by executing it. - -Use only supplied validation evidence, public CI results, uploaded logs, maintainer-supplied summaries, Codex-supplied command output, or repository workflow files when discussing test/build status. - -If no validation evidence is supplied for a command, state that the command was not independently verified by this report. +## Codex Execution And Validation Evidence Policy + +This is a read-only review workflow except for creating or updating the Phase 1 +draft at the path listed in Inputs. Do not change application code, tests, +migrations, workflows, configuration, source documentation, the final Phase 2 +report, GitHub settings, issues, or pull requests. Do not stage or commit files. + +Inspect the working tree before research and preserve all existing tracked and +untracked work. Never discard, overwrite, reformat, or incorporate unrelated +user changes into the draft. + +Record the current branch, current `HEAD`, reviewed branch/ref, and exact +``. Resolve `` and confirm it points +to `` before continuing; stop and report a mismatch. +Ground repository claims in that reviewed commit. If the current checkout is +not the reviewed commit, do not run a checkout-dependent command against `HEAD` +and attribute its result to the reviewed commit. Use a clean isolated copy, +commit-specific supplied evidence, or mark the command as not independently +executed for the reviewed commit. + +Even when `HEAD` equals ``, a dirty working tree is not the +reviewed commit. Use `git show :` or another +commit-addressed read for source inspection. Run tests, builds, or smoke checks +as reviewed-commit evidence only in a clean isolated temporary clone or archive +of that commit whose creation was approved in Phase 0. Do not switch, clean, +reset, reformat, or add a worktree to the maintainer's current checkout. Results +from a dirty working tree may be recorded only as current-workspace evidence, +never as proof about the reviewed commit. + +Codex may use non-mutating local shell inspection, run safe local validation in +an approved clean isolated copy of the reviewed commit, and consult +authoritative public web or source documentation. Do not access or change +private or production services. Do not run checks that require real secrets, +private deployment details, production credentials, or private service +endpoints. Disposable local services may be used only with synthetic test +credentials and temporary storage, and must not write generated artifacts into +the repository checkout. + +Claim that a command, test, build, container, smoke test, CI run, repository +setting, or external source was checked only when this Phase 1 run actually +checked it or when cited supplied evidence proves it. Record the exact command +or evidence, commit context, result, limitations, and whether it was generated +in this run or supplied by another source. If evidence is unavailable, state +that the check was not independently executed or verified; do not infer a pass. + +Do not write that review constraints prohibited network calls, web access, or +external source consultation unless the maintainer explicitly imposed that +constraint for this review. Recommended validation evidence to request or use when available: - exact reviewed branch/ref - exact reviewed commit SHA - GitHub Actions run URLs for the reviewed commit -- local or Codex output for `gofmt -w ./cmd ./internal ./migrations` -- local or Codex output for `go test ./...` -- local or Codex output for `go vet ./...` -- local or CI output for `docker build -t proofline-server .` -- local or Codex output for PostgreSQL integration tests: - -```bash -SAFE_POSTGRES_TEST_DSN='' go test ./internal/postgresdb -count=1 -``` - -- local or Codex output for S3-compatible blob storage tests or smoke tests using non-secret local/test credentials only -- local or Codex output for Valkey/Redis-compatible coordination startup-check tests or smoke tests +- Phase 1 output for the non-mutating formatting check + `gofmt -l ./cmd ./internal ./migrations` +- Phase 1 or supplied output for `go test ./...` +- Phase 1 or supplied output for `go vet ./...` +- Phase 1, local, or CI output for `docker build -t proofline-server .` +- supplied or public CI evidence for PostgreSQL integration tests, or Phase 1 + output from a disposable local test service that requires no secret DSN +- supplied or public CI evidence for S3-compatible blob storage tests or smoke + tests, or Phase 1 output using a disposable local service with fixed + non-secret test credentials only +- supplied or public CI evidence for Valkey/Redis-compatible coordination + startup-check tests or smoke tests, or Phase 1 output using a disposable local + service that requires no secrets - explicit note whether PostgreSQL, S3-compatible storage, and Valkey/Redis-compatible coordination were only reviewed from code/docs or also exercised with live disposable services -- local or Codex output for the simulator smoke test: - -```bash -go run ./cmd/simclient --chunks 5 --interval 1s --download-bundle -``` - -Do not put raw tokens, secrets, request bodies, uploaded bytes, plaintext, raw keys, private deployment details, exploit payloads, or user-safety data into validation summaries or the public report. +- Phase 1 or supplied output for the documented simulator smoke flow only when + Phase 1 starts a fresh disposable server on an explicit non-default loopback + URL, uses temporary storage and synthetic credentials, clears inherited + deployment and `PROOFLINE_SIM_*` configuration before setting explicit test + values, and proves it cannot target an existing local, private, or production + service. Otherwise, do not run the simulator and record the limitation. + +Do not put raw viewer, incident, session, or future token-like values; secrets; +Authorization headers; request bodies; uploaded file bytes; plaintext; raw keys; +wrapped-key ciphertext; private deployment details; stored paths; object keys; +exploit payloads; or user-safety data into validation summaries or the public +report. ## Source Policy @@ -218,14 +292,17 @@ Minimum requirements: - List required authoritative external source categories that were not consulted and explain why. - List validation commands that were actually supported by supplied evidence. - List validation commands that were not independently executed or not supported by supplied evidence. -- List generated report outputs, including the target report path if supplied. +- List the Phase 1 draft artifact and the final Phase 2 target path. Mark the + final path as a planned output that Phase 1 did not generate. - List active review connector/tool context, including whether web search was available. ## Citation Requirements Use portable citation keys only. -Do not use ChatGPT internal citation tokens such as renderer-only `filecite` / `cite` blocks or raw `turnXfileY`, `turnXviewY`, `turnXsearchY`, `turnXfetchY`, or `turnXopenY` references. +Do not use platform-internal or renderer-only citation identifiers such as +`filecite` / `cite` blocks or raw `turnXfileY`, `turnXviewY`, `turnXsearchY`, +`turnXfetchY`, or `turnXopenY` references. Use this citation style: @@ -276,8 +353,8 @@ When public governance posture, political alignment, public-good framing, public voice, reusable README baseline guidance, or source-of-truth mapping is in scope, inspect the website source documents listed in Repository Context. When the report discusses web-client behavior or prototype limits, inspect the -current `open-proofline/web-client` source documents if accessible, and clearly -separate companion-repository behavior from server behavior. +companion-repository sources applicable to the reviewed commit when accessible, +and clearly separate companion-repository behavior from server behavior. Technical focus areas: @@ -293,9 +370,12 @@ Technical focus areas: 10. Optional Valkey/Redis-compatible coordination startup checks, failure behavior, and non-durable coordination boundaries 11. ZIP bundle generation, manifest completeness, fail-closed behavior, and path traversal handling 12. Crypto-adjacent simulator envelope, ciphertext-only backend boundary, and naming-compatibility claims -13. Future key custody, browser/client-side decryption, break-glass, trusted-contact access, and server escrow boundaries -14. Current web-client companion scope, future iOS/Android/protocol/client - planning, and platform assumptions +13. Recipient-key, trusted-contact, sharing-grant, and wrapped-key behavior + implemented at the reviewed commit, plus future production key custody, + browser/client-side decryption, trusted-contact review, break-glass, and + server escrow boundaries +14. Web-client companion status and scope applicable to the reviewed commit, + future iOS/Android/protocol/client planning, and platform assumptions 15. Deployment guidance, Traefik examples, WireGuard/private boundary, rate limiting, and no `/v1` public exposure 16. Docker/GHCR/GitHub Actions/supply-chain hygiene 17. Public issue/report safety @@ -315,12 +395,24 @@ For every finding, include: - reviewed branch/ref and commit context - why it matters - minimal actionable fix -- suggested GitHub issue title +- follow-up handling: GitHub private vulnerability reporting, sanitized public + hardening/documentation issue, non-security issue, or none +- suggested GitHub issue title only for a sanitized non-vulnerability follow-up - acceptance criteria Do not inflate severity merely because a finding is security-adjacent. If a limitation is already documented as out of scope, classify it as a non-finding or future-work item unless there is a contradiction between docs and code. -Do not recommend public GitHub issues for private vulnerabilities, raw tokens, secrets, exploit details, private deployment details, or user safety data. +Do not recommend public GitHub issues containing private vulnerability details, +raw or future token-like values, secrets, Authorization headers, request bodies, +uploaded file bytes, plaintext, raw keys, wrapped-key ciphertext, private +deployment details, stored paths, object keys, exploit details, or user-safety +data. + +Route suspected or unresolved vulnerabilities through `SECURITY.md` and GitHub +private vulnerability reporting. Do not put exploitability, reproduction, or +remediation details for an unresolved vulnerability in the public technical +review draft or a public issue suggestion. A sanitized public hardening issue is +appropriate only when it does not disclose a vulnerability. ## Common False Positives To Avoid @@ -329,11 +421,19 @@ Do not recommend public GitHub issues for private vulnerabilities, raw tokens, s incident modes, capture profiles, escalation policies, sharing state, browser decryption, production key custody, or break-glass behavior is a defect when docs mark those as future work. -- Do not say `open-proofline/web-client` is missing when current project docs - mark it as an existing experimental companion repository. -- Do not describe the post-quantum envelope as implemented unless code proves - it. If reviewing a v1 preview readiness claim, verify that the post-quantum - envelope is implemented, documented, tested, and default. +- Do not say `open-proofline/web-client` is missing when the project map and + companion-repository evidence applicable to the reviewed commit identify it + as an existing experimental companion repository. +- Do not describe recipient-key, trusted-contact, sharing-grant, or wrapped-key + behavior as wholly absent or wholly future when code at the reviewed commit + proves an implemented metadata or API surface. Do not overstate that surface + as completed production key custody or client-side review. +- Do not describe the post-quantum envelope as wholly future when code at the + reviewed commit proves implemented server or simulator behavior, and do not + describe it as fully implemented across server, web-client, key custody, and + review paths unless evidence proves each component. If reviewing a v1 preview + readiness claim, verify that the required envelope behavior is implemented, + documented, tested, and default across the claimed preview paths. - Do not describe Proofline as ready for v1 preview, v1.0.0, or real-user evidence upload unless the reviewed tree satisfies the v1 preview readiness checklist hard blockers. @@ -380,4 +480,7 @@ The report should use this structure: ## Citation References ``` -The report must clearly separate implemented behavior from future planning, preserve public-safety restrictions, and avoid production-readiness claims. +Write the Phase 1 report only to the draft path listed in Inputs. Do not write +or replace the final Phase 2 report. The draft must clearly separate implemented +behavior from future planning, preserve public-safety restrictions, and avoid +production-readiness claims. diff --git a/docs/simulator.md b/docs/simulator.md index daa4c5f..2cd1882 100644 --- a/docs/simulator.md +++ b/docs/simulator.md @@ -102,17 +102,27 @@ bootstrap secret from TOML, the environment, or the secret mount and restart the server. See [deployment](deployment.md) for the bootstrap flow. -Then run: +For a disposable fresh database, the simulator can complete the new account's +required TOTP setup in the same session. This setup path intentionally does not +print or persist the TOTP seed, so use it only with account state that will be +discarded after the smoke test: ```bash PROOFLINE_SIM_USERNAME=admin \ PROOFLINE_SIM_PASSWORD='replace-with-a-long-local-password' \ -go run ./cmd/simclient --chunks 12 --interval 5s +go run ./cmd/simclient --chunks 12 --interval 5s \ + --setup-totp-second-factor ``` The simulator creates a read-only incident viewer token for the flow but omits token-bearing viewer URLs from output. +For an established local account with active TOTP, provide the current +short-lived code through `PROOFLINE_SIM_TOTP_CODE`. The simulator uses it only +to verify the new session and does not print it. Do not put TOTP codes in +committed files, terminal output, or issue text. Active email-only or +WebAuthn-only session challenges are not automated by `simclient`. + ## Relay Upload Mode Relay upload mode is opt-in and requires both the main API base URL and the @@ -473,10 +483,10 @@ session token. The standard simulator can call the duplicate chunk reconciliation route with `--reconcile-duplicate` to compare a local expected chunk fingerprint with -accepted server metadata without re-uploading ciphertext. Broader desktop -recorder ambiguous-network and process-restart reconciliation drills remain -future work planned in -[cluster-safe-upload-semantics.md](cluster-safe-upload-semantics.md). +accepted server metadata without re-uploading ciphertext. Desktop recorder +retries and process restarts reuse the durable staged bytes and stable +`Idempotency-Key`. The separate reconciliation drill remains +direct-upload-only; desktop and relay modes do not call that endpoint. ## Poor-Network Desktop Controls @@ -516,6 +526,7 @@ attempts and durable metadata for accepted chunks. | `--relay-url` | Stream-ingress relay base URL. Required when `--upload-mode=relay`; rejected for direct mode. | | `--username` | Proofline account username. Defaults to `PROOFLINE_SIM_USERNAME`. | | `--password` | Proofline account password. Defaults to `PROOFLINE_SIM_PASSWORD`. | +| `--setup-totp-second-factor` | Enroll and verify TOTP before product-route calls for a fresh account whose required setup is incomplete. Use only with disposable/local test account state. | | `--chunks` | Number of chunks to upload. | | `--interval` | Delay between chunk uploads. | | `--chunk-size` | Size of each fake plaintext chunk before optional encryption. | diff --git a/docs/v1-preview-direction.md b/docs/v1-preview-direction.md index 4d2c507..c1a4348 100644 --- a/docs/v1-preview-direction.md +++ b/docs/v1-preview-direction.md @@ -191,7 +191,7 @@ prefer neutral user-facing language like `Interaction record`. | Post-quantum envelope | Server upload validation, wrapped-key metadata validation, bundle profile hints, docs, and simulator uploads now default to the accepted PQ profile. Web-client evidence upload and review still belong to companion-repository work. | Keep the accepted PQ profile as the preview default across server and web-client evidence upload, wrapped-key delivery, and review flows. | | Browser recording | Not implemented. | In scope for v1 preview as a reviewed secondary/fallback capture path, not a replacement for native mobile reliability. | | Browser decryption | Not implemented. | In scope for authorized account-owner or trusted-contact review after browser trust model, key custody, and deployment-integrity decisions are accepted. | -| Trusted contacts | Owner-scoped metadata for contact public keys, grants, and wrapped keys. | Account-based trusted-contact invite/accept, grant-scoped review, wrapped-key delivery, and client-side decrypt UX. | +| Trusted contacts | Account-to-account invite/accept relationships, owner-scoped contact public keys and grants, and authenticated grant-scoped wrapped-key delivery. Incident reads and client-side decrypt UX are not implemented. | Complete the trusted-contact review and client-side decrypt UX without expanding the backend's ciphertext-only role. | | Device sharing | Not implemented. | Each device should have its own key material. Existing trusted devices or a recovery flow should approve new devices, then rewrap relevant CEKs to the new device recipient key. | | Regional relay | Health/readiness routes with safe aggregate readiness categories, configured backend-issued upload and fanout capabilities for authorized open streams, service-authenticated core relay preflight/commit/fanout authorization endpoints, configured complete-chunk upload forwarding with temporary ciphertext staging, optimistic encrypted fanout marked unconfirmed, and bounded backend confirmation/rejection state. | Optional temporary, ciphertext-only relay listener subordinate to the core API, with replay, metrics, production service identity, and deployment hardening only after separate review. | | Public registration and required setup | Disabled by default; open mode requires SMTP verification; paid mode fails closed. New admin-created and open-registration accounts carry required setup state that blocks main product routes until email challenge, TOTP, or configured WebAuthn setup is completed. Active email challenge, TOTP, and WebAuthn factors require per-session verification. | Explicit preview deployments may enable open registration with email verification, rate limits, deployment controls, account-scoped committed blob quota, configured WebAuthn/passkey factors, and a reviewed recovery policy. | @@ -724,9 +724,10 @@ Current docs are broadly aligned, but future work should watch these seams: - Current server and web-client docs describe browser decryption and recording as not implemented. That remains true, but neither should be treated as a permanent v1 preview non-goal. -- Current post-quantum envelope docs describe an implementation plan, not - runtime behavior. That remains true now, but the post-quantum envelope should - be treated as a v1 preview requirement, not optional later hardening. +- The accepted post-quantum envelope is now enforced for new chunk uploads and + wrapped-key metadata, and the simulator uses it by default. Companion-client + upload, key-custody, and decrypt UX still need to adopt and validate the same + profile before v1 preview. - Current billing docs describe a future Stripe-hosted service boundary. That should not become a default v1 preview requirement unless separately scoped. - Current runtime protocol and default data-layout identifiers use Proofline diff --git a/internal/httpapi/admin_web_session.go b/internal/httpapi/admin_web_session.go index 92d2493..63a6f60 100644 --- a/internal/httpapi/admin_web_session.go +++ b/internal/httpapi/admin_web_session.go @@ -22,10 +22,6 @@ func (a *API) parseAdminWebForm(w http.ResponseWriter, r *http.Request, data adm return true } -func (a *API) parseAdminWebDashboardForm(w http.ResponseWriter, r *http.Request, principal privatePrincipal, message string) bool { - return a.parseAdminWebPageForm(w, r, principal, adminWebPageOverview, message) -} - func (a *API) parseAdminWebPageForm(w http.ResponseWriter, r *http.Request, principal privatePrincipal, page, message string) bool { r.Body = http.MaxBytesReader(w, r.Body, fieldLimit) defer r.Body.Close() diff --git a/internal/httpapi/auth_test.go b/internal/httpapi/auth_test.go index c19db60..45fa39e 100644 --- a/internal/httpapi/auth_test.go +++ b/internal/httpapi/auth_test.go @@ -1003,7 +1003,7 @@ func TestTOTPActiveFactorRequiresSessionChallengeAfterLogin(t *testing.T) { response, body = requestWithAuth(t, app.privateHandler, http.MethodPost, "/v1/account/second-factor/totp/verify", "application/json", bytes.NewBufferString(`{"code":"`+code+`"}`), loginResult.Token) response.Body.Close() if response.StatusCode != http.StatusOK { - t.Fatalf("TOTP session verify status = %d, want 200", response.StatusCode) + t.Fatalf("TOTP session verify status = %d, want 200: %s", response.StatusCode, body) } response, body = requestWithAuth(t, app.privateHandler, http.MethodPost, "/v1/incidents", "application/json", bytes.NewBufferString(`{}`), loginResult.Token) @@ -1082,7 +1082,7 @@ func TestTOTPActiveFactorRequiresBrowserCookieSessionChallenge(t *testing.T) { }) response.Body.Close() if response.StatusCode != http.StatusOK { - t.Fatalf("TOTP cookie verify status = %d, want 200", response.StatusCode) + t.Fatalf("TOTP cookie verify status = %d, want 200: %s", response.StatusCode, body) } response, body = requestWithCookieAndHeaders(t, app.privateHandler, http.MethodPost, "/v1/incidents", "application/json", bytes.NewBufferString(`{}`), cookie, map[string]string{ @@ -1130,7 +1130,7 @@ func TestTOTPRejectsInvalidReplayAndStaleEnrollmentCodes(t *testing.T) { response, body = requestWithAuth(t, app.privateHandler, http.MethodPost, "/v1/account/second-factor/totp/verify", "application/json", bytes.NewBufferString(`{"code":"`+code+`"}`), loginToken) response.Body.Close() if response.StatusCode != http.StatusOK { - t.Fatalf("valid TOTP status = %d, want 200", response.StatusCode) + t.Fatalf("valid TOTP status = %d, want 200: %s", response.StatusCode, body) } response, body = requestWithAuth(t, app.privateHandler, http.MethodPost, "/v1/account/second-factor/totp/verify", "application/json", bytes.NewBufferString(`{"code":"`+code+`"}`), loginToken) defer response.Body.Close() diff --git a/internal/httpapi/main_rate_limit.go b/internal/httpapi/main_rate_limit.go index 449d67a..0a9116d 100644 --- a/internal/httpapi/main_rate_limit.go +++ b/internal/httpapi/main_rate_limit.go @@ -26,10 +26,6 @@ const ( mainRateLimitDownload mainRateLimitClass = "download" ) -func (a *API) mainRateLimitMiddleware(next http.Handler) http.Handler { - return a.mainRateLimitMiddlewareWithClassFilter(next, nil) -} - func (a *API) mainAPIRouteRateLimitMiddleware(next http.Handler) http.Handler { return a.mainRateLimitMiddlewareWithClassFilter(next, func(class mainRateLimitClass) bool { return class != mainRateLimitBootstrap @@ -138,9 +134,9 @@ func classifyMainAPIRateLimit(r *http.Request) (mainRateLimitClass, bool) { } } case "account-recipient-keys": - return classifyMainAPIAccountRecipientKeyRateLimit(r, segments) + return classifyMainAPIKeyMetadataRateLimit(r, segments) case "contact-public-keys": - return classifyMainAPIContactPublicKeyRateLimit(r, segments) + return classifyMainAPIKeyMetadataRateLimit(r, segments) case "trusted-contact-relationships": return classifyMainAPITrustedContactRelationshipRateLimit(r, segments) case "trusted-contact": @@ -199,22 +195,10 @@ func classifyMainAPIAuthRateLimit(r *http.Request, segments []string) (mainRateL return "", false } -func classifyMainAPIContactPublicKeyRateLimit(r *http.Request, segments []string) (mainRateLimitClass, bool) { - switch { - case len(segments) == 2 && (r.Method == http.MethodGet || r.Method == http.MethodPost): - return mainRateLimitAccount, true - case len(segments) == 3 && (r.Method == http.MethodGet || r.Method == http.MethodPatch): - return mainRateLimitAccount, true - case len(segments) == 4 && r.Method == http.MethodPost: - switch segments[3] { - case "revoke", "lost", "replace": - return mainRateLimitAccount, true - } - } - return "", false -} - -func classifyMainAPIAccountRecipientKeyRateLimit(r *http.Request, segments []string) (mainRateLimitClass, bool) { +// classifyMainAPIKeyMetadataRateLimit keeps the account-recipient-key and +// contact-public-key route families on the same account-scoped limit. Their +// collection, item, and lifecycle route shapes intentionally match. +func classifyMainAPIKeyMetadataRateLimit(r *http.Request, segments []string) (mainRateLimitClass, bool) { switch { case len(segments) == 2 && (r.Method == http.MethodGet || r.Method == http.MethodPost): return mainRateLimitAccount, true diff --git a/internal/incidents/wrapped_keys.go b/internal/incidents/wrapped_keys.go index ad3dff0..af55264 100644 --- a/internal/incidents/wrapped_keys.go +++ b/internal/incidents/wrapped_keys.go @@ -340,15 +340,6 @@ func activeGrantForWrappedKey(ctx context.Context, tx *sql.Tx, params CreateWrap return grant, nil } -func (r *Repository) getWrappedKeyRecordForOwner(ctx context.Context, ownerAccountID, wrappedKeyID string) (WrappedKeyRecord, error) { - row := r.db.QueryRowContext(ctx, wrappedKeyRecordSelect()+` - WHERE w.owner_account_id = ? AND w.id = ?`, - ownerAccountID, - wrappedKeyID, - ) - return scanWrappedKeyRecordForOwner(row) -} - func getWrappedKeyRecordForOwnerTx(ctx context.Context, tx *sql.Tx, ownerAccountID, wrappedKeyID string) (WrappedKeyRecord, error) { row := tx.QueryRowContext(ctx, wrappedKeyRecordSelect()+` WHERE w.owner_account_id = ? AND w.id = ?`, diff --git a/internal/postgresdb/wrapped_keys.go b/internal/postgresdb/wrapped_keys.go index bade2b6..edd4116 100644 --- a/internal/postgresdb/wrapped_keys.go +++ b/internal/postgresdb/wrapped_keys.go @@ -342,15 +342,6 @@ func activeGrantForWrappedKey(ctx context.Context, tx *sql.Tx, params incidents. return grant, nil } -func (r *Repository) getWrappedKeyRecordForOwner(ctx context.Context, ownerAccountID, wrappedKeyID string) (incidents.WrappedKeyRecord, error) { - row := r.db.QueryRowContext(ctx, wrappedKeyRecordSelect()+` - WHERE w.owner_account_id = $1 AND w.id = $2`, - ownerAccountID, - wrappedKeyID, - ) - return scanWrappedKeyRecordForOwner(row) -} - func getWrappedKeyRecordForOwnerTx(ctx context.Context, tx *sql.Tx, ownerAccountID, wrappedKeyID string) (incidents.WrappedKeyRecord, error) { row := tx.QueryRowContext(ctx, wrappedKeyRecordSelect()+` WHERE w.owner_account_id = $1 AND w.id = $2`, From b951057ce568d76089d5309c0c0dd328c7506e9c Mon Sep 17 00:00:00 2001 From: Ellie Melton Date: Sat, 11 Jul 2026 17:48:50 +1000 Subject: [PATCH 2/4] docs: publish unreleased technical review --- ...0-proofline-unreleased-technical-review.md | 588 ++++++++++++++++++ 1 file changed, 588 insertions(+) create mode 100644 docs/reports/2026-07-10-proofline-unreleased-technical-review.md diff --git a/docs/reports/2026-07-10-proofline-unreleased-technical-review.md b/docs/reports/2026-07-10-proofline-unreleased-technical-review.md new file mode 100644 index 0000000..81ec717 --- /dev/null +++ b/docs/reports/2026-07-10-proofline-unreleased-technical-review.md @@ -0,0 +1,588 @@ +# Technical Review of Proofline unreleased + +- Review date: 2026-07-10 +- Phase 2 validation date: 2026-07-11 +- Current checkout branch: `upgrade-codex-reports-and-repo-full-validation-security-review` +- Current checkout HEAD at review start: `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a` +- Initial working-tree status: clean; `git status --short --branch --untracked-files=all` reported only the branch/upstream header +- Reviewed branch/ref: `upgrade-codex-reports-and-repo-full-validation-security-review` +- Reviewed commit SHA: `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a` +- Target release/version: `unreleased` +- Phase 1 draft path: `.technical-review-drafts/2026-07-10-proofline-unreleased-technical-review-draft.md` +- Final Phase 2 report path: `docs/reports/2026-07-10-proofline-unreleased-technical-review.md` +- Issue handling mode: `drafts_only` +- Phase 1 model/tool disclosure: OpenAI Codex using GPT-5.6 Sol in Ultra mode. +- Phase 2 validation tool: OpenAI Codex using independent source, execution-evidence, citation, and disclosure-safety checks. + +**Publication status:** Independent Phase 2 validation is complete for this report of the reviewed SHA. Phase 2 created only this public-hardened report and ignored branch-scoped local issue drafts; it did not create GitHub issues, private vulnerability reports, pull requests, releases, or repository-setting changes. No matching disposable review container, network, volume, image, or temporary checkout remained at handoff. Suspected vulnerabilities remain routed to GitHub private vulnerability reporting, and public reproduction or exploit detail is intentionally omitted. [R-REPORT-PROMPT] [R-PHASE2-PROMPT] [R-SECURITY] [V-PHASE2-PUBLICATION] [V-PHASE2-CLEANUP] + +This is a technical review, not a formal security audit, penetration test, compliance certification, legal review, production-readiness endorsement, or release approval. + +## Executive Summary + +The reviewed commit is **not ready for release in its present state**. The review identified one High-severity, six Medium-severity, and five Low-severity findings. The public findings cover the pinned Go security patch level, optional PostgreSQL and S3 correctness, release-control enforcement, and optional-backend test reproducibility. Details of suspected or unresolved vulnerabilities are reserved for GitHub private vulnerability reporting. + +Release-blocking findings are F-001 through F-009. F-012 is also release-blocking under the maintainer's Phase 0 decision that optional-backend findings block this release. F-010 and F-011 require private triage but were not independently elevated to release blockers because their demonstrated effects are bounded. The release decision is based on source behavior and release controls, not on a failed happy-path smoke test. + +Phase 1 recorded broad positive validation evidence. In a clean isolated copy of the exact reviewed SHA, formatting, Markdown links, the full Go test suite, vet, race tests, both application build paths, the disposable PostgreSQL/MinIO/Valkey stack, an induced retry-path stack, live PostgreSQL integration tests, an S3 deletion smoke, and relay packaging all passed; aggregate statement coverage was 54.6%. Phase 2 independently reran formatting, the 112-file Markdown link check, the full Go test suite, vet, and clean-tree checks in a separate disposable exact-SHA clone. It inspected rather than repeated the Phase 1 race, coverage, Docker, and optional-backend stack evidence. [V-LOCAL-BASE] [V-LOCAL-FULLSTACK] [V-LOCAL-EXTENDED] [V-PHASE2-RECHECK] + +Those passes do not clear the release. Public GitHub Actions for the reviewed SHA failed at `Go vulnerability scan`: the repository and pinned builder stages select Go 1.26.4, while the authoritative Go vulnerability entry is fixed in Go 1.26.5. Product-specific applicability was not established in this public report and is reserved for private triage. [R-GO-TOOLCHAIN] [R-DOCKERFILE] [R-DOCKERFILE-INGRESS] [V-CI-RUN] [S-GO-RELEASE] [S-GO-VULN-5856] + +The reviewed tree correctly presents Proofline as experimental, maintainer-led, ciphertext-only backend infrastructure rather than a production service. Main API/viewer and private-admin listeners remain separated; public viewer routes are read-only; encrypted bundle generation re-verifies stored chunk size and digest; viewer and session tokens are hashed at rest; and current/future product boundaries remain conservative. The latest website and web-client default-branch sources support that framing. [R-README] [R-CHANGELOG] [R-CMD-SERVERS] [R-HTTPAPI-ROUTES] [R-EVIDENCE-BUNDLE] [R-BUNDLE-HTTP] [R-VIEWER-TOKENS] [R-AUTH-REPOSITORIES] [R-AUTH-POSTGRES] [R-WEBSITE-GOV] [R-WEBCLIENT-README] + +The maintainer confirmed during Phase 2 that there are no known public or private deployments. The review therefore found no known deployed-user exposure. That deployment context lowers present disclosure sensitivity, but it does not change the technical findings, release-blocking decisions, or the private-reporting path required for unresolved vulnerabilities. [V-MAINTAINER-CONTEXT] [R-SECURITY] + +The v1-preview readiness result remains **Not ready for v1 preview claim**. This review concerns an ordinary experimental pre-v1 release, and passing the ordinary validation set must not be converted into a real-user, public `/v1`, or production-readiness claim. [R-V1-CHECKLIST] + +## Source Registry + +### Repository sources inspected + +All server repository URLs below are pinned to the reviewed SHA. A grouped row lists every materially relied-on file in that evidence family. + +| Source ID | Source type and location | Commit/ref/date | Purpose | Status | Limitations | Related findings/sections | +|---|---|---|---|---|---|---| +| R-REPORT-PROMPT | Review policy: [`docs/reports/prompts/phase-1-codex-technical-review.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/reports/prompts/phase-1-codex-technical-review.md) | Server SHA `e609ff8`; 2026-07-10 | Governing scope, source, citation, validation, public-safety, and output rules | Inspected in full | Process evidence, not runtime behavior | All sections | +| R-PHASE2-PROMPT | Phase 2 policy: [`codex/prompts/95-validate-technical-review-report.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/codex/prompts/95-validate-technical-review-report.md) | Server SHA `e609ff8`; executed 2026-07-11 | Independent validation, public-hardening, issue-draft, and publication rules | Inspected in full and executed | Process evidence, not runtime behavior | Publication status; Phase 2 method | +| R-PRIOR-REPORT | Prior technical review: [`docs/reports/2026-06-13-proofline-v0.11.0-rc.1-technical-review.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/reports/2026-06-13-proofline-v0.11.0-rc.1-technical-review.md) | Server SHA `e609ff8`; re-read 2026-07-11 | Commit-pinned comparison for previously reported bundle-integrity work | Inspected | Historical review evidence; current implementation was checked directly | Non-findings | +| R-DOCS-INDEX / R-V1-DIRECTION / R-INCIDENT-MODES / R-SECURITY-MODEL / R-THREAT-MODEL / R-API / R-ENCRYPTION | Current and current-versus-future guidance: [`docs/README.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/README.md), [`docs/v1-preview-direction.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/v1-preview-direction.md), [`docs/incident-modes.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/incident-modes.md), [`docs/security-model.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/security-model.md), [`docs/threat-model.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/threat-model.md), [`docs/api.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/api.md), and [`docs/encryption.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/encryption.md) | Server SHA `e609ff8`; re-read 2026-07-11 | Product boundaries, implemented API/security behavior, incident-label limits, ciphertext posture, and v1 direction | Required Phase 2 reads completed; v1 direction read to EOF | Documentation does not replace commit-addressed implementation evidence | Executive summary; implementation summary; non-findings | +| R-KEY-CUSTODY / R-BROWSER-DECRYPTION / R-BREAK-GLASS / R-IOS-PLAN | Future-design guidance: [`docs/key-custody.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/key-custody.md), [`docs/browser-decryption.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/browser-decryption.md), [`docs/break-glass-key-access.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/break-glass-key-access.md), and [`docs/ios-local-recorder-prototype.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/ios-local-recorder-prototype.md) | Server SHA `e609ff8`; re-read 2026-07-11 | Separate future production custody, client decryption, break-glass, and mobile capture from current server behavior | Required Phase 2 reads completed | Planning sources do not implement the described clients or key access | Implementation summary; false-positive review | +| R-README / R-SECURITY / R-CHANGELOG / R-AGENTS | Project boundaries: [`README.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/README.md), [`SECURITY.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/SECURITY.md), [`CHANGELOG.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/CHANGELOG.md), [`AGENTS.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/AGENTS.md) | Server SHA `e609ff8`; 2026-07-10 | Current status, component ownership, security-reporting route, release wording, review constraints | Inspected | Documentation does not prove deployment behavior | Executive summary, boundaries, handling | +| R-CMD-API / R-CMD-SERVERS | Startup and listener construction: [`cmd/api/main.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/cmd/api/main.go), [`cmd/api/servers.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/cmd/api/servers.go) | Server SHA `e609ff8`; checked 2026-07-10 | Backend initialization, dependency checks, handler/listener split | Inspected; startup exercised in disposable stacks | No deliberately invalid S3 startup was run | F-007; non-findings | +| R-HTTPAPI-ROUTES / R-HTTPAPI-API | Route and middleware construction: [`internal/httpapi/routes.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/routes.go), [`internal/httpapi/api.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/api.go) | Server SHA `e609ff8`; checked 2026-07-10 | Main/private route separation and middleware placement | Inspected; route boundaries exercised by tests and relay smoke | Not a public-edge deployment test | Non-findings | +| R-AUTH-HANDLERS / R-ADMIN-WEB-AUTH / R-AUTH-MIDDLEWARE | Authentication flows: [`internal/httpapi/auth_handlers.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/auth_handlers.go), [`internal/httpapi/admin_web_handlers.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/admin_web_handlers.go), [`internal/httpapi/auth_middleware.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/auth_middleware.go) | Server SHA `e609ff8`; checked 2026-07-10 | Authentication and session lifecycle | Inspected | No production traffic or account data was used | Non-findings | +| R-TOTP / R-AUTH-REPOSITORIES / R-AUTH-POSTGRES | Auth primitives and persistence: [`internal/auth/totp.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/auth/totp.go), [`internal/incidents/auth.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/auth.go), [`internal/postgresdb/auth.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/auth.go) | Server SHA `e609ff8`; checked 2026-07-10 | Authentication policy and SQLite/PostgreSQL session persistence | Inspected; ordinary repository tests passed | No production traffic or account data was used | Non-findings | +| R-WEB-AUTH-CONTROLS / R-WEB-AUTH-TESTS | Browser-session controls and tests: [`internal/httpapi/web_auth.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/web_auth.go), [`internal/httpapi/web_cors.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/web_cors.go), [`internal/httpapi/admin_web_session.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/admin_web_session.go), [`internal/config/web_auth.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/config/web_auth.go), [`internal/httpapi/auth_test.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/auth_test.go), and [`internal/httpapi/admin_web_test.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/admin_web_test.go) | Server SHA `e609ff8`; checked 2026-07-10 | Cookie attributes, CSRF binding, credentialed-CORS allowlisting, auth-mode ambiguity rejection, and separate admin session policy | Inspected; relevant tests passed | Loopback-local and private-admin exceptions remain explicit configuration choices | Non-findings | +| R-VIEWER-TOKENS / R-VIEWER-TOKEN-SQLITE / R-VIEWER-TOKEN-POSTGRES / R-VIEWER-TOKEN-TESTS | Viewer-token implementation and tests: SQLite [`identifier generation`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/ids.go) and [`token persistence`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/incident_tokens.go); PostgreSQL [`identifier generation`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/ids.go) and [`token persistence`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/incident_tokens.go); [`HTTP handling/tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/incident_viewer.go), [`viewer tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/incident_viewer_test.go), and [`PostgreSQL contract tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/postgresdb_test.go) | Server SHA `e609ff8`; checked 2026-07-10 | Entropy generation, one-time raw-token return, hash storage/lookup, constant-time comparison, expiry/revocation, generic public failures, and viewer behavior | Inspected; repository and HTTP tests passed | No production traffic or token was used | Non-findings | +| R-HTTP-LOGGING / R-HTTP-LOGGING-TESTS | Application logging controls and tests: [`internal/httpapi/middleware.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/middleware.go), [`internal/httpapi/logging.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/logging.go), [`cmd/api/logging.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/cmd/api/logging.go), [`internal/httpapi/middleware_test.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/middleware_test.go), [`internal/httpapi/logging_internal_test.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/logging_internal_test.go), and [`docs/logging-requirements.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/logging-requirements.md) | Server SHA `e609ff8`; checked 2026-07-10 | Request-path redaction and categorized internal/startup errors | Inspected; relevant tests passed | Source review cannot prove every deployment log sink | Non-findings | +| R-UPLOAD-HANDLER | Upload orchestration: [`internal/httpapi/chunk_handlers.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/chunk_handlers.go) | Server SHA `e609ff8`; checked 2026-07-10 | Upload state transitions, storage error mapping, envelope validation | Inspected; happy and retry stack paths passed | Some exceptional paths remain unexecuted | F-006; non-findings | +| R-POSTGRES-CHUNKS / R-UPLOAD-OPERATIONS | PostgreSQL upload persistence: [`internal/postgresdb/chunks.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/chunks.go), [`internal/postgresdb/upload_operations.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/upload_operations.go) | Server SHA `e609ff8`; checked 2026-07-10 | Durable upload state and transaction behavior | Inspected; live PostgreSQL package tests passed | Some exceptional paths remain unexecuted | Boundaries | +| R-UPLOAD-DESIGN | [`docs/cluster-safe-upload-semantics.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/cluster-safe-upload-semantics.md) | Server SHA `e609ff8`; checked 2026-07-10 | Current and deferred cluster-safe upload controls | Inspected | Planning text does not implement deferred controls | Boundaries | +| R-LOCAL-STORAGE / R-LOCAL-STORAGE-TESTS | Local immutable commit implementation and tests: [`internal/storage/committed_blobs.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/storage/committed_blobs.go) and [`internal/storage/storage_test.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/storage/storage_test.go) | Server SHA `e609ff8`; checked 2026-07-10 | Server-controlled paths and local no-overwrite commit behavior | Inspected; tests passed | Tests cover the ordinary local no-overwrite path only | Non-findings | +| R-S3 / R-S3-TESTS | S3 backend: [`internal/storage/s3.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/storage/s3.go), [`internal/storage/s3_test.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/storage/s3_test.go), [`internal/httpapi/s3_deletion_smoke_test.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/s3_deletion_smoke_test.go) | Server SHA `e609ff8` | Conditional writes, existence mapping, startup check capability, deletion smoke | Inspected; live MinIO stack and deletion smoke passed | No real 409 collision or broken-bucket startup test | F-006, F-007 | +| R-POSTGRES-WEBAUTHN / R-WEBAUTHN-HANDLERS | [`internal/postgresdb/webauthn_second_factors.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/webauthn_second_factors.go), [`internal/httpapi/webauthn_second_factor_handlers.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/webauthn_second_factor_handlers.go) | Server SHA `e609ff8` | PostgreSQL get-or-create concurrency and HTTP error mapping | Inspected | No concurrent WebAuthn live test exists or was added | F-005 | +| R-PQ-ENVELOPE / R-PQ-TESTS / R-PQ-DOC | Accepted PQ frame: [`internal/envelope/pq/envelope.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/envelope/pq/envelope.go), [`internal/envelope/pq/envelope_test.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/envelope/pq/envelope_test.go), [`docs/post-quantum-envelope.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/post-quantum-envelope.md) | Server SHA `e609ff8`; checked 2026-07-10 | Ciphertext structural validation and current/future PQ boundary | Inspected; package and simulator tests passed | Structural validation is not ciphertext authentication | Boundaries | +| R-SHARING-HTTP / R-SHARING-HTTP-TESTS | Sharing and wrapped-key HTTP surfaces: [`internal/httpapi/account_recipient_key_handlers.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/account_recipient_key_handlers.go), [`internal/httpapi/trusted_contact_relationship_handlers.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/trusted_contact_relationship_handlers.go), [`internal/httpapi/sharing_handlers.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/sharing_handlers.go), [`internal/httpapi/wrapped_key_handlers.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/wrapped_key_handlers.go), and their corresponding [`account-recipient-key`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/account_recipient_key_handlers_test.go), [`relationship`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/trusted_contact_relationship_handlers_test.go), [`grant`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/sharing_handlers_test.go), and [`wrapped-key`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/wrapped_key_handlers_test.go) tests | Server SHA `e609ff8`; checked 2026-07-10 | Owner/recipient scoping and active relationship/key/grant/record filtering | Inspected; HTTP tests passed | Does not establish production key custody or decrypt UX | Non-findings | +| R-SHARING-REPOSITORIES / R-SHARING-REPOSITORY-TESTS | SQLite/PostgreSQL sharing persistence: SQLite [`account recipient keys`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/account_recipient_keys.go), [`relationships`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/trusted_contact_relationships.go), [`grants`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/sharing.go), and [`wrapped keys`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/wrapped_keys.go); PostgreSQL [`account recipient keys`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/account_recipient_keys.go), [`relationships`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/trusted_contact_relationships.go), [`grants`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/sharing.go), and [`wrapped keys`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/wrapped_keys.go); plus [`SQLite contract tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/repository_test.go) and [`PostgreSQL contract tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/postgresdb_test.go) | Server SHA `e609ff8`; checked 2026-07-10 | Backend authorization/filter parity and contract coverage | Inspected; ordinary SQLite and live PostgreSQL tests passed | Tests demonstrate the repository contracts, not a production decrypt client | Non-findings | +| R-DELETION-HTTP / R-DELETION-REPOSITORIES / R-RETENTION-WORKER | Deletion and retention implementation/tests: [`HTTP handlers/tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/deletion_handlers.go), [`HTTP authorization tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/deletion_handlers_test.go); SQLite [`deletion`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/deletion.go) and [`retention`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/retention_pruning.go); PostgreSQL [`deletion`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/deletion.go) and [`retention`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/retention_pruning.go); [`worker`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/retention/deletion_worker.go), [`worker tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/retention/deletion_worker_test.go), [`SQLite contract tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/repository_test.go), and [`PostgreSQL contract tests`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/postgresdb_test.go) | Server SHA `e609ff8`; checked 2026-07-10 | Owner/admin authorization, tombstones, retry handling, and access-metadata pruning | Inspected; SQLite/HTTP/worker and live PostgreSQL tests passed | Does not establish deployed lifecycle behavior | Non-findings | +| R-CI / R-RELEASE-PROMPT / R-DEVELOPMENT | Release controls in tree: [`.github/workflows/ci.yml`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/.github/workflows/ci.yml), [`codex/prompts/90-release-check.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/codex/prompts/90-release-check.md), [`docs/development.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/development.md) | Server SHA `e609ff8` | Jobs, dependencies, release checklist, documented required signals | Inspected and compared with live Actions/rulesets | Workflow text alone cannot prove live settings | F-002, F-009 | +| R-GO-TOOLCHAIN / R-DOCKERFILE / R-DOCKERFILE-INGRESS / R-GETTING-STARTED | [`go.mod`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/go.mod), [`Dockerfile`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/Dockerfile), [`Dockerfile.ingress`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/Dockerfile.ingress), [`README.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/README.md), [`docs/getting-started.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/getting-started.md), and [`docs/post-quantum-envelope.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/post-quantum-envelope.md) | Server SHA `e609ff8`; checked 2026-07-10 | Selected Go version, builder images, and user-facing version references | Inspected; shared builder digest executed and reported Go 1.26.4 | Image execution checked Linux/amd64 only | F-002 | +| R-DEPLOYMENT | [`docs/deployment.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/deployment.md) | Server SHA `e609ff8` | Deployment boundaries and operational warnings | Inspected | No real deployment was exercised | Boundaries | +| R-COMPOSE / R-COMPOSE-PG / R-COMPOSE-S3 / R-COMPOSE-SMOKE / R-COMPOSE-RELAY | [`compose/compose-full.yml`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/compose-full.yml), [`compose/compose-postgresql-local.yml`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/compose-postgresql-local.yml), [`compose/compose-sqlite-s3.yml`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/compose-sqlite-s3.yml), [`compose/smoke-test.sh`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/smoke-test.sh), [`compose/compose-relay-sqlite-local.yml`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/compose-relay-sqlite-local.yml) | Server SHA `e609ff8`; checked 2026-07-10 | Optional-backend stacks, smoke orchestration, relay smoke | Inspected and executed for full/retry/relay variants | Tag-only backend service selection is not reproducible over time | F-009, F-012; validation | +| R-V1-CHECKLIST / R-CLUSTER-BACKUP | [`docs/v1-preview-readiness-checklist.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/v1-preview-readiness-checklist.md), [`docs/cluster-backup-restore-runbook.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/cluster-backup-restore-runbook.md), [`docs/v1-preview-direction.md`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/v1-preview-direction.md) | Server SHA `e609ff8` | Preview gate, optional-backend operational limits, known future work | Inspected; linked issue state sampled live | No backup/restore drill executed | Release decision; follow-ups | +| R-EVIDENCE-BUNDLE / R-SQLITE-DB / R-POSTGRES-MIGRATIONS / R-COORDINATION | [`internal/evidencebundle/bundle.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/evidencebundle/bundle.go), [`internal/db/db.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/db/db.go), [`internal/postgresdb/migrate.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/migrate.go), [`internal/coordination/coordinator.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/coordination/coordinator.go) | Server SHA `e609ff8`; checked 2026-07-10 | Bundle integrity, SQLite opening, migrations, Valkey leases | Inspected; relevant tests and stack passed | No backup, load, or lease-expiry campaign | Non-findings; follow-ups | +| R-BUNDLE-HTTP / R-BUNDLE-HTTP-TESTS | Bundle HTTP construction and tests: [`internal/httpapi/bundles.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/bundles.go), [`internal/httpapi/bundle_zip.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/bundle_zip.go), and [`internal/httpapi/bundles_test.go`](https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/bundles_test.go) | Server SHA `e609ff8`; checked 2026-07-10 | Pre-response verification, controlled ZIP entry names/headers, authorization, and ciphertext-only output | Inspected; tests and full-stack bundle flow passed | No production proxy or large-bundle load test | Non-findings | +| R-WEBSITE-GOV / R-WEBSITE-BASELINE | Website sources: [`governance-and-political-alignment.md`](https://github.com/open-proofline/website/blob/1366ea4086db5668ad821b364b31ae25221866aa/docs/governance-and-political-alignment.md), [`repository-readme-baseline.md`](https://github.com/open-proofline/website/blob/1366ea4086db5668ad821b364b31ae25221866aa/docs/repository-readme-baseline.md) | Website `main` SHA `1366ea4`; checked 2026-07-10 | Canonical governance posture, public voice, source mapping | Inspected at requested latest default-branch commit | Companion source; does not prove server behavior | Executive summary; non-findings | +| R-WEBCLIENT-README / R-WEBCLIENT-SECURITY | Web-client sources: [`README.md`](https://github.com/open-proofline/web-client/blob/ac006f6dd0d88db361a92a92dc3a0557f715b215/README.md), [`docs/security-model.md`](https://github.com/open-proofline/web-client/blob/ac006f6dd0d88db361a92a92dc3a0557f715b215/docs/security-model.md), [`docs/api-client.md`](https://github.com/open-proofline/web-client/blob/ac006f6dd0d88db361a92a92dc3a0557f715b215/docs/api-client.md) | Web-client `develop` SHA `ac006f6`; checked 2026-07-10 | Latest prototype scope and client/server boundary | Inspected at requested latest default-branch commit | Companion behavior is not server implementation | Executive summary; non-findings | +| I-PR-377 | Existing GitHub work: [PR #377](https://github.com/open-proofline/server/pull/377), checked head [`3f7a10804b7a5eb3a032c512ede85ee40c90e3c4`](https://github.com/open-proofline/server/commit/3f7a10804b7a5eb3a032c512ede85ee40c90e3c4), and immutable vulnerability jobs [86175757215](https://github.com/open-proofline/server/actions/runs/29034519007/job/86175757215) and [86175748553](https://github.com/open-proofline/server/actions/runs/29034516394/job/86175748553) | Open; refreshed 2026-07-11 | Duplicate/partial-remediation check for Go builder update | Inspected read-only; both cited vulnerability jobs failed at the checked head | The PR can change after this dated snapshot | F-002 | + +### External authoritative sources consulted + +| Source ID | Source type and location | Date checked | Purpose | Status | Limitations | Related findings/sections | +|---|---|---|---|---|---|---| +| S-GO-RELEASE | Go release history, [Go 1.26 minor revisions](https://go.dev/doc/devel/release) | 2026-07-10 | Confirm Go 1.26.5 release date and security-fix classes | Consulted | Does not establish Proofline exploitability | F-002 | +| S-GO-VULN-5856 | Go vulnerability database, [`GO-2026-5856`](https://vuln.go.dev/ID/GO-2026-5856.json) | 2026-07-10 | Advisory affected and fixed versions | Consulted | Product applicability, traces, and exploit discussion are withheld for private triage | F-002 | +| S-AWS-PUTOBJECT | AWS S3 [`PutObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) and [conditional writes](https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-writes.html) | 2026-07-10 | `If-None-Match`, 412, and retryable 409 semantics | Consulted | AWS semantics; other S3-compatible providers may differ | F-006 | +| S-AWS-HEADBUCKET | AWS S3 [`HeadBucket`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html) | 2026-07-10 | Bucket existence/access check semantics | Consulted | Provider-specific compatibility can differ | F-007 | +| S-POSTGRES-PROTOCOL | PostgreSQL [frontend/backend message flow](https://www.postgresql.org/docs/current/protocol-flow.html) | 2026-07-10 | Transaction and error-recovery semantics | Consulted | Does not execute application code | F-005 | +| S-POSTGRES-ERRORS / S-POSTGRES-UNIQUE | PostgreSQL [error codes](https://www.postgresql.org/docs/current/errcodes-appendix.html) and [unique-index behavior](https://www.postgresql.org/docs/current/index-unique-checks.html) | 2026-07-10 | Transaction-result and uniqueness/concurrency semantics | Consulted | Repository uses the `database/sql`/pgx abstraction | F-005 | +| S-DOCKER-DIGESTS | Docker [pull by digest](https://docs.docker.com/reference/cli/docker/image/pull/#pull-an-image-by-digest-immutable-identifier) | 2026-07-10 | Tag mutability and digest pinning | Consulted | Reproducibility guidance, not a runtime vulnerability claim | F-012 | +| S-GITHUB-RULESETS / S-GITHUB-STATUS | GitHub [ruleset required-status-check rules](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets) and [status checks](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks) | 2026-07-10 | Meaning of required checks | Consulted | Live repository configuration remains separate evidence | F-009 | +| S-GITHUB-JOBS / S-GITHUB-SECURE | GitHub Actions [job dependencies](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-jobs) and [secure use](https://docs.github.com/en/actions/reference/security/secure-use) | 2026-07-10 | `needs` gating and Actions hardening | Consulted | Does not prove this workflow ran | F-009; non-findings | +| S-VALKEY-SET | Valkey [`SET`](https://valkey.io/commands/set/) semantics | 2026-07-10 | `NX` and expiry lease behavior | Consulted | No dedicated live expiry/ACL campaign | Non-findings; follow-ups | +| S-SQLITE-FK / S-SQLITE-WAL | SQLite [foreign keys](https://sqlite.org/foreignkeys.html) and [WAL](https://sqlite.org/wal.html) | 2026-07-10 | Confirm database-open invariants | Consulted | No load benchmark | Non-findings | +| S-OWASP-LOGGING | OWASP [Logging Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html) | 2026-07-10 | Sensitive-log boundary | Consulted | General guidance | Non-findings | + +No Apple-platform or legal sources were consulted because the reviewed server tree makes no implemented Apple behavior or legal-admissibility claim, and this report makes none. Provider-specific MinIO documentation was not required for any finding; MinIO was used only as a disposable S3-compatible test service, with AWS API documentation grounding S3 semantics. + +### Validation and execution evidence + +All local application validation attributed to the reviewed tree ran in clean detached clones of the exact reviewed SHA, not in the maintainer's working checkout. Synthetic credential values and generated identifiers are redacted from this public report. Commands below preserve the executable and arguments; credential-bearing environment values are shown as placeholders. Phase 2 distinguishes commands it reran from Phase 1 evidence it inspected only. + +| Source ID | Source type, location, and exact command/evidence | Commit/ref/date | Purpose/result | Status/limitations | Related findings/sections | +|---|---|---|---|---|---| +| V-REVIEW-TARGET | `git status --short --branch --untracked-files=all`; `git rev-parse --show-toplevel`; `git rev-parse HEAD`; `git branch --show-current`; `git rev-parse refs/heads/upgrade-codex-reports-and-repo-full-validation-security-review`; `git rev-parse refs/remotes/origin/upgrade-codex-reports-and-repo-full-validation-security-review`; `git -C '' status --short --branch --untracked-files=all` | Current and isolated checkouts; 2026-07-10 | Current branch, local ref, upstream ref, and isolated checkout all resolved to `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a`; initial maintainer checkout was clean; isolated checkout was clean and detached | Confirms source identity, not correctness; temporary host path intentionally omitted | Scope | +| V-PHASE2-TARGET | `git status --short --branch --untracked-files=all`; `git branch --show-current`; `git rev-parse HEAD`; `git rev-parse 'upgrade-codex-reports-and-repo-full-validation-security-review^{commit}'`; `git cat-file -e 'e609ff86028c81bd149839e03d1ffc0eb2ee9e4a^{commit}'`; `git rev-parse refs/remotes/origin/upgrade-codex-reports-and-repo-full-validation-security-review` | Current Phase 2 checkout; refreshed 2026-07-11 | Branch, `HEAD`, reviewed ref, reviewed object, and upstream ref all resolved to `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a`; status showed only the final report as untracked because local backlog drafts are ignored | The current checkout is the editing workspace, not runtime evidence for the reviewed tree | Scope; publication status | +| V-LOCAL-BASE | `gofmt -l ./cmd ./internal ./migrations`; `go test ./...`; `go vet ./...`; `scripts/check-markdown-links.py`; `git diff --check`; `docker build --progress=plain -t proofline-server-review:e609ff8 .` | Isolated exact SHA; generated 2026-07-10 | All passed; `gofmt -l` produced no paths; link checker passed 112 files | Main Docker image only in the direct build; relay built separately | General validation | +| V-LOCAL-FULLSTACK | `COMPOSE_PROJECT_NAME=proofline-phase1-e609ff8 compose/smoke-test.sh full`; `COMPOSE_PROJECT_NAME=proofline-phase1-retry-e609ff8 compose/smoke-test.sh full -- --chunks 5 --simulate-failure-every 2`; `COMPOSE_PROJECT_NAME=proofline-phase1-relay-e609ff8 compose/smoke-test.sh relay-sqlite-local` | Isolated exact SHA; generated 2026-07-10 | All passed. Disposable PostgreSQL, MinIO, and Valkey started; authenticated simulator/TOTP, incident, stream, upload, idempotent replay, induced retry, completion, bundle download, simulator-local decrypt verification, and relay readiness/route-boundary checks succeeded | Does not exercise private-report regressions, simultaneous WebAuthn registration, real S3 409, lease expiry, Redis-server compatibility, or backup/restore | F-005–F-007, F-009, F-012; non-findings | +| V-LOCAL-OPTIONAL | `SAFE_POSTGRES_TEST_DSN='' go test ./internal/postgresdb -count=1`; `SAFE_S3_DELETION_SMOKE=1 SAFE_S3_ENDPOINT='' SAFE_S3_REGION='' SAFE_S3_BUCKET='' SAFE_S3_PREFIX='' SAFE_S3_ACCESS_KEY_ID='' SAFE_S3_SECRET_ACCESS_KEY='' SAFE_S3_FORCE_PATH_STYLE=true go test ./internal/httpapi -run TestS3DeletionSmokeRemovesObjectsAndHidesViewer -count=1` | Isolated exact SHA; generated 2026-07-10 | Live PostgreSQL package tests passed in 26.772s; S3 deletion smoke passed | Only synthetic credential-bearing values and generated identifiers are redacted; no production/private service accessed | F-005–F-007; non-findings | +| V-LOCAL-EXTENDED | `go test -race ./...`; `go test -covermode=atomic -coverprofile='' ./...`; `go tool cover -func=''` | Isolated exact SHA; generated 2026-07-10 | Race suite passed; aggregate statement coverage 54.6% | Coverage is not a security or release-readiness guarantee; opt-in PostgreSQL execution was a separate run and therefore appears as 0% in the aggregate profile | General validation | +| V-GOVULN-OFFICIAL | `docker run --rm -v ':/src:ro' -w /src golang:1.26.4 go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 ./...`; `docker run --rm golang:1.26-alpine@sha256:3ad57304ad93bbec8548a0437ad9e06a455660655d9af011d58b993f6f615648 go version` (the same digest is selected by both Dockerfiles) | Exact SHA; generated 2026-07-10 | Official Go 1.26.4 scan failed on `GO-2026-5856`; the shared builder digest reported Go 1.26.4 | Detailed traces and applicability analysis withheld for private triage; container run was Linux/amd64 | F-002 | +| V-PHASE2-GOVULN | `docker run --rm -v ':/src:ro' -w /src golang:1.26.4 sh -c 'go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 ./...'`; `docker run --rm golang:1.26-alpine@sha256:3ad57304ad93bbec8548a0437ad9e06a455660655d9af011d58b993f6f615648 go version` | Detached exact SHA; executed 2026-07-11 | The official Go 1.26.4 scan independently exited non-zero and reported `GO-2026-5856`; the exact builder digest independently reported `go1.26.4 linux/amd64` | The advisory scan used the official Go 1.26.4 container; the exact builder digest was used only to verify the builder version; applicability remains private | F-002 | +| V-GOVULN-LOCAL-DISTRO | `go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 ./...`; `go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 -show verbose ./...` | Exact SHA; generated 2026-07-10 | The distribution-customized Go version string `1.26.4-X:nodwarf5` produced no reachable finding | The cause of the discrepancy was not established; this toolchain does not represent the official toolchain selected by the repository and does not clear F-002 | F-002 | +| V-CI-RUN | Public Actions [run 29081200062](https://github.com/open-proofline/server/actions/runs/29081200062) for exact SHA | Push run; 2026-07-10 08:53–08:57 UTC | Overall failure. [PostgreSQL metadata tests](https://github.com/open-proofline/server/actions/runs/29081200062/job/86324199759), [Go tests/vet](https://github.com/open-proofline/server/actions/runs/29081200062/job/86324199760), [binary build](https://github.com/open-proofline/server/actions/runs/29081200062/job/86324583020), [server image build](https://github.com/open-proofline/server/actions/runs/29081200062/job/86324583064), and [relay image build](https://github.com/open-proofline/server/actions/runs/29081200062/job/86324583082) passed. [Go vulnerability scan](https://github.com/open-proofline/server/actions/runs/29081200062/job/86324199779) failed. Tag-only attestation/upload/publish jobs were correctly skipped on the feature branch | No S3/Valkey full-stack job ran in public CI | F-002, F-009 | +| V-GITHUB-CONTROLS | Read-only commands: `gh run view 29081200062 --repo open-proofline/server --json databaseId,headSha,status,conclusion,url,workflowName,event,jobs`; `for id in 16849643 16748997 16849900 16987226; do gh api "repos/open-proofline/server/rulesets/$id"; done`; `gh api repos/open-proofline/server --jq '.security_and_analysis'`; `gh api repos/open-proofline/server/private-vulnerability-reporting --jq '.enabled'`; `gh api 'repos/open-proofline/server/dependabot/alerts?state=open&per_page=100' --jq 'length'`; `gh api repos/open-proofline/server/code-scanning/default-setup --jq '{state,query_suite,languages,updated_at}'`; `gh api repos/open-proofline/server/actions/permissions --jq '{allowed_actions}'` | Live state refreshed 2026-07-11 | The immutable exact-SHA run still had the recorded job results; `develop`, `main`, and `release/v*` still required only `Go tests`, `Build Linux binary`, and `Build Docker image`; private vulnerability reporting and Dependabot security updates were enabled; open Dependabot alerts were zero; secret scanning/push protection were disabled; CodeQL was `not-configured`; Actions permissions allowed all actions | Live settings can change; some endpoints require authenticated read access; exact rulesets remain publicly viewable as [16849643](https://github.com/open-proofline/server/rules/16849643), [16748997](https://github.com/open-proofline/server/rules/16748997), [16849900](https://github.com/open-proofline/server/rules/16849900), and [16987226](https://github.com/open-proofline/server/rules/16987226) | F-009; follow-ups | +| V-GITHUB-ISSUES | `gh issue list --repo open-proofline/server --state all --limit 300 --json number,title,state,url`; `gh pr list --repo open-proofline/server --state all --limit 300 --json number,title,state,url`; exact-title comparison against all nine sanitized recommendations | Live state checked 2026-07-11 | 143 issues with zero open; 234 pull requests with seven open; no exact issue/PR title duplicate among the nine recommendations | State can change; related closed work and open dependency PRs were reviewed as partial overlaps, not exact duplicates | Follow-ups and local draft index | +| V-COMPANION-HEADS | `gh api repos/open-proofline/website --jq '.default_branch'`; `gh api repos/open-proofline/website/commits/main --jq '.sha'`; `gh api repos/open-proofline/web-client --jq '.default_branch'`; `gh api repos/open-proofline/web-client/commits/develop --jq '.sha'`; `git -C ../website cat-file -e '1366ea4086db5668ad821b364b31ae25221866aa:docs/governance-and-political-alignment.md'`; `git -C ../website cat-file -e '1366ea4086db5668ad821b364b31ae25221866aa:docs/repository-readme-baseline.md'`; `git -C ../web-client cat-file -e 'ac006f6dd0d88db361a92a92dc3a0557f715b215:README.md'`; `git -C ../web-client cat-file -e 'ac006f6dd0d88db361a92a92dc3a0557f715b215:docs/security-model.md'`; `git -C ../web-client cat-file -e 'ac006f6dd0d88db361a92a92dc3a0557f715b215:docs/api-client.md'` | Checked 2026-07-11 | Website `main` remained `1366ea4086db5668ad821b364b31ae25221866aa`; web-client `develop` remained `ac006f6dd0d88db361a92a92dc3a0557f715b215`; all cited files existed at those commits | Companion repositories are contextual evidence only | Executive summary; boundaries | +| V-PHASE2-SOURCE-READS | Commit-addressed reviewed-tree source inspection plus current publication-guidance, full-file v1-direction/PQ-envelope, complete Phase 1 draft, future-design, report-policy, and companion-source inspection | Exact SHA/current guidance; 2026-07-11 | Every source required by prompt 95 was read before publication editing | Source review does not substitute for runtime validation | Phase 2 method; implementation boundaries | +| V-PHASE2-RECHECK | Disposable clone at exact SHA: `gofmt -l ./cmd ./internal ./migrations`; `scripts/check-markdown-links.py`; `go test ./...`; `go vet ./...`; `git diff --check`; initial/final `git status --short --branch --untracked-files=all` | Detached exact SHA; executed 2026-07-11 | All passed; formatting produced no paths; link checker passed 112 files; checkout remained clean | Phase 2 did not repeat race, coverage, Docker builds, or optional-backend stacks | Executive summary; Phase 2 validation | +| V-PHASE2-PUBLICATION | `scripts/check-markdown-links.py`; `scripts/check-markdown-links.py .backlog-drafts/2026-07-11/upgrade-codex-reports-and-repo-full-validation-security-review`; `git diff --check`; per-file `git diff --no-index --check /dev/null `; `git status --short --branch --untracked-files=all`; portable-key used/defined comparison; commit-addressed `git cat-file -e` checks for cited server/companion paths; public-safety and private-mechanics phrase scans; required draft-section/label checks | Current Phase 2 artifacts; executed 2026-07-11 | Passed: 113 repository Markdown files, 11 draft Markdown files, 12 per-file whitespace checks, 112 used/defined portable citation keys, 108 server paths, five companion paths, nine issue-draft schemas, verified labels, and disclosure scans; status showed only the final report as untracked | The local follow-up drafts are ignored; this row records validation, not remediation | Publication status; handoff | +| V-PHASE2-EXTERNAL | Independent browser opens of every non-GitHub authoritative URL used by the public report, with targeted checks of each material public claim | Checked 2026-07-11 | All URLs resolved; material public claims remained supported | Moving documentation was time-boxed to the validation date; product applicability of the Go advisory remains privately triaged | F-002, F-005, F-006, F-009, F-012; non-findings | +| V-MAINTAINER-CONTEXT | Maintainer statement in the Phase 2 task: there are no known public or private Proofline server deployments and private vulnerabilities can generally be treated as lower disclosure sensitivity in that context | 2026-07-11 | No known deployed-user exposure; used to calibrate disclosure context, not technical severity or release impact | This is maintainer-supplied deployment context, not an independent infrastructure inventory | Executive summary; private handling | +| V-PHASE2-CLEANUP | Disposable-artifact inventory covering Docker containers, networks, volumes, images, and top-level temporary entries filtered for Phase 1/2 review names | Checked 2026-07-11 | Four citation-lane scratch files were removed; the repeated inventory then found no matching disposable container, network, volume, review image, temporary checkout, or scratch file | Name-based cleanup verification only | Generated artifacts; handoff | +| V-ULTRA-REVIEW | Independent Phase 1 and Phase 2 source, backend, citation, execution-evidence, and disclosure-safety review lanes | Exact SHA; 2026-07-10 to 2026-07-11 | Findings and publication wording were independently reconciled against sources and validation evidence | AI-assisted multi-lane review is not an independent human audit | Scope and method | +| V-TOOLS | Local shell, Git, Docker/Compose, Go tooling, SQLite CLI, read-only GitHub CLI/API, public web search/open, and authoritative public documentation | 2026-07-10 | Available and used | No private/production service, credential, endpoint, or user data was accessed | Source registry | + +### Sources, checks, and commands not available or not executed + +| Source/check ID | Source type and location | Commit/ref/date | Purpose | Status | Limitations | Related findings/sections | +|---|---|---|---|---|---|---| +| V-NO-PRODUCTION | Deployment/runtime check; private or production services | Reviewed SHA; 2026-07-10 | Determine whether deployment-specific controls were directly verified | Not executed | No real account, evidence, token, private endpoint, managed backend, or production credential was accessed; TLS, firewall, proxy, WAF, monitoring, backups, and log sinks remain deployment-specific | Scope; all findings | +| V-NO-PENTEST | Security testing campaign; reviewed application | Reviewed SHA; 2026-07-10 | Bound the assurance level of the review | Not executed | No penetration test, adversarial load test, long-duration soak, fuzzing campaign, or legal/compliance review | Scope and conclusion | +| V-NO-FAULT-INJECTION | Failure/concurrency regression campaign; clean isolated checkout | Reviewed SHA; 2026-07-10 | Test exceptional paths identified by review | Not executed | Security-sensitive scenarios and detailed test designs are reserved for private reports; selected public concurrency/error cases also remain unexecuted | Private triage; F-005–F-006 | +| V-NO-BACKUP-RESTORE | Disposable PostgreSQL/S3 restore drill; optional-backend runbook | Reviewed SHA; 2026-07-10 | Validate durable metadata/blob recovery together | Not executed | The docs already require this before real optional-backend reliance; retained as a readiness boundary rather than an ordinary pre-v1 defect | Follow-ups; production boundary | +| V-NO-VALKEY-CAMPAIGN | Disposable Valkey/Redis failure campaign | Reviewed SHA; 2026-07-10 | Validate expiry, stale ownership, ACL/command restrictions, failover, and Redis-server compatibility | Partially exercised | Ordinary live Valkey coordination passed in the full stack; isolated adverse/compatibility cases did not run | F-009; follow-ups; non-findings | +| V-NO-EXTERNAL-WRITES | GitHub/external mutations | Phase 1 and Phase 2; through 2026-07-11 | Preserve review-only external scope | Deliberately not executed | No GitHub issue, private advisory, PR, release, branch/ruleset change, or security-setting change was created; Phase 2 issue drafts are ignored local files only | Follow-up recommendations | + +### Generated artifacts and report outputs + +| Artifact ID | Source type and location | Commit/ref/date | Purpose | Status | Limitations | Related findings/sections | +|---|---|---|---|---|---|---| +| G-PHASE1-DRAFT | Markdown draft; `.technical-review-drafts/2026-07-10-proofline-unreleased-technical-review-draft.md` | Reviewed SHA; generated 2026-07-10 | Phase 1 source-cited review input | Retained locally | Ignored pre-publication input; this Phase 2 report supersedes it for publication | All sections | +| G-PHASE2-TARGET | Final report source; `docs/reports/2026-07-10-proofline-unreleased-technical-review.md` | Reviewed SHA; generated/validated 2026-07-11 | Independent public-hardened report | Finalized by Phase 2 | Report of the reviewed SHA only; not remediation validation | All sections | +| G-TEMP-VALIDATION | Removed isolated exact-SHA checkout, temporary coverage profile, disposable containers/networks/volumes, and locally tagged review images | Reviewed SHA; generated/cleaned 2026-07-10 | Approved local validation without mutating the maintainer checkout | Generated temporarily; cleaned after evidence capture | Host path, synthetic credentials, and generated identifiers are intentionally omitted | Validation evidence | +| G-FOLLOWUPS | Sanitized branch-scoped local issue drafts under `.backlog-drafts/2026-07-11/upgrade-codex-reports-and-repo-full-validation-security-review/` | Generated 2026-07-11 | Preserve nine non-vulnerability follow-ups for maintainer review | Local drafts only; no GitHub issues created | Suspected/unresolved vulnerabilities excluded; GitHub state must be rechecked before later creation | Follow-up recommendations | + +## Scope And Method + +The review anchored every server claim to commit `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a`. The current branch and remote tracking ref resolved to that SHA, and all checkout-dependent validation ran in a separate clean clone. The maintainer's working checkout was not reset, cleaned, switched, reformatted, or used as runtime proof. [V-REVIEW-TARGET] [V-PHASE2-TARGET] [R-REPORT-PROMPT] + +Ultra mode was used because the repository-wide review materially benefited from independent read-only lanes. Phase 1 covered core HTTP/auth/security/crypto/sharing/deletion behavior; PostgreSQL/S3/Valkey/migration/storage behavior; and documentation, CI, deployment, companion repositories, and live public evidence. Phase 2 separately rechecked source support, execution evidence, citations, current-versus-future boundaries, disclosure safety, GitHub state, and issue-draft hygiene before publication. [V-ULTRA-REVIEW] [V-PHASE2-SOURCE-READS] + +Review scope included the repository root documents; `cmd`, `internal`, migrations, tests, Dockerfiles, Compose stacks, GitHub workflows/settings, release prompts, deployment/runbook documents, current-versus-future product documents, the latest requested website governance/baseline sources, and the latest requested web-client default-branch sources. External claims were checked against primary or authoritative documentation, and Phase 2 refreshed every external source materially relied on by this public report. [V-TOOLS] [V-PHASE2-EXTERNAL] + +Severity reflects demonstrated impact and prerequisites. Release blocking is a separate policy decision. Optional-backend findings are marked release-blocking because the maintainer explicitly set that policy in Phase 0, even where technical severity is Low or Medium. The absence of known deployments reduces present exposure but does not remove a defect or release gate. Suspected vulnerabilities use the private-reporting path required by `SECURITY.md`; this report omits exploit payloads, raw traces, sensitive identifiers, and step-by-step reproduction. [R-SECURITY] [V-MAINTAINER-CONTEXT] + +The validation method intentionally combined ordinary tests with live disposable backends. Happy-path and retry-path success is evidence that the reviewed implementation works under the exercised conditions. It is not evidence that unexercised failure, concurrency, deployment-specific, backup, or security-control paths are safe. [V-LOCAL-FULLSTACK] [V-NO-FAULT-INJECTION] + +## Current Implementation Summary + +Proofline at the reviewed commit is an experimental Go backend. It accepts already-encrypted complete chunks through authenticated main `/v1` routes, stores metadata in SQLite by default or optional PostgreSQL, stores committed ciphertext on local disk by default or optional S3-compatible object storage, and optionally uses Valkey/Redis-compatible coordination for short-lived leases and rate-limit counters. It also provides a private-admin web/API listener, a token-scoped read-only viewer, encrypted ZIP evidence bundles, and a bounded complete-chunk stream-ingress relay with temporary optimistic encrypted fanout. The relay is subordinate to the core API and does not own durable evidence, viewer, admin, or broad main-API behavior. [R-README] [R-CMD-API] [R-CMD-SERVERS] [R-HTTPAPI-ROUTES] [R-HTTPAPI-API] + +Main API/viewer and private-admin route trees are constructed as separate handlers and served on separate configured listener groups. `/admin` and `/admin/api/...` are absent from the main handler; public viewer operations are GET/read-only; the relay smoke confirms admin, main API, viewer, and metrics paths are not exposed by the relay container. Separate binds remain a deployment boundary rather than a complete security model. [R-CMD-SERVERS] [R-HTTPAPI-ROUTES] [R-HTTPAPI-API] [R-COMPOSE-RELAY] [V-LOCAL-FULLSTACK] + +Uploads are bounded, staged locally, hashed over accepted bytes, envelope-checked, and committed to server-generated immutable paths or object keys before metadata insertion. Local storage uses a no-overwrite primitive; S3 writes use `If-None-Match: *`. Bundle generation requires completed contiguous streams and verifies stored chunk size and SHA-256 before serving ZIP headers/body. Completed bundles contain encrypted chunk payloads with server-controlled ZIP entry names; they are not decrypted or playable exports. Phase 1's decrypt verification was performed locally by the simulator using development/test key material, not by the server. [R-UPLOAD-HANDLER] [R-LOCAL-STORAGE] [R-LOCAL-STORAGE-TESTS] [R-S3] [R-EVIDENCE-BUNDLE] [R-BUNDLE-HTTP] [R-BUNDLE-HTTP-TESTS] [R-ENCRYPTION] [V-LOCAL-FULLSTACK] + +SQLite enables foreign keys and verifies WAL mode with a constrained pool. Both SQLite and PostgreSQL migration paths checksum applied migrations and execute migration steps transactionally; PostgreSQL additionally serializes migration application with an advisory lock. PostgreSQL contract tests cover the principal metadata repository behavior. [R-SQLITE-DB] [R-POSTGRES-MIGRATIONS] [S-SQLITE-FK] [S-SQLITE-WAL] [V-LOCAL-OPTIONAL] + +Valkey coordination uses random ownership tokens, expiries, `SET NX`, and a token-matched compare-and-delete script. Coordination is not treated as durable evidence truth, and its failures fail closed for affected operations. The approved full stack exercised ordinary live Valkey coordination but not the more adversarial campaign listed in the validation limitations. [R-COORDINATION] [S-VALKEY-SET] [V-NO-VALKEY-CAMPAIGN] + +Generic incidents remain the default. Private incident create/read routes implement nullable `incident_mode`, `capture_profile`, `escalation_policy`, and `sharing_state` fields as labels only. Those labels do not grant access, notify contacts, change retention or key custody, release wrapped keys, or alter public viewer and bundle behavior. [R-INCIDENT-MODES] [R-API] [R-SECURITY-MODEL] + +Account-to-account trusted-contact relationships, owner-scoped account/contact recipient-key metadata, owner-scoped sharing grants, wrapped-key storage, and authenticated grant-scoped trusted-contact wrapped-key reads are implemented and authorization-scoped in both repository backends; their HTTP and repository contract tests passed. Trusted-contact incident review and client decryption UX are not implemented. [R-SHARING-HTTP] [R-SHARING-HTTP-TESTS] [R-SHARING-REPOSITORIES] [R-SHARING-REPOSITORY-TESTS] [R-KEY-CUSTODY] + +The accepted PQ profile is implemented for server upload shape/identity validation, wrapped-key public metadata and frame validation, key-free bundle profile hints, and the simulator's default reference encryption/decrypt-verification flow. These are structural/public-metadata checks and development reference behavior; they are not server-side ciphertext authentication, backend decryption, production key custody, browser decryption, or cross-repository v1-preview conformance. [R-PQ-ENVELOPE] [R-PQ-TESTS] [R-PQ-DOC] [R-ENCRYPTION] [R-V1-DIRECTION] [R-V1-CHECKLIST] [R-WEBCLIENT-README] + +The latest website and web-client sources remain aligned with the server's conservative framing. Governance is maintainer-led and intended to develop toward mission-locked public-good stewardship; the web client is an experimental account/incident-metadata prototype, mock-first and local-live-test oriented, not a recorder, decryption service, emergency workflow, or production account portal. [R-WEBSITE-GOV] [R-WEBSITE-BASELINE] [R-WEBCLIENT-README] [R-WEBCLIENT-SECURITY] [V-COMPANION-HEADS] + +## Findings + +### F-001: Private vulnerability finding + +- **Severity:** High +- **Confidence:** High +- **Reviewed context:** `upgrade-codex-reports-and-repo-full-validation-security-review` at `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a` +- **Release impact:** Release-blocking +- **Follow-up handling:** GitHub private vulnerability reporting +- **Suggested public issue title:** None before private triage + +Details, affected components, reproduction, remediation design, and regression criteria are withheld pending private triage. The maintainer reports no known deployments, so no deployed-user exposure is known; this does not change release impact. [R-SECURITY] [V-MAINTAINER-CONTEXT] + +### F-002: The reviewed Go toolchain fails the public vulnerability gate + +- **Severity:** Medium +- **Confidence:** High for affected/fixed versions and the failed gate; product applicability reserved for private triage +- **Current implementation vs future design:** Current build and CI configuration +- **Affected files/functions:** `go.mod`; server and relay builder stages; Go-version documentation; CI `govulncheck` +- **Reviewed context:** Exact reviewed SHA and public Actions run for that SHA +- **Release impact:** Release-blocking security patch and failed required review evidence +- **Follow-up handling:** GitHub private vulnerability reporting for applicability; sanitized release note after remediation +- **Suggested public issue title:** None while applicability is privately assessed + +The repository selects Go 1.26.4. Both Dockerfiles reference the same inspected builder image, both Docker build paths passed, and that shared image reported Go 1.26.4. The exact-SHA public `Go vulnerability scan` and clean Phase 1 and Phase 2 official Go 1.26.4 scans failed on `GO-2026-5856`; the Go project lists Go 1.26.5 as the security-fix release. Product-specific applicability is withheld for private triage. [R-GO-TOOLCHAIN] [R-DOCKERFILE] [R-DOCKERFILE-INGRESS] [R-GETTING-STARTED] [R-PQ-DOC] [R-CI] [V-GOVULN-OFFICIAL] [V-PHASE2-GOVULN] [V-CI-RUN] [S-GO-RELEASE] [S-GO-VULN-5856] + +The local distribution-customized toolchain produced no reachable finding, but the cause of that discrepancy was not established and it is not the official toolchain selected by `go.mod` or used by the pinned builders. It cannot clear the official scan or CI failure. PR #377 was refreshed on 2026-07-11 at head `3f7a10804b7a5eb3a032c512ede85ee40c90e3c4`; it changes only the builder digests, and its two immutable vulnerability jobs still failed because `go.mod` remained on 1.26.4. [V-GOVULN-LOCAL-DISTRO] [I-PR-377] + +Why it matters: the reviewed SHA fails its public security gate and its selected official build toolchain predates the advisory's fixed release. + +Minimal actionable fix: update the Go directive/toolchain, both builder digests, badges and version references to a fixed release; reconcile or supersede PR #377; then rerun the official vulnerability scan, full Go validation, both image builds, and approved optional-backend stack. + +Acceptance criteria: + +1. The repository and both builder images use a fixed official Go release consistently. +2. `govulncheck@v1.3.0 ./...` passes under the selected official toolchain. +3. Public Actions pass for the remediation SHA, including both image builds and PostgreSQL integration. +4. The full disposable PostgreSQL/S3/Valkey stack and retry variant pass on the remediation SHA. +5. Any security applicability statement is approved through private triage and does not speculate beyond evidence. + +### F-003: Private vulnerability finding + +- **Severity:** Medium +- **Confidence:** High +- **Reviewed context:** `upgrade-codex-reports-and-repo-full-validation-security-review` at `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a` +- **Release impact:** Release-blocking +- **Follow-up handling:** GitHub private vulnerability reporting +- **Suggested public issue title:** None before private triage + +Details, affected components, reproduction, remediation design, and regression criteria are withheld pending private triage. The maintainer reports no known deployments, so no deployed-user exposure is known; this does not change release impact. [R-SECURITY] [V-MAINTAINER-CONTEXT] + +### F-004: Private vulnerability finding + +- **Severity:** Medium +- **Confidence:** High +- **Reviewed context:** `upgrade-codex-reports-and-repo-full-validation-security-review` at `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a` +- **Release impact:** Release-blocking +- **Follow-up handling:** GitHub private vulnerability reporting +- **Suggested public issue title:** None before private triage + +Details, affected components, reproduction, remediation design, and regression criteria are withheld pending private triage. The maintainer reports no known deployments, so no deployed-user exposure is known; this does not change release impact. [R-SECURITY] [V-MAINTAINER-CONTEXT] + +### F-005: PostgreSQL WebAuthn user get-or-create is not concurrency-safe + +- **Severity:** Low +- **Confidence:** High +- **Current implementation vs future design:** Current optional PostgreSQL backend +- **Affected files/functions:** `postgresdb.Repository.GetOrCreateWebAuthnUser`; WebAuthn registration/verification start handlers +- **Reviewed context:** Exact reviewed SHA +- **Release impact:** Release-blocking under the optional-backend policy +- **Follow-up handling:** Sanitized public non-security bug after duplicate check +- **Suggested public issue title:** `Make PostgreSQL WebAuthn get-or-create concurrency safe` + +Concurrent requests can both observe no WebAuthn user. After the losing insert receives a uniqueness error, the code immediately tries to select the winner inside the same PostgreSQL transaction. PostgreSQL leaves an explicit transaction failed after the statement error until rollback/recovery, so that re-read cannot implement the intended conflict recovery. The handler can consequently return a transient false not-found/error during otherwise valid concurrent setup. [R-POSTGRES-WEBAUTHN] [R-WEBAUTHN-HANDLERS] [S-POSTGRES-PROTOCOL] [S-POSTGRES-ERRORS] [S-POSTGRES-UNIQUE] + +Why it matters: this is a transient availability/correctness defect, not an authentication bypass. It is release-blocking because it affects the optional PostgreSQL path and no concurrent live-PostgreSQL test covers it. + +Minimal actionable fix: use one concurrency-safe PostgreSQL statement pattern, such as `INSERT ... ON CONFLICT DO NOTHING` followed by a select in a usable transaction, or rollback and retry on a fresh transaction. Review sibling email/TOTP enrollment conflict recovery for the same anti-pattern. + +Acceptance criteria: + +1. A live PostgreSQL test starts concurrent get-or-create calls for one account/RP and every successful caller receives the same durable user handle. +2. No expected uniqueness race maps to `account_not_found` or a 500 response. +3. Other constraint failures remain distinguishable internally but safely mapped externally. +4. SQLite behavior and public/private route boundaries remain unchanged. + +### F-006: S3 conditional-write conflict is misclassified as an existing immutable object + +- **Severity:** Medium +- **Confidence:** High +- **Current implementation vs future design:** Current optional S3-compatible backend +- **Affected files/functions:** `isS3AlreadyExists`, `S3Store.CommitTemp`, upload duplicate mapping, S3 unit tests +- **Reviewed context:** Exact reviewed SHA +- **Release impact:** Release-blocking under the optional-backend policy +- **Follow-up handling:** Sanitized public non-security bug after duplicate check +- **Suggested public issue title:** `Retry S3 ConditionalRequestConflict instead of reporting duplicate chunk` + +The S3 helper maps both `412 PreconditionFailed` and `409 ConditionalRequestConflict`—including any raw HTTP 409—to `ErrAlreadyExists`. AWS specifies that 412 means the `If-None-Match` precondition failed because the key exists, while a 409 conditional conflict should be retried. The HTTP layer consequently reports a permanent `duplicate_chunk` for a condition that does not establish equivalent committed metadata. Tests cover 412 but not the 409 distinction. [R-S3] [R-S3-TESTS] [R-UPLOAD-HANDLER] [S-AWS-PUTOBJECT] + +Why it matters: an ordinary transient storage conflict can be presented to the client as a permanent evidence duplicate, preventing the intended retry behavior. + +Minimal actionable fix: separate precondition failure from conflicting-operation failure. Apply a bounded retry at the storage layer or surface a safe retryable storage-unavailable result; do not convert an undifferentiated 409 into duplicate evidence. + +Acceptance criteria: + +1. Smithy error-code and raw HTTP tests cover 412 and 409 separately. +2. 412 preserves immutable duplicate behavior. +3. 409 is retried within a documented bound or returned as a retryable operational failure, never a false duplicate solely from status code. +4. A disposable S3-compatible test exercises the application mapping without logging object keys or request details. + +### F-007: The configured S3 backend is not checked before the API begins serving + +- **Severity:** Medium +- **Confidence:** High +- **Current implementation vs future design:** Current optional S3-compatible startup path +- **Affected files/functions:** `run`, `newBlobStore`, `S3Store.Check` +- **Reviewed context:** Exact reviewed SHA +- **Release impact:** Release-blocking under the optional-backend policy +- **Follow-up handling:** Sanitized public operational bug +- **Suggested public issue title:** `Check the configured blob backend before API startup` + +Startup checks the optional coordination backend and opens/pings the metadata backend. It constructs the blob store but does not call its `Check` method before starting HTTP listeners. For S3, construction validates configuration shape and local temp-directory setup; the existing `Check` method is what calls `HeadBucket` to establish bucket reachability/access. A bad endpoint, unavailable bucket, or insufficient bucket permission can therefore remain undiscovered until a storage operation or a later private admin status request. [R-CMD-API] [R-S3] [S-AWS-HEADBUCKET] + +The approved full stack passed because Compose waited for MinIO initialization. It does not test fail-closed startup with a broken configured bucket. [R-COMPOSE] [V-LOCAL-FULLSTACK] + +Why it matters: a process can appear started while its configured evidence backend is unusable. This increases the chance that availability failure is first discovered during an upload or operator action. + +Minimal actionable fix: invoke the configured blob store's safe check during startup and report only the existing sanitized startup stage/category. If deployments intentionally need delayed object-store readiness, document and implement an explicit reviewed mode rather than silently skipping validation. + +Acceptance criteria: + +1. Configured S3 startup fails closed when the bucket is unreachable or inaccessible. +2. Local storage startup behavior remains unchanged and checked. +3. Startup errors contain no endpoint, bucket, credential, object key, stored path, or raw SDK error. +4. Disposable success and failure tests cover both local and S3 backends. + +### F-008: Private vulnerability finding + +- **Severity:** Low +- **Confidence:** High +- **Reviewed context:** `upgrade-codex-reports-and-repo-full-validation-security-review` at `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a` +- **Release impact:** Release-blocking +- **Follow-up handling:** GitHub private vulnerability reporting +- **Suggested public issue title:** None before private triage + +Details, affected components, reproduction, remediation design, and regression criteria are withheld pending private triage. The maintainer reports no known deployments, so no deployed-user exposure is known; this does not change release impact. [R-SECURITY] [V-MAINTAINER-CONTEXT] + +### F-009: Branch and publication controls do not enforce all release-blocking checks + +- **Severity:** Medium +- **Confidence:** High +- **Current implementation vs future design:** Current workflow, release prompt, and live GitHub rulesets +- **Affected files/settings:** `.github/workflows/ci.yml`, release-check prompt, development docs, `develop`/`main`/`release/v*` rulesets +- **Reviewed context:** Exact reviewed SHA plus live settings refreshed on 2026-07-11 +- **Release impact:** Release-blocking release-assurance gap +- **Follow-up handling:** Sanitized public CI/release-control issue +- **Suggested public issue title:** `Gate protected branches and release publishing on security and optional-backend validation` + +The active protected-branch rulesets require only `Go tests`, `Build Linux binary`, and `Build Docker image`. They do not require `Go vulnerability scan`, `PostgreSQL metadata tests`, or `Build stream-ingress Docker image`. The workflow's image publication and binary attestation paths depend on tests, vulnerability scanning, and selected builds, but not PostgreSQL integration. Public CI contains no complete PostgreSQL/MinIO/Valkey job. The release prompt's standard command list likewise omits the vulnerability scan and approved optional-backend stack. [R-CI] [R-RELEASE-PROMPT] [R-DEVELOPMENT] [R-COMPOSE-SMOKE] [V-GITHUB-CONTROLS] [S-GITHUB-RULESETS] [S-GITHUB-JOBS] + +The exact-SHA run illustrates the distinction: the overall workflow failed on vulnerability scanning while the three branch-required checks passed. GitHub documents that only configured required checks must pass for the protected-ref control. [V-CI-RUN] [S-GITHUB-RULESETS] [S-GITHUB-STATUS] + +Why it matters: merge controls can accept a commit without security, PostgreSQL, or relay checks being required, and release artifact paths can proceed without PostgreSQL evidence. S3 and Valkey have no public CI gate at all. This contradicts the maintainer's decision that optional-backend findings are release-blocking. + +Minimal actionable fix: add stable release-blocking jobs for the full optional-backend combination, include the vulnerability/PostgreSQL/relay/full-stack signals in publication dependencies, update the release prompt/docs, and require the emitted check names in the relevant live rulesets. + +Acceptance criteria: + +1. `develop`, `main`, and `release/v*` require vulnerability, PostgreSQL, relay-image, and full-stack optional-backend checks where applicable. +2. Binary attestation/upload and both image publications depend on every release-blocking job. +3. CI exercises disposable PostgreSQL, S3-compatible storage, and Valkey without real secrets or private services. +4. The release prompt explicitly includes `govulncheck` and the selected full-stack evidence. +5. Live rulesets are re-read after the new check names have emitted successfully. + +### F-010: Private vulnerability finding + +- **Severity:** Low +- **Confidence:** High +- **Reviewed context:** `upgrade-codex-reports-and-repo-full-validation-security-review` at `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a` +- **Release impact:** Private triage required; not independently release-blocking at demonstrated impact +- **Follow-up handling:** GitHub private vulnerability reporting +- **Suggested public issue title:** None before private triage + +Details, affected components, reproduction, remediation design, and regression criteria are withheld pending private triage. The maintainer reports no known deployments, so no deployed-user exposure is known; this does not change release impact. [R-SECURITY] [V-MAINTAINER-CONTEXT] + +### F-011: Private vulnerability finding + +- **Severity:** Low +- **Confidence:** High +- **Reviewed context:** `upgrade-codex-reports-and-repo-full-validation-security-review` at `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a` +- **Release impact:** Private triage required; not independently release-blocking at demonstrated impact +- **Follow-up handling:** GitHub private vulnerability reporting +- **Suggested public issue title:** None before private triage + +Details, affected components, reproduction, remediation design, and regression criteria are withheld pending private triage. The maintainer reports no known deployments, so no deployed-user exposure is known; this does not change release impact. [R-SECURITY] [V-MAINTAINER-CONTEXT] + +### F-012: Optional-backend smoke images are selected by mutable tags + +- **Severity:** Low +- **Confidence:** High +- **Current implementation vs future design:** Current release-validation Compose stacks +- **Affected files:** `compose/compose-full.yml`, `compose/compose-postgresql-local.yml`, and `compose/compose-sqlite-s3.yml` +- **Reviewed context:** Exact reviewed SHA +- **Release impact:** Release-blocking under the maintainer's optional-backend policy; reproducibility gap, not a runtime vulnerability +- **Follow-up handling:** Sanitized public supply-chain/testing issue +- **Suggested public issue title:** `Pin disposable PostgreSQL, MinIO, and Valkey smoke images by digest` + +The full stack selects PostgreSQL and Valkey by version tag and MinIO server/client by `latest`; the focused PostgreSQL and S3 variants also use tag-only backend images. Docker documents that a tag can resolve to updated contents, while a digest identifies a fixed image. The exact reviewed source can therefore exercise different database, object-store, or coordination bytes on a later rerun. [R-COMPOSE] [R-COMPOSE-PG] [R-COMPOSE-S3] [S-DOCKER-DIGESTS] + +Why it matters: the stack passed during this review, so this is not evidence that the tested versions are broken. It is a reproducibility and reviewability gap for evidence that the maintainer designated release-blocking. + +Minimal actionable fix: retain readable tags but add manifest digests for every smoke service, remove `latest`, and document/automate reviewed refreshes. + +Acceptance criteria: + +1. PostgreSQL, MinIO server, MinIO client, and Valkey images in every release smoke variant use explicit digests. +2. A documented refresh command or dependency automation updates tags and digests together. +3. Full, retry, relay, and S3-deletion validation pass after pinning. +4. No production credentials or provider-specific private endpoints are introduced. + +## Non-Findings And Confirmed Boundaries + +- **Listener and route separation held.** Main API/viewer and private-admin trees are separate handlers, muxes, listener groups, and server objects. Admin write routes are absent from the main mux; viewer routes remain read-only. The relay packaging smoke also confirmed that admin, main API, viewer, and metrics routes are absent from the relay listener. [R-CMD-API] [R-CMD-SERVERS] [R-HTTPAPI-ROUTES] [R-HTTPAPI-API] [R-COMPOSE-RELAY] [V-LOCAL-FULLSTACK] + +- **Token and browser-session handling was not promoted as a finding.** Session and viewer credentials use high-entropy random values, stored hashes, expiry/revocation checks, generic failure shapes, and constant-time final comparison where applicable. Browser-cookie support is disabled by default and remains future web-client plumbing, not public `/v1` deployment approval. When explicitly enabled for a non-local main listener, the preferred cookie configuration is Secure, HttpOnly, and `__Host-` constrained; documented loopback-local configuration and the separate path-scoped admin cookie are explicit exceptions. Cookie mode uses session-bound CSRF and exact credentialed-CORS allowlisting, and bearer-plus-cookie ambiguity is rejected. [R-HTTPAPI-API] [R-AUTH-HANDLERS] [R-AUTH-MIDDLEWARE] [R-AUTH-REPOSITORIES] [R-AUTH-POSTGRES] [R-WEB-AUTH-CONTROLS] [R-WEB-AUTH-TESTS] [R-VIEWER-TOKENS] [R-VIEWER-TOKEN-SQLITE] [R-VIEWER-TOKEN-POSTGRES] [R-VIEWER-TOKEN-TESTS] + +- **Sensitive application logging controls were materially aligned.** The inspected request, internal-error, panic, viewer-path, and startup logging implementations use safe route patterns/redaction and controlled error categories; their tests did not emit the representative sensitive values under review. [R-HTTP-LOGGING] [R-HTTP-LOGGING-TESTS] [R-SECURITY] [S-OWASP-LOGGING] + +- **Upload bounds and normal immutable-commit behavior held under exercised conditions.** Multipart/upload byte limits, local temp quota, account committed-byte quota, hash comparison, stream/media checks, server-generated paths, local no-overwrite commit, S3 `If-None-Match: *`, hashed idempotency dimensions, and Valkey lease behavior are present. F-006 does not erase the positive happy/retry evidence. [R-UPLOAD-HANDLER] [R-LOCAL-STORAGE] [R-LOCAL-STORAGE-TESTS] [R-S3] [R-COORDINATION] [V-LOCAL-FULLSTACK] + +- **Evidence-bundle integrity regressions from the prior report are resolved.** Bundle construction now reopens and verifies committed chunk byte size and SHA-256 before sending response headers/body; stream contiguity and server-controlled entry names remain enforced. Completed bundles remain encrypted chunk bundles, not decrypted/playable media. [R-PRIOR-REPORT] [R-EVIDENCE-BUNDLE] [R-BUNDLE-HTTP] [R-BUNDLE-HTTP-TESTS] [R-CHANGELOG] + +- **Migration and database-open invariants held.** SQLite foreign keys and WAL mode are verified; migrations use checksums and transactions; PostgreSQL migration execution uses a session advisory lock. Shared repository contract tests and the live PostgreSQL package run passed. F-005 is a narrow PostgreSQL error-recovery/concurrency defect, not a conclusion that the backend generally lacks parity. [R-SQLITE-DB] [R-POSTGRES-MIGRATIONS] [S-SQLITE-FK] [S-SQLITE-WAL] [V-LOCAL-OPTIONAL] + +- **Valkey remains non-durable coordination with a sound ordinary lease pattern.** Random owner tokens, expiry, `SET NX`, and compare-and-delete release are present; failures fail closed for affected operations. Lack of a dedicated expiry/ACL/Redis-compatibility campaign is a validation gap and follow-up, not evidence of a current lease exploit. [R-COORDINATION] [S-VALKEY-SET] [V-NO-VALKEY-CAMPAIGN] + +- **Sharing, wrapped-key, and deletion authorization boundaries otherwise held under inspection.** Active relationship/key/grant/record filters and owner/recipient scoping fail closed; viewer/bundle surfaces remain key-free. Deletion snapshots metadata-derived paths, blocks write paths after deletion begins, retries safe categories, and prunes access-enabling metadata while retaining tombstones. [R-SHARING-HTTP] [R-SHARING-HTTP-TESTS] [R-SHARING-REPOSITORIES] [R-SHARING-REPOSITORY-TESTS] [R-BUNDLE-HTTP] [R-BUNDLE-HTTP-TESTS] [R-DELETION-HTTP] [R-DELETION-REPOSITORIES] [R-RETENTION-WORKER] + +- **PQ recipient consistency is a known preview blocker, not a newly discovered authorization bypass.** Current server validation checks accepted-profile shapes and metadata but does not prove complete client-side key custody, recipient binding, cross-repository conformance, or decryption UX. The v1 checklist already blocks a preview claim on that broader work. No duplicate issue should be created solely from this review. [R-PQ-ENVELOPE] [R-PQ-DOC] [R-V1-CHECKLIST] [R-WEBCLIENT-README] + +- **The public/current-versus-future wording remains conservative.** The reviewed changelog describes an ordinary experimental pre-v1 patch, not v1-preview or production readiness. Missing production mobile capture, browser decryption, emergency dispatch, notifications, hosted billing, and complete trusted-contact UX remain documented future/out-of-scope work rather than defects in this server review. [R-README] [R-CHANGELOG] [R-V1-CHECKLIST] [R-WEBCLIENT-README] + +- **Website governance and web-client scope were checked at the requested latest commits.** Server public framing follows the canonical website sources, and the companion web client remains a current experimental metadata/account prototype rather than an absent repository or proof of production client readiness. [R-WEBSITE-GOV] [R-WEBSITE-BASELINE] [R-WEBCLIENT-README] + +- **Current workflow action references are full-SHA pinned and production Docker runtime images are digest-pinned/non-root.** Live repository enforcement of action pinning, secret scanning, push protection, and CodeQL can be strengthened, but those settings are retained as defense-in-depth follow-ups rather than inflated into demonstrated vulnerabilities. [R-CI] [R-DOCKERFILE] [R-DOCKERFILE-INGRESS] [S-GITHUB-SECURE] [V-GITHUB-CONTROLS] + +- **Backup/restore and production-cluster readiness remain explicitly unproven.** The repository already says a PostgreSQL-plus-encrypted-blob restore drill is required before real optional-backend reliance and that the runbook is not production approval. The missing drill is recorded as a limitation and recommended follow-up, not misclassified as a defect in an ordinary experimental pre-v1 release. [R-CLUSTER-BACKUP] [V-NO-BACKUP-RESTORE] + +## Follow-Up Recommendations + +### Private security handling + +Use GitHub private vulnerability reporting, which was confirmed enabled, for F-001, F-003, F-004, F-008, F-010, and F-011, and for the product-applicability assessment associated with F-002. Keep each report narrow enough to triage severity and disclosure independently. Do not paste the Phase 1 draft wholesale into an advisory, and do not move reproduction, exploitability, trace, object, account, session, or deployment detail into public issues. No private report was created by Phase 2. [R-SECURITY] [V-GITHUB-CONTROLS] + +### Sanitized public issues + +The 2026-07-11 all-state duplicate check found 143 issues with zero open, 234 pull requests with seven open, and no exact title duplicate among these nine recommendations. Issue state can change, so repeat the check before any later GitHub creation. Phase 2 created only sanitized, branch-scoped local drafts under `.backlog-drafts/2026-07-11/upgrade-codex-reports-and-repo-full-validation-security-review/`; suspected or unresolved vulnerabilities were excluded. [R-AGENTS] [V-GITHUB-ISSUES] [G-FOLLOWUPS] + +| Priority | Finding/follow-up | Suggested public issue title | Type / suggested labels | Core acceptance scope | +|---|---|---|---|---| +| P1 | F-005 | `Make PostgreSQL WebAuthn get-or-create concurrency safe` | Bug; `backlog`, `bug`, `go`, `testing` | Atomic conflict handling plus concurrent live-PostgreSQL test | +| P1 | F-006 | `Retry S3 ConditionalRequestConflict instead of reporting duplicate chunk` | Bug; `backlog`, `bug`, `go`, `deployment`, `testing` | Separate 412/409 semantics plus application mapping tests | +| P1 | F-007 | `Check the configured blob backend before API startup` | Deployment bug; `backlog`, `bug`, `go`, `deployment`, `testing` | Fail-closed sanitized startup success/failure tests | +| P1 | F-009 | `Gate protected branches and release publishing on security and optional-backend validation` | Release assurance; `backlog`, `ci`, `security`, `testing`, `deployment`, `maintenance` | Workflow dependencies, full stack, prompt/docs, and live rulesets | +| P2 | F-012 | `Pin disposable PostgreSQL, MinIO, and Valkey smoke images by digest` | Supply-chain/testing; `backlog`, `dependencies`, `docker`, `testing`, `maintenance` | All variants pinned; refresh process; rerun stack | +| P1 | Validation gap | `Add disposable PostgreSQL and S3 backup/restore validation` | Test/runbook; `backlog`, `testing`, `deployment`, `documentation` | Consistent restore, missing/mismatched object detection, deletion-state reconciliation; no real secrets | +| P2 | Validation gap | `Add live Valkey expiry, failure, ACL, and Redis-compatibility tests` | Test; `backlog`, `testing`, `go`, `deployment` | TTL/stale ownership/failure/compatibility behavior | +| P2 | Documentation | `Refresh v1 preview readiness blocker status and cross-repository tracking` | Documentation; `backlog`, `documentation`, `maintenance` | Separate implementation status from closed issue state; retain Not-ready boundary | +| P2 | Security hardening | `Enable repository secret scanning, push protection, and CodeQL default setup` | Repository settings; `backlog`, `security`, `maintenance`, `ci` | Confirm plan/availability, enable safely, document resulting required signals if adopted | + +The nonexistent `postgresql`, `s3`, `valkey`, and `redis` labels from the Phase 1 suggestions were replaced above with current repository labels. The backup/restore and Valkey campaign recommendations are not contradictions of the successful smoke test; they cover durability and failure modes the smoke flow does not attempt. The v1 tracking refresh is warranted because the checklist calls linked items “open issues” although the all-state check found the referenced issue set closed while the latest web client still documents several corresponding product surfaces as planned/not implemented. Issue closure must not be mistaken for satisfaction of the release gate. [R-V1-CHECKLIST] [R-WEBCLIENT-README] [V-GITHUB-ISSUES] [V-NO-BACKUP-RESTORE] + +Also correct two narrow documentation drifts during the relevant follow-up: the cluster backup runbook still describes upload leases as future even though complete-upload leases are implemented, and the PostgreSQL migration/development guidance should reflect the current full Compose environment. These are documentation cleanups, not separate vulnerabilities. [R-CLUSTER-BACKUP] [R-COORDINATION] [R-UPLOAD-HANDLER] [R-DEVELOPMENT] [R-COMPOSE] + +### Publication, remediation, and fresh-review order + +1. Triage the private findings and retain sensitive mechanics only in GitHub private vulnerability reports. +2. Remediate the release-blocking findings in separately reviewed changes and add the missing private/public regression tests. +3. Because remediation changes the reviewed commit, start a fresh Phase 0/Phase 1 review at the new SHA and rerun formatting, links, unit/integration/race tests, official `govulncheck`, both Docker builds, live PostgreSQL, S3 deletion, full stack, retry stack, relay smoke, public Actions, and live ruleset inspection. +4. Run that fresh review's own independent Phase 2 pass before publishing or making a release decision for the remediation SHA. + +## Conclusion + +The reviewed commit shows substantial engineering progress and passed every approved normal and retry-path local validation. Core listener separation, ciphertext-only storage, token handling, bundle integrity, migration discipline, and conservative public wording remain strong. Those results are meaningful but not sufficient to approve release. + +At `e609ff86028c81bd149839e03d1ffc0eb2ee9e4a`, one High, six Medium, and five Low findings remain. The release-blocking private findings, failed official Go vulnerability gate, public optional-backend findings, and incomplete release enforcement block the release. The mutable optional-backend smoke images are additionally blocking under the maintainer's explicit Phase 0 policy. [V-CI-RUN] [V-LOCAL-FULLSTACK] + +The correct decision is: + +- **Not approved for release at the reviewed SHA.** +- **Not ready for a v1 preview, v1.0.0, real-user evidence-upload, public `/v1`, or production-readiness claim.** +- **Release eligibility must be reassessed at the remediation SHA through a fresh Phase 0/Phase 1 review and its own Phase 2 pass; this report makes no readiness determination for that future SHA.** + +Phase 2 finalized this disclosure-hardened report and created only ignored local follow-up drafts. It did not remediate the reviewed SHA or create private advisories, public issues, pull requests, releases, or repository-setting changes. + +## Citation References + +[R-REPORT-PROMPT]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/reports/prompts/phase-1-codex-technical-review.md +[R-PHASE2-PROMPT]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/codex/prompts/95-validate-technical-review-report.md +[R-PRIOR-REPORT]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/reports/2026-06-13-proofline-v0.11.0-rc.1-technical-review.md +[R-README]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/README.md +[R-SECURITY]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/SECURITY.md +[R-CHANGELOG]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/CHANGELOG.md +[R-AGENTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/AGENTS.md +[R-V1-DIRECTION]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/v1-preview-direction.md +[R-INCIDENT-MODES]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/incident-modes.md +[R-SECURITY-MODEL]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/security-model.md +[R-API]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/api.md +[R-ENCRYPTION]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/encryption.md +[R-KEY-CUSTODY]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/key-custody.md +[R-CMD-API]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/cmd/api/main.go +[R-CMD-SERVERS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/cmd/api/servers.go +[R-HTTPAPI-ROUTES]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/routes.go +[R-HTTPAPI-API]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/api.go +[R-AUTH-HANDLERS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/auth_handlers.go +[R-AUTH-MIDDLEWARE]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/auth_middleware.go +[R-AUTH-REPOSITORIES]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/auth.go +[R-AUTH-POSTGRES]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/auth.go +[R-WEB-AUTH-CONTROLS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/web_auth.go +[R-WEB-AUTH-TESTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/auth_test.go +[R-VIEWER-TOKENS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/incident_viewer.go +[R-VIEWER-TOKEN-SQLITE]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/incident_tokens.go +[R-VIEWER-TOKEN-POSTGRES]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/incident_tokens.go +[R-VIEWER-TOKEN-TESTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/incident_viewer_test.go +[R-HTTP-LOGGING]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/middleware.go +[R-HTTP-LOGGING-TESTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/middleware_test.go +[R-UPLOAD-HANDLER]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/chunk_handlers.go +[R-LOCAL-STORAGE]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/storage/committed_blobs.go +[R-LOCAL-STORAGE-TESTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/storage/storage_test.go +[R-S3]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/storage/s3.go +[R-S3-TESTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/storage/s3_test.go +[R-POSTGRES-WEBAUTHN]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/webauthn_second_factors.go +[R-WEBAUTHN-HANDLERS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/webauthn_second_factor_handlers.go +[R-PQ-ENVELOPE]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/envelope/pq/envelope.go +[R-PQ-TESTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/envelope/pq/envelope_test.go +[R-PQ-DOC]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/post-quantum-envelope.md +[R-SHARING-HTTP]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/sharing_handlers.go +[R-SHARING-HTTP-TESTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/sharing_handlers_test.go +[R-SHARING-REPOSITORIES]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/sharing.go +[R-SHARING-REPOSITORY-TESTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/incidents/repository_test.go +[R-DELETION-HTTP]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/deletion_handlers.go +[R-DELETION-REPOSITORIES]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/deletion.go +[R-RETENTION-WORKER]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/retention/deletion_worker.go +[R-CI]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/.github/workflows/ci.yml +[R-RELEASE-PROMPT]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/codex/prompts/90-release-check.md +[R-DEVELOPMENT]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/development.md +[R-GO-TOOLCHAIN]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/go.mod +[R-DOCKERFILE]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/Dockerfile +[R-DOCKERFILE-INGRESS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/Dockerfile.ingress +[R-GETTING-STARTED]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/getting-started.md +[R-COMPOSE]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/compose-full.yml +[R-COMPOSE-PG]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/compose-postgresql-local.yml +[R-COMPOSE-S3]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/compose-sqlite-s3.yml +[R-COMPOSE-SMOKE]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/smoke-test.sh +[R-COMPOSE-RELAY]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/compose/compose-relay-sqlite-local.yml +[R-V1-CHECKLIST]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/v1-preview-readiness-checklist.md +[R-CLUSTER-BACKUP]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/docs/cluster-backup-restore-runbook.md +[R-EVIDENCE-BUNDLE]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/evidencebundle/bundle.go +[R-BUNDLE-HTTP]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/bundle_zip.go +[R-BUNDLE-HTTP-TESTS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/httpapi/bundles_test.go +[R-SQLITE-DB]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/db/db.go +[R-POSTGRES-MIGRATIONS]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/postgresdb/migrate.go +[R-COORDINATION]: https://github.com/open-proofline/server/blob/e609ff86028c81bd149839e03d1ffc0eb2ee9e4a/internal/coordination/coordinator.go +[R-WEBSITE-GOV]: https://github.com/open-proofline/website/blob/1366ea4086db5668ad821b364b31ae25221866aa/docs/governance-and-political-alignment.md +[R-WEBSITE-BASELINE]: https://github.com/open-proofline/website/blob/1366ea4086db5668ad821b364b31ae25221866aa/docs/repository-readme-baseline.md +[R-WEBCLIENT-README]: https://github.com/open-proofline/web-client/blob/ac006f6dd0d88db361a92a92dc3a0557f715b215/README.md +[R-WEBCLIENT-SECURITY]: https://github.com/open-proofline/web-client/blob/ac006f6dd0d88db361a92a92dc3a0557f715b215/docs/security-model.md +[I-PR-377]: https://github.com/open-proofline/server/pull/377 + +[S-GO-RELEASE]: https://go.dev/doc/devel/release +[S-GO-VULN-5856]: https://vuln.go.dev/ID/GO-2026-5856.json +[S-AWS-PUTOBJECT]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html +[S-AWS-HEADBUCKET]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html +[S-POSTGRES-PROTOCOL]: https://www.postgresql.org/docs/current/protocol-flow.html +[S-POSTGRES-ERRORS]: https://www.postgresql.org/docs/current/errcodes-appendix.html +[S-POSTGRES-UNIQUE]: https://www.postgresql.org/docs/current/index-unique-checks.html +[S-DOCKER-DIGESTS]: https://docs.docker.com/reference/cli/docker/image/pull/#pull-an-image-by-digest-immutable-identifier +[S-GITHUB-RULESETS]: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets +[S-GITHUB-STATUS]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks +[S-GITHUB-JOBS]: https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-jobs +[S-GITHUB-SECURE]: https://docs.github.com/en/actions/reference/security/secure-use +[S-VALKEY-SET]: https://valkey.io/commands/set/ +[S-SQLITE-FK]: https://sqlite.org/foreignkeys.html +[S-SQLITE-WAL]: https://sqlite.org/wal.html +[S-OWASP-LOGGING]: https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html + +[V-REVIEW-TARGET]: #validation-and-execution-evidence +[V-PHASE2-TARGET]: #validation-and-execution-evidence +[V-LOCAL-BASE]: #validation-and-execution-evidence +[V-LOCAL-FULLSTACK]: #validation-and-execution-evidence +[V-LOCAL-OPTIONAL]: #validation-and-execution-evidence +[V-LOCAL-EXTENDED]: #validation-and-execution-evidence +[V-GOVULN-OFFICIAL]: #validation-and-execution-evidence +[V-GOVULN-LOCAL-DISTRO]: #validation-and-execution-evidence +[V-CI-RUN]: https://github.com/open-proofline/server/actions/runs/29081200062 +[V-GITHUB-CONTROLS]: #validation-and-execution-evidence +[V-GITHUB-ISSUES]: #validation-and-execution-evidence +[V-COMPANION-HEADS]: #validation-and-execution-evidence +[V-PHASE2-SOURCE-READS]: #validation-and-execution-evidence +[V-PHASE2-RECHECK]: #validation-and-execution-evidence +[V-PHASE2-PUBLICATION]: #validation-and-execution-evidence +[V-PHASE2-EXTERNAL]: #validation-and-execution-evidence +[V-MAINTAINER-CONTEXT]: #validation-and-execution-evidence +[V-PHASE2-CLEANUP]: #validation-and-execution-evidence +[V-PHASE2-GOVULN]: #validation-and-execution-evidence +[V-ULTRA-REVIEW]: #validation-and-execution-evidence +[V-TOOLS]: #validation-and-execution-evidence +[V-NO-FAULT-INJECTION]: #sources-checks-and-commands-not-available-or-not-executed +[V-NO-BACKUP-RESTORE]: #sources-checks-and-commands-not-available-or-not-executed +[V-NO-VALKEY-CAMPAIGN]: #sources-checks-and-commands-not-available-or-not-executed +[G-FOLLOWUPS]: #generated-artifacts-and-report-outputs From 94c09e41d338c44d3bb0d3e6f09f83e60ade27c4 Mon Sep 17 00:00:00 2001 From: Ellie Melton Date: Sat, 11 Jul 2026 17:48:55 +1000 Subject: [PATCH 3/4] docs: separate public and local scripts --- .gitignore | 5 +++-- CHANGELOG.md | 4 ++++ README.md | 2 +- codex/README.md | 7 ++++++- .../81-backlog-drafts-structure-and-hygiene.md | 13 ++++++++++--- .../prompts/85-create-github-issues-from-drafts.md | 12 +++++++----- docs/development.md | 5 +++++ 7 files changed, 36 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index cfd8274..512f460 100644 --- a/.gitignore +++ b/.gitignore @@ -59,11 +59,12 @@ Thumbs.db # Codex generated issues / issue review drafts / technical review drafts / # generated review directories -# Scripts directory should be local and ignored .backlog-drafts/ .issue-review-drafts/ .technical-review-drafts/ # Legacy local output from the former ChatGPT Deep Research workflow. .deep-research-drafts/ -scripts/ +# Local operational/generated scripts and their artifacts. Public repository +# scripts belong in scripts/ and are reviewed like other tracked source files. +.local-scripts/ .*-review/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 098d6b4..610dd9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,10 @@ preview readiness claim. - Migrated the public technical-review workflow to Codex maximum-reasoning prompts while preserving an independent Phase 2 validation pass. +- Separated tracked repository tooling under `scripts/` from ignored local and + generated helpers under `.local-scripts/`, keeping the Markdown link checker + public while preventing local script artifacts from ordinary Git staging. + - Consolidated duplicate key-metadata rate-limit classification, removed unreachable internal helpers, and reconciled current implementation docs for complete-upload coordination, the regional relay, trusted-contact wrapped-key diff --git a/README.md b/README.md index 10c0795..46e8c2c 100644 --- a/README.md +++ b/README.md @@ -590,7 +590,7 @@ Use `80-backlog-scan-issue-drafts.md` to generate reviewed local issue drafts un Review those drafts manually before creating GitHub issues. Drafts are generated review artifacts, not the long-term source of truth once GitHub issues exist. -Only after review, use `85-create-github-issues-from-drafts.md` to generate `scripts/create-backlog-issues.sh` and `.backlog-drafts/.../create-issues-review.md`. Do not run the generated script unless the maintainer explicitly asks for issue creation. +Only after review, use `85-create-github-issues-from-drafts.md` to generate `.local-scripts/create-backlog-issues.sh` and `.backlog-drafts/.../create-issues-review.md`. Do not run the generated script unless the maintainer explicitly asks for issue creation. Do not let Codex create GitHub issues directly during the initial scan. diff --git a/codex/README.md b/codex/README.md index 14a171a..0d55b32 100644 --- a/codex/README.md +++ b/codex/README.md @@ -80,13 +80,18 @@ Rules: Generated local artifacts should not be placed under `codex/`. +Tracked reusable repository tooling belongs under `scripts/`; the Markdown link +checker is public repository tooling. Generated, host-specific, or +maintainer-local helpers belong under the ignored `.local-scripts/` directory +and must not be added to `scripts/` incidentally. + Current generated artifact locations: - `.technical-review-drafts/` for source-cited Codex Phase 1 report drafts that still require independent Phase 2 validation before publication - `.backlog-drafts/YYYY-MM-DD//` or `.backlog-drafts/current//` for backlog issue drafts - `.issue-review-drafts/YYYY-MM-DD//` or `.issue-review-drafts/current//` for open-issue review drafts -- `scripts/create-backlog-issues.sh` only when explicitly generated from reviewed backlog drafts +- `.local-scripts/create-backlog-issues.sh` only when explicitly generated from reviewed backlog drafts Backlog and issue-review drafts must not include raw tokens, secrets, private deployment details, exploit details, or user safety data. Public GitHub issues must not be created from drafts until the maintainer reviews them. diff --git a/codex/prompts/81-backlog-drafts-structure-and-hygiene.md b/codex/prompts/81-backlog-drafts-structure-and-hygiene.md index cf183c3..0c33f9d 100644 --- a/codex/prompts/81-backlog-drafts-structure-and-hygiene.md +++ b/codex/prompts/81-backlog-drafts-structure-and-hygiene.md @@ -32,7 +32,7 @@ Read: - `codex/prompts/82-review-open-issues-for-stale-or-fixed.md`, if present - `codex/prompts/95-validate-technical-review-report.md`, if present - `.backlog-drafts/`, if present -- `scripts/create-backlog-issues.sh`, if present +- `.local-scripts/create-backlog-issues.sh`, if present - `.gitignore` If GitHub CLI is available, inspect repository labels: @@ -228,7 +228,7 @@ new generated drafts are branch-scoped new generated drafts include Priority, Type, Labels, and Branch scope issue creation scripts fail closed for missing metadata committed .backlog-drafts/ is removed or archived -scripts/create-backlog-issues.sh is removed, archived, or updated to branch-scoped draft paths +.local-scripts/create-backlog-issues.sh is removed, archived, or updated to branch-scoped draft paths ``` ## Validation @@ -237,10 +237,17 @@ After changes, if any: ```bash git diff --stat -git diff -- .gitignore .backlog-drafts codex docs scripts +git diff -- .gitignore codex docs scripts git diff --check ``` +If `.local-scripts/create-backlog-issues.sh` exists, also confirm it remains +ignored: + +```bash +git check-ignore -q .local-scripts/create-backlog-issues.sh +``` + Validate draft metadata: ```bash diff --git a/codex/prompts/85-create-github-issues-from-drafts.md b/codex/prompts/85-create-github-issues-from-drafts.md index 6ab2332..ac82289 100644 --- a/codex/prompts/85-create-github-issues-from-drafts.md +++ b/codex/prompts/85-create-github-issues-from-drafts.md @@ -12,10 +12,10 @@ Do **not** modify workflows, Dockerfiles, SQL migrations, Go code, generated fil Generate a shell script that creates GitHub issues from maintainer-reviewed backlog draft files, preserving priority in the issue body and applying GitHub labels from each draft. -Create: +Create this ignored local script: ```text -scripts/create-backlog-issues.sh +.local-scripts/create-backlog-issues.sh ``` ## Repository @@ -48,7 +48,7 @@ Before generating the script: 3. If multiple directories exist and the newest or intended branch scope is unclear, stop and ask which draft directory to use. 4. Do not use `.backlog-drafts/private-notes/` or any `private-notes/` directory for public issue creation. 5. Read the selected directory `README.md` and every `NNN-*.md` draft before generating a script. -6. If an existing `scripts/create-backlog-issues.sh` points at a different or missing draft directory, replace it only after selecting and validating the intended branch-scoped directory. +6. If an existing `.local-scripts/create-backlog-issues.sh` points at a different or missing draft directory, replace it only after selecting and validating the intended branch-scoped directory. ## Required draft metadata @@ -247,7 +247,7 @@ This file should summarize: Allowed files: -- `scripts/create-backlog-issues.sh` +- `.local-scripts/create-backlog-issues.sh` - `.backlog-drafts//create-issues-review.md` Do not change anything else unless needed only for a tiny documentation link. @@ -258,7 +258,9 @@ After generating the script: ```bash git diff --stat -git diff -- scripts/create-backlog-issues.sh .backlog-drafts +test -x .local-scripts/create-backlog-issues.sh +bash -n .local-scripts/create-backlog-issues.sh +git check-ignore -q .local-scripts/create-backlog-issues.sh git diff --check ``` diff --git a/docs/development.md b/docs/development.md index 89fd467..03b4e10 100644 --- a/docs/development.md +++ b/docs/development.md @@ -251,6 +251,11 @@ and does not require network access, Node/npm, Docker, cloud services, or secrets. If the checker itself changes, also run `scripts/check-markdown-links.py --self-test`. +The `scripts/` directory contains tracked, reviewable repository tooling. +Generated, host-specific, and maintainer-local helpers belong under the ignored +`.local-scripts/` directory so they cannot be included in public commits by +ordinary Git staging. + ## Backlog Discipline New ideas discovered during unrelated work should become issues or backlog items unless they are required to finish the current task. Capture the context, acceptance criteria, tests, docs impact, and out-of-scope items instead of expanding the active diff. From 5e2a92febdab742b1b709b2ec3592e088f11ec70 Mon Sep 17 00:00:00 2001 From: Ellie Melton Date: Sun, 12 Jul 2026 00:09:21 +1000 Subject: [PATCH 4/4] build: upgrade Go to 1.26.5 --- CHANGELOG.md | 4 ++++ Dockerfile | 2 +- Dockerfile.ingress | 2 +- README.md | 4 ++-- docs/getting-started.md | 2 +- docs/post-quantum-envelope.md | 2 +- go.mod | 2 +- 7 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 610dd9c..f027ca6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,10 @@ preview readiness claim. generated helpers under `.local-scripts/`, keeping the Markdown link checker public while preventing local script artifacts from ordinary Git staging. +- Updated the repository, CI-selected toolchain, and pinned server/relay + builder image to Go 1.26.5 so the standard-library vulnerability scan uses + the current security-fix release. + - Consolidated duplicate key-metadata rate-limit classification, removed unreachable internal helpers, and reconciled current implementation docs for complete-upload coordination, the regional relay, trusted-contact wrapped-key diff --git a/Dockerfile b/Dockerfile index ff626c0..a40e2f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.26-alpine@sha256:3ad57304ad93bbec8548a0437ad9e06a455660655d9af011d58b993f6f615648 AS builder +FROM golang:1.26-alpine@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS builder WORKDIR /src diff --git a/Dockerfile.ingress b/Dockerfile.ingress index 4c54ba6..f756abb 100644 --- a/Dockerfile.ingress +++ b/Dockerfile.ingress @@ -1,4 +1,4 @@ -FROM golang:1.26-alpine@sha256:3ad57304ad93bbec8548a0437ad9e06a455660655d9af011d58b993f6f615648 AS builder +FROM golang:1.26-alpine@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS builder WORKDIR /src diff --git a/README.md b/README.md index 46e8c2c..723b694 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

CI - Go 1.26.4 + Go 1.26.5 License: AGPL-3.0-only Status: Experimental Security policy @@ -381,7 +381,7 @@ For more diagrams and package-level details, see [docs/architecture.md](docs/arc Requirements: -- Go 1.26.4 +- Go 1.26.5 - SQLite via the bundled Go SQLite driver dependency - TOTP generation and validation through the bundled Go OTP dependency - WebAuthn/FIDO2 ceremony validation through the bundled go-webauthn dependency diff --git a/docs/getting-started.md b/docs/getting-started.md index d8252ae..5bd2474 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -4,7 +4,7 @@ This guide starts the Proofline backend locally and runs the simulator against i ## Requirements -- Go 1.26.4 +- Go 1.26.5 - SQLite through the bundled Go SQLite driver dependency - TOTP generation and validation through the bundled Go OTP dependency - WebAuthn/FIDO2 ceremony validation through the bundled go-webauthn dependency diff --git a/docs/post-quantum-envelope.md b/docs/post-quantum-envelope.md index 0eaab17..0ab0023 100644 --- a/docs/post-quantum-envelope.md +++ b/docs/post-quantum-envelope.md @@ -652,7 +652,7 @@ without padding must match the current repository convention. ### Go -The server repository currently targets Go 1.26.4 and already uses +The server repository currently targets Go 1.26.5 and already uses standard-library AES-GCM for the v1 compatibility envelope. Runtime implementation should prefer: diff --git a/go.mod b/go.mod index b86ca21..6957360 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/open-proofline/server -go 1.26.4 +go 1.26.5 require ( filippo.io/age v1.3.1