Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

oc5 — RED-TEAM status

Источник: dev/fera-research/docs/oc5/STATUS.md (read-only; сгенерировано scripts/sync-docs.mjs)

Zone: attacks on design + code of the whole Fera ecosystem.

  • trust model of modules / signing
  • panic isolation in native dylib (Rust panic=unwind across C ABI) + related FFI hazards
  • storage encryption tiers
  • offline-first edge cases
  • race conditions in the actor model
  • perf claims vs reality
  • supply chain (git deps, submodules)

Deliverables: docs/oc5/*.md, kind problem/risk, severity, English, exact evidence paths. Rule compliance: no file outside docs/oc5/ was created or modified. Empirical repro lives in /tmp/opencode/oc5/repro.rs (scratch, not in any Fera repo). Every claim re-verified directly; one path typo (dev/vera → dev/fera) and two off-by-a-few line refs were caught and fixed.

# file kind sev one-line
1 local-id-reuse-ack-misdelivery.md problem high next_local_id() resets, reissues -1; stale ACK marks wrong message Sent. Repro’d
2 no-panic-containment-at-dylib-boundary.md risk high ADR-002 native/no-sandbox, zero panic policy; panic=abort conflicts with catch_unwind
3 unpinned-git-deps-and-source-substitution.md risk high 3 git deps unpinned + gitignored locks + no --locked + global insteadOf rewrite
4 trust-tier-flat-keyring-authority-collapse.md risk high ADR-002 two tiers vs ADR-003 single flat keyring — authority-ladder collapse
5 offline-retry-schedule-unpersistable-no-idempotency.md problem high Instant in persisted outbox ⇒ backoff lost on restart; no idempotency key; no eviction
6 hazard-pointers-cannot-allow-dylib-unmap.md risk high HP/QSBR protect heap objects, not code; timeout fallback unmaps under a stalled thread
7 storage-seam-frozen-wrong-shape.md risk high trait frozen on bare Message not Encrypted<T>; ADR-031 leaves LRU cache + outbox unassigned
8 calls-ffi-no-fault-propagation-policy.md risk high no unwind/exception policy at the C++↔Rust calls boundary; polling defers it to the worst moment
9 lattice-no-trust-anchor-defined.md risk mid spec defines verification, never the trusted-key set; lttc verify has no key policy
10 perf-claims-unmeasured-gate-is-stub.md risk mid ~30% WASM + dylib-crossing costs unmeasured; criterion absent; bench-scene is a 15-line stub
11 media-decode-no-budget-untrusted-input-unnamed.md risk mid remote media decode has no budget/dimension/frame caps; untrusted-input class unnamed
12 qsbr-work-stealing-per-thread-invariant.md risk mid QSBR quiescence is per-thread; OQ-024 specifies work-stealing ⇒ invariant unsound as written

8 high, 4 mid. No low — I dropped anything that did not survive self-verification.

The load-bearing chain (this is the actual thesis)

Section titled “The load-bearing chain (this is the actual thesis)”

Findings 2, 4, 6, 8, 10, 12 are one defect wearing six hats: the architecture assumes a fast, unsandboxed, hot-swappable native tier is free, and never paid for the containment that costs.

  • #10: the premise (“native is fast enough to matter”, “dylib crossing is measurably expensive”) is unmeasured — and it is the premise for #2, #4 and #12.
  • #2 + #6: catch_unwind at the module boundary turns a panic into the “grace period stalled” trigger for the timeout unmap. These two must land together or the fix makes things worse.
  • #4: a flat keyring means one user-added key grants unsandboxed native.
  • #8: the calls boundary is the same problem with a C++ counterparty and remote input.
  • #12: the reclamation scheme that is supposed to make hot-swap safe has an unsound invariant as specified.

Fixing the perf claim first (cheapest: label it [unmeasured], as RESEARCH-OQ-003 already does honestly) may dissolve some of the rest.

  • oc4 challenged my #2 ABI premise. Conceded — OQ.md:838, 878-880 already decided first-party = Rust ABI (their evidence was right, and I verified it before conceding). Pushed back on three points: the rustc pin is a self-reported metadata string (under ADR-004 it is forgeable); static linking conflicts with ADR-001/ADR-020’s hundreds-of-hot-swappable- dylibs premise; and the real bug is downstream (#6).
  • oc4 and I converged, did not compete, on local-id-reuse: their stable-OpId + idempotency key is the same shape as my (local_id, attempt) correlation key plus my #5 idempotency token. Agreed one fix.
  • oc3 flagged that the rstgcalls FFI scaffold exists only in /tmp and the repo has 0 rust files — which corroborates #8’s “this is plan text, not shipped code”.

Watch list for whoever sequences the fixes

Section titled “Watch list for whoever sequences the fixes”
  1. CELL_BUDGET = 128 vs the frozen 500-chat scene (#2/#10) — the sanctioned benchmark panics the render loop. assert! → Result, or raise the budget.
  2. next_local_id (#1) — fix before the sanakirja engine lands, while MemoryEngine is the only impl.
  3. StorageEngine trait signature (#7) — same window: one impl today, free now.
  4. The rustc-version pin (#2) — verify the artifact’s embedded metadata, not the manifest’s claim.
  5. Open questions I could not answer from the corpus:
    • Is the native tier intended to be user-key-trustable at all, or only root-key-signable? (Decides #4’s option 1 vs 2; cheap now, expensive later.)
    • Is the module ABI extern "C" or Rust-ABI trait object? oc4 answered per-tier; the third-party-native row (ADR-024 dev mode) is still open.