Skip to content

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

Lattice is a frozen spec plus 983 lines of pure byte-codecs: no reader, no crypto, no capabilities, no WASM — and its newest code is uncommitted

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

Lattice is a frozen spec plus 983 lines of pure byte-codecs: no reader, no crypto, no capabilities, no WASM — and its newest code is uncommitted

Section titled “Lattice is a frozen spec plus 983 lines of pure byte-codecs: no reader, no crypto, no capabilities, no WASM — and its newest code is uncommitted”
  • kind: problem
  • area: modules
  • severity: high

Repo state (~/dev/fera/lattice): remote the-fera/lattice, 3 commits, the only one containing code is 7996b97 “pre-migration snapshot”. Language: Rust only, 983 LOC across 8 files (fs_node.rs 523, superblock.rs 177, error.rs 78, block_table.rs 56, cid.rs 56, merkle.rs 49, pointer_table.rs 13, lib.rs 31) against a 920-line SPEC.md. Branch feat/core-writer-reader has zero commits.

A git dependency on lattice from Fera would not compile today. git status --short reports:

?? TODO.md
?? crates/lttc-format/src/fs_node.rs
?? crates/lttc-format/src/pointer_table.rs

but crates/lttc-format/src/lib.rs:12,14 declares mod fs_node; and mod pointer_table;. The two files that hold 536 of the 983 lines are untracked local files. HEAD does not build; only the working tree does.

Two declared dependencies are referenced by zero lines of Rust. crates/lttc-format/Cargo.toml:9-12 declares blake3 and serde. grep -rn "blake3\|serde" crates/lttc-format/src/ | wc -l → 0. So no hashing has ever executed and no manifest has ever been serialized in this crate.

No reader and no writer exist. crates/lttc-format/src/lib.rs:1-5 states “No I/O. Every type here is a byte-exact mirror of a frozen structure in SPEC.md”. There is no open, no read_block, no verify, no unpack — only encode/decode byte codecs. pointer_table.rs:1-3 is explicit: “TEMPORARY compile stub — Task A1 needs the crate to build so its tests can run; this file is replaced by Task A2 and is never committed.”

No capability enforcement of any kind. grep -rn "capability\|sandbox\|grant\|policy" crates/**/*.rs → zero hits. Capabilities exist only as spec prose: the manifest field capabilities_requested (SPEC.md:328), and the frozen capability→subtree map at SPEC.md:445-455 (translations.read→/localization, themes.read→/themes, code.execute→/code), realized as WASI preopens (“Capability = subtree”, SPEC.md:455). There is no capability type, no manifest parser, and no enforcing code — so neither the load-time surface reduction that ADR-002 requires nor a call-time policy check exists.

No WASM runtime. No wasmtime/wasmer/wasm3/wasm-tools/wit-bindgen in Cargo.toml or Cargo.lock. wasmtime appears only as prose (SPEC.md:788-789, README.md:47,51).

Not consumable by Fera. Not published on crates.io (the API returns “crate lttc-format does not exist”). No C ABI, no stable reader API, version = "0.1.0", #![forbid(unsafe_code)] only. grep -rni fera crates/ --include='*.rs' → empty; “fera” appears in lattice only in docs and the repository URL.

