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
Evidence
Section titled “Evidence”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.rsbut 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):
crates/lttc-format/src/merkle.rs:44-46— unknown node-kind byte is accepted asLeaf:
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.
crates/lttc-format/src/block_table.rs:47—pub fn decode(b: &[u8; BLOCK_TABLE_ENTRY_SIZE]) -> Selfis infallible (returnsSelf, notResult), whileSPEC.md:610-614requires: “bits 2–31 reserved, must be zero in writers, must-error in readers”, andSPEC.md:605-609requires 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.rsalready 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.mdalready tracks A1/A2/B5 correctly.
Предлагаемое решение
Section titled “Предлагаемое решение”A immediately (it is a bug, not a design choice), then B, then let C stand for the rest.
- Commit
fs_node.rsandpointer_table.rs. HEAD does not compile becauselib.rs:12,14declares 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. - Make
MerkleNode::decodereject unknown kind bytes andBlockTableEntry::decodereturnResult, enforcingSPEC.md:610-614. Both rules are already written in the spec; the codecs are simply not honoring them yet.LttcErroralready has the right variants and stable exit codes (error.rs:9-49,57-77). - Either use or drop the
blake3/serdedependencies. Two declared-but-unused deps read as “hashing is done” to anyone auditing the supply chain, and will tripunused_crate_dependenciesin any workspace that adopts it. - 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, thenplugins-sdkgets its WIT interfaces. Reversing that order would put a policy check at the wrong layer, which is the specific thing ADR-002 forbids.
Cross-references
Section titled “Cross-references”docs/oc3/005-launcher-trust-plugins-are-skeletons.md— the other half of the plugin tier, also empty of enforcementdocs/oc3/009-no-closed-alpha-scope.md—OQ-013being open is not a closed-alpha blocker, but “container format deferred” should be stated as such rather than discoveredOQ.md:437-438referencescontext/LATTICE.md, a document that does not exist in the corpus — seedocs/oc3/010-spec-hygiene-defects.md