Embedding turns signed payload fragments into carrier observations. The current implementation favors deterministic frame plans and explainable budgets over maximum capacity.
Visual carrier
@lss/embedder currently exposes a simple visual frame plan, not a full production image codec. createVisualFramePlan maps each character in fragmentData to one timed frame. Each frame contains four normalized luma regions near the bottom of the image. The regions use a small positive or negative luma delta based on the character code parity.
The richer 24 by 24 grid codec used by the web demo is app-level carrier work, not the @lss/embedder package contract. Package docs should treat the frame plan as the stable package API.
Audio carrier
The audio path is also deliberately small. createTonePlan maps each character in fragmentData to one of four ultrasonic frequencies: 16200, 16700, 17200, or 17700 Hz. renderTonePlan renders those symbols into a Float32Array at the requested sample rate with low amplitude.
This is useful for deterministic package tests and for exploring a second observation family. Production behavior should treat audio as a contributor to confidence, not as the only reliability path yet.
Practical budget
The practical package budget is intentionally tiny. Real media paths need repeated opportunities because compression, scaling, frame interpolation, filters, and screen recording can erase or distort visual regions or tones. Pointer mode is the compact payload shape to prefer for production-style flows; manifest mode is useful when the scan result needs to carry more data directly.
Redundancy plan
Embedding should be planned like a lossy network path. A platform transcode can remove frames, a crop can hide visual regions, and a replayed screen can introduce blur or refresh artifacts. The embedder should therefore spend capacity on repeated fragments before it spends capacity on larger payloads.
Good carrier plans make redundancy explicit:
- Repeat each fragment across multiple frame opportunities.
- Spread adjacent fragments across time so one bad segment does not erase a whole payload range.
- Keep visual and audio channel hints in the fragment metadata so the reader can compare evidence families.
- Prefer compact pointer payloads when the action can be resolved online.
The goal is not to make every single frame self-sufficient. The goal is to create enough independent observations that @lss/reader can reconstruct the same signed envelope after ordinary media damage.
Package boundary
@lss/embedder should not decide whether an action is allowed. It receives fragment data derived from @lss/protocol output and plans carrier output. Signature verification, expiry checks, issuer policy, and action policy belong before or around resolver handoff, not inside the embedder.