Testing: 16 tests, all in fs_node.rs (#[cfg(test)] appears exactly once in the crate). superblock.rs, block_table.rs, merkle.rs, cid.rs, error.rs have no tests at all. Zero fixture .lttc files, no tests/ dir, no integration test. TODO.md has 34 unchecked boxes; every box in Phase A and Phase B is [ ].

Two silent-acceptance defects in committed codecs (verified directly, contrasted against their own spec):

  1. crates/lttc-format/src/merkle.rs:44-46 — unknown node-kind byte is accepted as Leaf:
kind: match b[66] {
0x01 => NodeKindDiscriminant::Internal,
_ => NodeKindDiscriminant::Leaf,
},

fs_node.rs:107-109 hard-refuses an unknown kind in the same crate, so the two are inconsistent with each other.

  1. crates/lttc-format/src/block_table.rs:47 — pub fn decode(b: &[u8; BLOCK_TABLE_ENTRY_SIZE]) -> Self is infallible (returns Self, not Result), while SPEC.md:610-614 requires: “bits 2–31 reserved, must be zero in writers, must-error in readers”, and SPEC.md:605-609 requires readers to “validate sort order and uniqueness in one O(n) pass on load and hard-error on violation (LttcError::MalformedBlockTable)”.

ADR-002 requires that an unauthorized capability be “absent from the callable surface, not merely policy-checked at call time” (TECHSPEC.md:336-339, restated as the plugins-sdk charter at plugins-sdk/src/lib.rs:3-6). That is a load-time property: it can only be delivered by the container reader that constructs the instance and decides which interfaces to link.

That reader does not exist. So the sandbox tier’s central security property currently has no implementation point in the entire ecosystem — lattice has no reader, plugins-sdk has 10 lines and an empty [dependencies], and wasmtime is not a dependency of anything in any repo. Note this is not a criticism: OQ-013 explicitly defers the container format (“Final format spec is still pending”, OQ.md:344-347), and TECHSPEC.md:359 records “Plugin container format: open — deferred to the author (OQ-013)”. The honest finding is about what the deferral means in practice, plus two real defects in code that is committed.

The two silent-acceptance defects matter more than they look. Both are in the structures a future reader will use to find and verify content. A container whose block table may contain unsorted or duplicate digests, with reserved flag bits set, will be read as valid. A Merkle tree whose node kinds are silently coerced will verify a tree that was not the tree that was signed. For a format whose entire purpose is to carry signed, capability-gated plugins, “accept a malformed structure quietly” is the wrong default at exactly the layer where the spec already demanded hard-error.

Варианты решения (с tradeoffs)

Section titled “Варианты решения (с tradeoffs)”

Option A — commit the working tree and treat the current state as an honest pre-implementation snapshot.

  • Cost: one git add.
  • Benefit: makes the repo buildable from a clean clone; today it does not, which is the most concrete defect in the whole lattice story.

Option B — make decode fallible now, before a reader exists.

  • Cost: changes every call site’s signature; fs_node.rs already does this (fs_node.rs:107-109) so there is a precedent in-crate.
  • Benefit: the reserved-flag and sort-order rules become types rather than comments, enforced before any consumer is written.

Option C — leave lattice alone; it is a separate project with its own TODO.md and roadmap.

  • Cost: Fera keeps a dependency it cannot consume.
  • Benefit: respects the project’s own sequencing; TODO.md already tracks A1/A2/B5 correctly.

A immediately (it is a bug, not a design choice), then B, then let C stand for the rest.

  1. Commit fs_node.rs and pointer_table.rs. HEAD does not compile because lib.rs:12,14 declares modules that git does not track. Until that is fixed, lattice cannot be a git dependency, cannot be vendored, and cannot be reviewed by anyone but the author. This is the whole blocker on the “readiness” question — not the missing features.
  2. Make MerkleNode::decode reject unknown kind bytes and BlockTableEntry::decode return Result, enforcing SPEC.md:610-614. Both rules are already written in the spec; the codecs are simply not honoring them yet. LttcError already has the right variants and stable exit codes (error.rs:9-49,57-77).
  3. Either use or drop the blake3/serde dependencies. Two declared-but-unused deps read as “hashing is done” to anyone auditing the supply chain, and will trip unused_crate_dependencies in any workspace that adopts it.
  4. Do not attempt to make lattice Fera-consumable before the OQ-013 spec freeze completes. The capability→subtree map (SPEC.md:445-455) is a good design and the enforcement point is clear (the reader). The right order is: reader lands, then capability enforcement lands in the reader, then plugins-sdk gets its WIT interfaces. Reversing that order would put a policy check at the wrong layer, which is the specific thing ADR-002 forbids.
  • docs/oc3/005-launcher-trust-plugins-are-skeletons.md — the other half of the plugin tier, also empty of enforcement
  • docs/oc3/009-no-closed-alpha-scope.md — OQ-013 being open is not a closed-alpha blocker, but “container format deferred” should be stated as such rather than discovered
  • OQ.md:437-438 references context/LATTICE.md, a document that does not exist in the corpus — see docs/oc3/010-spec-hygiene-defects.md