Menu
AkurAI-Build
publicLatest change 9a85658e32969c2d70a1aeab5c6000c7fee45474 - docs: refresh stale dependency, MSRV, and test-count references by Olafur Bui
# Implementation resolution record The ten consultant reports in this directory are preserved as point-in-time, read-only critiques. Their statements about the “current” tree and the final `NO-SHIP` verdict describe the checkout each consultant reviewed; they have not been rewritten after implementation. This record maps the final blocking classes to the present source and evidence. It is not a new security audit, release certification, or production attestation. ## Blocking findings | Final gate | Implemented behavior | Current evidence and boundary | | --- | --- | --- | | Non-destructive deployment | `bunfork-deployment-v2` inventories every shipped file by SHA-256 and byte length. Replacement accepts one direct, non-protected project child only, verifies the existing inventory and mode payload, stages with exclusive file creation, syncs files and directories, and uses rename with restoration of the prior release if installation fails. | [`src/main.rs`](../../src/main.rs) (`deploy`, `validate_deploy_output`, `validate_owned_deployment`, `sync_tree`); tests `refuses_unowned_deployment_directory`, `refuses_protected_deployment_outputs`, and `accepts_complete_owned_deployment_directory`. Forced replacement uses two renames, so readers can briefly observe a missing output; rename-failure injection is not a committed test. Older `*.previous-*` directories are not pruned automatically. | | Filesystem-safe backup and restore | Existing database and backup files are opened with no-follow flags, checked for regular-file type, private mode, one link, and stable device/inode identity. Backup publication and restore staging use exclusive files and durable syncs. Restore copies from retained backup/live descriptors, holds the maintenance lock, checkpoints WAL, verifies staged and preserved databases, then atomically renames the staged database. | [`src/db.rs`](../../src/db.rs) (`backup`, `restore_database`, `open_validated_existing_file`, `ensure_path_matches_file`, `copy_file_contents`); tests `encrypted_backup_round_trip`, `open_file_identity_detects_path_replacement`, `migration_rejects_hard_linked_database`, `restore_rejects_empty_and_unrelated_databases`, and `restore_round_trip_preserves_previous_database`. SQLCipher verification still reopens a pathname bracketed by identity checks, and there is no explicit link/swap-race integration test. This is Linux-oriented hardening, not protection from root or a hostile owner of the private parent directory. | | Equivalent secret encodings | Database keys and API tokens are decoded to zeroizing 32-byte buffers and compared with constant-time byte equality before native startup. Text casing cannot bypass separation. | [`src/db.rs`](../../src/db.rs) (`secrets_equal`, `decode_secret`) and [`src/main.rs`](../../src/main.rs) (`run_server`); test `secret_equality_compares_decoded_bytes` includes upper/lowercase equivalence. | | Exact data contract and bounded vector work | Startup/backup/restore validate the application ID, schema version, exact migration ledger, normalized table/index SQL, and absence of unexpected schema objects. Vector identifiers, content, dimensions, finite values, nonzero norm, result count, candidate count, and dimension-by-candidate work are bounded. Client validation errors map to HTTP 400; the concurrent search gate maps to 429; unexpected database failures remain 500. | [`src/db.rs`](../../src/db.rs) (`validate_application_schema`, `validate_schema_sql`, `validate_vector_upsert`, `validate_vector_search`, `normalize_embedding`) and [`src/server.rs`](../../src/server.rs) (`ApiError::database`); tests `schema_validation_rejects_unexpected_objects`, `rejects_unsafe_vectors`, and `vector_top_k_is_bounded_and_deterministic`. The validation mapping has unit coverage; the committed black-box suite is static-host focused rather than a complete hostile vector HTTP matrix. | | Truthful, isolated artifacts | Static artifacts and deployment bundles derive file claims from inspected contents. The explicit frontend build command uses an argv vector, clears the inherited environment, restores a narrow tool environment, and refuses Bunfork database/API secrets. Deployment metadata says whether the payload is `native` or `static`; runtime database, key, and token paths are not bundled. | [`src/main.rs`](../../src/main.rs) (`build_frontend`, `deploy`) and [`src/artifact.rs`](../../src/artifact.rs) (`inventory_excluding`). This does not make third-party build scripts trusted; it limits ambient inputs and records Bunfork-owned output. | ## Required host evidence | Contract | Implemented behavior | Evidence | | --- | --- | --- | | Strict static admission and preload | `bunfork-static-v1` denies unknown manifest fields and requires a complete sorted map of paths to SHA-256 and byte length. Admission rejects hidden paths, symlinks, hard links, special files, duplicates, traversal, and bounded-size violations. Static startup verifies the complete tree, then opens with no-follow, rechecks size/hash/path identity, and preloads at most 512 MiB before binding; requests do not reopen artifact files. | [`src/artifact.rs`](../../src/artifact.rs), [`src/server.rs`](../../src/server.rs) (`serve_static`, `preload_static_files`, `read_static_file`); tests `admission_is_deterministic_and_detects_mutation`, `admission_rejects_links_and_hidden_files`, and `static_artifact_http_matrix`. | | Native/static readiness separation | `serve --static` returns into the static path before loading SQLCipher secrets or opening a database; parsed tenant/model values are unused. Static readiness reports ready only after verification/preload and listener construction; native readiness executes `SELECT 1` on the open encrypted database and returns 503 on failure. | [`src/main.rs`](../../src/main.rs) (`run_server`), [`src/server.rs`](../../src/server.rs) (`static_status_routes`, `native_ready`), and [`src/db.rs`](../../src/db.rs) (`check_ready`); tests `static_status_routes_are_stable_and_get_only`, `native_readiness_maps_database_failure_to_unavailable`, `readiness_probes_the_open_connection`, plus the black-box static test’s empty runtime-state assertion. A corrupt-artifact/no-bind case is covered at verifier level, not by a listener process test. | | Listener-level static HTTP | The committed integration tests start the shipped test binary and exercise MPA, SPA, base paths, GET/HEAD/405, 404s, redirects, ETags/304, cache headers, traversal rejection, security headers, absence of runtime state, clean SIGTERM shutdown, and header-read-timeout disconnection of slow-header clients. | [`tests/static_http.rs`](../../tests/static_http.rs), tests `static_artifact_http_matrix` and `slow_header_client_is_disconnected_by_the_header_read_timeout`. On 2026-07-11, `cargo test --locked --all-targets --no-fail-fast` passed all 50 unit/integration tests in this checkout. | | Framework HTTP and browser gates | Official Svelte/Vite, SvelteKit static, Next export, Vue/Vite, and Nuxt generate outputs were admitted, served by real Bunfork listeners, HTTP-probed, and exercised in Chromium through Playwright. Browser checks covered mounting/hydration, counters, client navigation, deep reloads, and referenced assets. | [`docs/framework-e2e.md`](../framework-e2e.md) records exact package versions, reference commits, artifact counts, and results from 2026-07-11. The generated projects, browser harness, and results remain under ignored `target/framework-e2e`; this is point-in-time evidence, not a committed cross-version CI matrix. | | Address contract | Native and static CLI serving default to `0.0.0.0:3100`; both systemd user units set the same value. Port 3000 is not the default. Tests and framework gates override the address with isolated loopback ports. | [`src/main.rs`](../../src/main.rs) (`DEFAULT_ADDRESS`, `ServerArgs`), [`deploy/bunfork.service`](../../deploy/bunfork.service), and [`deploy/bunfork-static.service`](../../deploy/bunfork-static.service). This confirms configuration, not a final Titan deployment. | ## Honest non-goals and remaining operations - No final deployment to Titan is claimed here. Host installation, firewall/TLS proxy setup, and a live check of `http://192.168.1.10:3100/` remain separate deployment work. - Bunfork hosts admitted prebuilt browser artifacts. It does not compile or execute Svelte, SvelteKit, Next.js, Vue, Nuxt, Vite, Node, Bun, Deno, RSC, Nitro, SSR adapters, server actions, middleware, HMR, or framework API routes. - There is no built-in TLS, DNS, cloud provisioning, remote backup transport, key rotation, account/role system, rate limiter, or distributed coordination. Internet exposure requires a trusted TLS reverse proxy and host firewall. - Encryption and path hardening do not protect against root, a compromised service account or binary, an unlocked live process, stolen key material, or malicious firmware/storage. - Framework browser compatibility is limited to the recorded versions and static-export shapes. Inline framework bootstrap currently requires the documented static CSP allowance. - Deployment preserves a previous release for manual rollback but does not implement retention pruning or remote rollout. Database restore likewise preserves the previous database and leaves retention policy to the operator.