Closed general

Local precheck for the hardware gates (.glb + 16:10 hero) before upload

Colby Knox · 24d ago ·closed by Colby Knox

Server contract shipped to prod 2026-09-25 (git-wiki 658d9f0). The CLI needs nothing for correctness: every refusal is a 400 with code, data and hints[], which the CLI already prints. This issue is the local precheck so a user fails in 0 ms instead of after uploading a tarball.

The rule

A PUBLIC page of type component (manifest type: hardware or component) with kind component, molecule, board or unset must have:

  • a .glb in its repo (anywhere in the tree, any name);
  • a hero that is a PNG, 16:10 (tolerance 0.03), at least 1600 px wide. No Hero Studio provenance is needed on hardware pages.

Private pages get the same findings as level: warning hints and the write lands; a page cannot go public until both hold.

Codes (400)

code where data
HARDWARE_3D_MODEL_REQUIRED repo push to a public page with no .glb after the push; page visibility public; pkg publish of a public package with no .glb in the tarball or the existing repo { ref, kind, accepted: [".glb"] }
HARDWARE_HERO_INVALID repo push that sets or replaces the hero; page hero --image / --screenshot; visibility -> public; publish with a declared hero { ref, path, reason: "not_png" | "bad_dimensions", width?, height?, aspect?, required: { min_width: 1600, aspect: 1.6, tolerance: 0.03, format: "png" } }
HARDWARE_HERO_REQUIRED visibility -> public with no hero declared { ref }

Valves on the server: ADOMPKG_REQUIRE_3D_MODEL=0, ADOMPKG_REQUIRE_HARDWARE_HERO=0. Reference: docs/git-wiki-api-reference.md "Hardware gates", docs/hint-codes.md.

Asks (CLI side)

  1. pkg publish and repo push on a hardware page that is or will be public: before upload, check the package dir / pushed file set for a .glb; when the page exists, GET /api/v1/pages/<ref>/files?recursive=1 tells whether the repo already has one. Refuse locally with the same code and the same hint text the server would send (the server's hints[0].message is the canonical wording; copy it).
  2. page hero --image <path> and --screenshot <path> on a hardware page: read the PNG header (IHDR width/height, 8 bytes at offset 16) and refuse locally on the same rule. No image library needed.
  3. pkg lint for hardware packages: the same two checks as warnings.
  4. When the page is private, print the server's warning hints as-is (they already say "making it public will refuse until this is fixed").

Whether the local checks read the kind from page.json/package.json (kind) or just from type, treat a missing kind as gated (the server does).

Server-side tests for the exact responses: test/pages/hardware-gates.test.mjs in git-wiki.

1 Reply

Colby Knox · 24d ago

Shipped in adom-wiki 1.7.60 (all five platforms through the release gate; a0aeaa9). All four asks, with the server's codes, data shapes and message text (the local copy adds the file's own facts in front, e.g. "docs/hero.png is 1600x1600 (1:1)"), mirrored from lib/hardware-gates.js.

  1. pkg publish landing public (explicit visibility, else the existing page's, else private under an org and public otherwise, the same resolution as the server): a .glb in the tarball or in the page repo (one ?recursive=1 listing), and a declared hero read from disk. Both problems are reported in one refusal, where the server stops at the first. --skip-lint does not cover them. repo push to a public hardware page: the repo keeps a .glb after the push, and a hero the push sets or replaces (a pushed page.json hero, or bytes over the current hero path) is validated from the pushed bytes. A branch push is not gated, as on the server.
  2. page hero --image / --screenshot on a hardware page: the IHDR width and height from the file's first 24 bytes when that repo path is on disk, on any visibility, since the server gates this route on private pages too.
  3. pkg lint: both checks as warnings, plus a note when a hardware package declares no hero.
  4. Private pushes print the server's warning hints as they come (no local duplicate); a private pkg publish lands with the same findings as warnings, worded the same way.

A missing or unknown kind is gated, like the server. Anything the CLI cannot read (the page, the listing, a hero not on disk) is left to the server rather than refused on a guess. ADOM_WIKI_HARDWARE_PRECHECK=0 turns the local refusals off for the day the registry's valves are open.

Verified on staging against the server's own answers with the precheck off, on test5 throwaways (both deleted after): page hero on a private board page with a 1600x1600, a 1200x750 and a non-PNG file (local 0.17 s, same HARDWARE_HERO_INVALID as the server); a square image pushed over the public page's hero (local refusal in 0.20 s, the server refuses the same, hero untouched, ordinary pushes still land); a public board package with no .glb and a square hero (local refusal in 0.30 s naming both, server HARDWARE_3D_MODEL_REQUIRED, nothing created); the same package --private (lands with both warnings); a private README push (the server's HARDWARE_3D_MODEL_REQUIRED warning printed as-is). Docs: hint-codes rows for the three codes plus HARDWARE_PRECHECK, and a Hardware gates section in the skill.

Log in to reply.