Skip to content

feat: /contracts — the visual lattice, live from the signed projection - #139

Open
bdelanghe wants to merge 1 commit into
mainfrom
feat/contract-lattice-page
Open

feat: /contracts — the visual lattice, live from the signed projection#139
bdelanghe wants to merge 1 commit into
mainfrom
feat/contract-lattice-page

Conversation

@bdelanghe

Copy link
Copy Markdown
Contributor

Summary

The final consumer of the trellis lattice projection — a visual page at /contracts.

  • contracts.html — brand-styled; client-fetches the signed status.json and renders the lattice: summary tiles (repos / edges / checked / passing / gaps) + a graded matrix (✅ Enforced / 🔴 Gap / 📐 Declared) per contract type, verified edges first. Always live (fetched at page load). Ships the copy-pasteable cosign verify-blob command — don't trust the page, check the source.
  • build.mjs — adds contracts.html to the page-copy list.
  • data/nav.jsonld — adds Contracts to the canonical nav.

Same signed artifact the Trust Center reads — one source of truth, two faces: grep-verifiable claims + a visual map. The two red drift edges (keeper-wire, door-kit-mirror) show publicly as gaps.

The full pipeline is now complete

trellis CI → checks → status.json → cosign sign → status branch   (emit+sign+publish)
   → Trust Center  → verify → graded claims                        (grep-verifiable)
   → bounded.tools → fetch → visual matrix                         (this PR)

Verification

Ran the page's render logic against the live status.json (73 repos, 4 checked, 2 passing / 2 gaps — matrix orders verified-first). nav.jsonld valid JSON. Full build.mjs runs in CI where brand assets are materialized (nix/npm).

Checklist

  1. Independent PR — one page + its build/nav wiring.
  2. Verified — render logic exercised against the live projection; nav JSON valid.
  3. Root cause — N/A.
  4. No duplication — consumes trellis's single signed artifact.
  5. No unrelated changes — N/A.

The final consumer of the trellis status projection: a brand-styled page that
client-fetches the signed status.json and renders the contract lattice — summary
tiles + a graded matrix (✅ Enforced / 🔴 Gap / 📐 Declared) per contract type.
Always live (fetched at page load); the two red drift edges show honestly as
gaps. Includes the copy-pasteable cosign verify command — don't trust the page,
check the source.

Same signed artifact the Trust Center reads; one source of truth, two faces
(grep-verifiable claims + a visual map). Added to build.mjs's page list and the
canonical nav (data/nav.jsonld → 'Contracts').

Verified the render logic against the live status.json (73 repos, 2 passing /
2 gaps); nav.jsonld valid. Brand assets materialize in CI (nix/npm).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V6j1N17T8exXeF8S6r99EM
bdelanghe added a commit that referenced this pull request Jul 5, 2026
…real (#144)

* feat: render the contract lattice at build time, verify the sync for real

/contracts (PR #139) was 100% client-side JS (fetch + DOM render at page
load), so axe/structure-audit/checks only ever saw a "Loading…" placeholder in
the static build output — that's why it never went green.

data/lattice.json + scripts/gen-lattice.mjs already vendor trellis's signed
projection into the build pipeline (#142). This finishes the job:

- contracts.html renders the lattice section at build time from
  data/lattice.json via scripts/gen-contracts.mjs (marker-spliced, offline,
  deterministic — mirrors gen-registry.mjs's --check pattern), so the static
  output has real content instead of a loading spinner.
- lattice-refresh.yml now actually runs `cosign verify-blob` against trellis's
  signed status.json before curating it (the prior version's comment claimed
  this happens in CI; nothing did). Verification runs against the exact bytes
  curated via gen-lattice.mjs's new --from-file flag, and only a
  verified + changed projection opens a PR. A pull_request-triggered `check`
  job (offline) fails if contracts.html drifts from data/lattice.json.
- wired contracts.html into build.mjs's static copy + data/nav.jsonld's
  primary nav; regenerated the structure-audit baseline for the new page.

Verified locally: build, axe (10/10 pages, 0 violations), structure-audit,
shacl, and the deno contracts gate all pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: contracts.html needs og:title/og:description/og:image + a ≤160-char description

brand-checks' meta.mjs gate (required for every non-40x page) failed: 3
required tags missing. Brought contracts.html's <head> up to the same social/
meta parity as conformance.html (og:*, twitter:*) and shortened the
description to 145 chars.

* fix: contracts.html's inline CSS must use bare var(), not var(--x, #fallback)

brand's colour-usage gate only recognizes var(--bs-x) with no fallback
argument as "tokenized" — var(--bs-color-forest, #0C5A42) leaves the fallback
hex exposed as a raw-colour violation (7 hits: 1x ink, 3x forest, 3x clay-red).
Dropped the fallbacks and swapped the ad-hoc #b3261e for the palette's actual
--bs-color-clay (the existing danger/red token); --bs-color-ink already
covers the intro text color.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant