LAWSOFUX · motion lab
Concept · postels-law

Postel's Law

Opacity-stepped bands palette · forest / cream takeaways · 4

Definition

Be liberal in what you accept and conservative in what you send. The system tolerates messy, varied, and even malformed input from users while producing strict, well-formed output to other systems. Resilience lives at the boundary.

Why it matters for ShurIQ reports

Search inputs, date filters, and natural-language queries on the viz hub should accept any plausible reader input — uppercase, lowercase, partial spellings, multiple languages — and resolve to canonical results. Likewise, evidence-trail data ingested from messy public sources must be normalized before it lands in a stack-rank cell. Tolerant inputs and disciplined outputs are what make the brief feel intelligent rather than brittle.

Takeaways

Visual motion language

Inputs animate from raw to normalized form (e.g., "BMW " becomes "BMW Group" with a magnetic-pull and a soft fade-in). The reader sees their input land in canonical state.

Cavalry recreation seed. 4 rows × 3 columns = 12 downward-pointing triangles inside a 567×580 panel. Each triangle 189×145, apex pointing down, vertices at (0,0), (189,0), (94.5,145) per cell. Cell origins: row 1 at y=0, row 2 at y=145, row 3 at y=290, row 4 at y=435; columns at x=0, 189, 378. All filled cream (#f4f1d0) with row-stepped fill-opacity: 1.0 / 0.8 / 0.6 / 0.4. Animate row-by-row top-to-bottom, all 3 triangles in a row entering simultaneously, ~250ms per row, ~1s total. Hold 2.5s; loop. Background: forest-green #2D5A3F. Replaces the lozenge-and-streams guess.

Origins

Jon Postel — formulated as the Robustness Principle for early TCP/IP implementations.

Cavalry scene

The script below builds this concept's motion in Cavalry through the Stallion bridge. Pipe to cavalry_run_script via MCP, or paste into Cavalry's JavaScript Editor.

// Laws of UX · postels-law · Cavalry scene
// CORRECTED 2026-04-30 · verified from production page
// Motion family: opacity-stepped horizontal bands (12 downward triangles in 4 rows x 3 cols)
// Row-stepped opacity 1.0/0.8/0.6/0.4; row-by-row reveal, all 3 in a row enter together
// Palette: forest-green + teals/cream
// To run: pipe to cavalry_run_script tool, or paste into Cavalry's JavaScript Editor
// Built 2026-04-30 by ShurAI

(function () {
  var PREFIX = "claude_lawofux_postels-law_";

  var existing = api.getAllSceneLayers();
  for (var i = 0; i < existing.length; i++) {
    try {
      var nm = api.getNiceName(existing[i]);
      if (nm && nm.indexOf("claude_lawofux_") === 0) api.deleteLayer(existing[i]);
    } catch (e) {}
  }

  var BG    = "#2D5A3F";
  var CREAM = "#D6CDB0";

  var bg = api.primitive("rectangle", PREFIX + "bg");
  api.set(bg, { "generator.dimensions": [1080, 1080] });
  api.setFill(bg, true);
  api.set(bg, { "material.materialColor": BG });

  // 4 rows x 3 cols = 12 downward-pointing triangles, scaled into 1080 canvas.
  // Cell dimensions: ~290 wide x 220 tall. Triangle fits cell.
  // Rotation.z = 180 to flip apex down.
  var triRadius = 145;          // polygon outer radius -> ~290px wide
  var rowOpacities = [100, 80, 60, 40];
  var rowBegin    = [0, 8, 16, 24];   // ~250ms per row at 30fps
  var COL_STEP = 290;
  var ROW_STEP = 220;
  var startX   = -COL_STEP;     // -290, 0, +290
  var startY   =  (3 * ROW_STEP) / 2 - ROW_STEP / 2; // top row Y (positive=up)

  for (var r = 0; r < 4; r++) {
    for (var c = 0; c < 3; c++) {
      var tri = api.primitive("polygon", PREFIX + "r" + (r+1) + "c" + (c+1));
      api.set(tri, {
        "generator.sides": 3,
        "generator.radius": triRadius,
        "position.x": startX + c * COL_STEP,
        "position.y": startY - r * ROW_STEP,
        "rotation.z": 180,
        "opacity": 0
      });
      api.setFill(tri, true);
      api.set(tri, { "material.materialColor": CREAM });

      var t0 = rowBegin[r];
      var t1 = t0 + 10;
      api.keyframe(tri, t0, { "opacity": 0 });
      api.keyframe(tri, t1, { "opacity": rowOpacities[r] });
      api.magicEasing(tri, "opacity", t1, "EaseOut", "");
    }
  }

  var layerCount = api.getAllSceneLayers().length;
  console.log("scene built: postels-law (" + layerCount + " layers)");
})();