Site shell contract Configure the shared Foundry header, navigation, footer, and shell behavior. v0.2.6 core current site-builderscore-developers
v0.2.6 core current Public

Site shell contract

Configure the shared Foundry header, navigation, footer, and shell behavior.

Owner
Foundry Core
Source
core/docs/SHELL.md
Ref
v0.1.24
Policy
release-bound
Component pins for v0.2.6
ComponentRoleVersion
coreruntimev0.1.24
theme-shieldthemev0.1.15
starterreferencev0.1.3
docsreferencev0.1.4
distributiontoolingv0.3.4
restricted-component-1consumer-referencev0.1.22
restricted-component-2consumer-referencev1.1.21

Phase: 08-shell-contract-governance Status: Stable (v1)

The Foundry shell contract defines how downstream themes and sites configure site chrome — header, navigation, footer, utility surfaces, and page-level exceptions — without copying shell partials locally.


Why a Shell Contract?

Without a contract, every site ends up with:

  • Local copies of layouts/partials/header/, layouts/partials/footer/, and layouts/_default/baseof.html
  • Bespoke template conditions scattered across dozens of partials
  • No machine-readable ownership model → AI editors can’t safely touch shell code
  • Governance by tribal knowledge rather than validated structure

The shell contract moves this behaviour into typed, schema-backed Core ownership that downstream repos configure rather than copy.


Artifacts

FilePurpose
schemas/foundry/shell-manifest.schema.jsonTyped contract for all shell surfaces
schemas/foundry/page-shell.schema.jsonPage-level chrome exception fields
layouts/partials/helpers/page-shell-params.htmlHugo partial that normalizes page front matter into the contract
scripts/validate-shell-contract.jsValidates Core contract artifacts are internally consistent
scripts/validate-shell-overrides.jsAudits downstream repos for unallowlisted shell shadows

Shell Surfaces (shell-manifest)

The shell manifest covers these surfaces:

SurfaceRequiredDescription
brandSite name, logo assets, home URL
navPrimary navigation (menu-driven or explicit links)
utility_navSecondary nav (language, preferences, auth)
searchSearch entry point
preferencesLanguage/theme/locale toggles
announcementTop-of-page announcement banner
primary_ctaHeader call-to-action button
footerFooter columns, legal nav, contact, social

All link entries in the manifest use a typed kind field:

KindMeaning
internalSite-local link (Hugo relURL)
externalOff-site link (opens with explicit rel)
anchorOn-page anchor (#section-id)
menu-drivenResolved from Hugo menus at build time
route-ownerPoints to the canonical owner of a content section

Page-Level Chrome Exceptions (page-shell)

Pages declare shell behaviour through front matter fields that are normalized by helpers/page-shell-params.html:

# content/some-page/_index.md
---
title: Landing Page
header_mode: transparent      # overlays first content block
footer_mode: minimal          # legal links only
hide_site_chrome: false       # true = full chrome suppression
route_owner: consult          # canonical section key
utility_surface: cta-only     # show only primary CTA in header
show_breadcrumbs: true        # render visible breadcrumbs when shell supports it
noindex: false
suppress_announcement: false
shell_compat_mode: false       # set true only during phased migration
---

Field Reference

FieldTypeDefaultValues
hide_site_chromeboolfalseSuppresses header + footer
header_modestring"default"default, transparent, minimal, hidden
footer_modestring"default"default, minimal, hidden
announcement_keystringMaps to data/announcements/{key}.yaml
suppress_announcementboolfalseHides site-level announcement on this page
route_ownerstringContent section key (e.g. consult, blog)
utility_surfacestring"default"default, none, cta-only, search-only
show_breadcrumbsboolfalseOpts the page into visible breadcrumbs
breadcrumb_home_labelstringsite home titleOptional home crumb label
breadcrumb_labelstring"Breadcrumb"Accessible nav label
breadcrumb_include_currentbooltrueIncludes current page as final crumb
noindexboolfalseAdds <meta name="robots" content="noindex">
shell_compat_modeboolfalseEnables legacy param resolution during migration

Using the Helper Partial

In your base layout or shell partial, resolve page-shell params once at the top:

{{/* layouts/_default/baseof.html */}}
{{ $shell := partial "foundry/helpers/page-shell-params.html" . }}

{{ if not $shell.hide_site_chrome }}
  {{ partial "header/site-header.html" (dict "page" . "shell" $shell) }}
{{ end }}

{{ block "main" . }}{{ end }}

{{ if not $shell.hide_site_chrome }}
  {{ partial "footer/site-footer.html" (dict "page" . "shell" $shell) }}
{{ end }}

The helper handles:

  • Reading typed contract fields from .Params
  • Applying defaults for missing fields
  • Legacy compat: falls back to older param names during migration

Visible Breadcrumbs

Foundry already emits breadcrumb structured data through SEO schema. For visible page breadcrumbs, call the shared partial from the shell where the site wants breadcrumbs to appear:

{{ partial "foundry/navigation/breadcrumbs.html" (dict "page" . "shell" $shell) }}

The partial renders only when show_breadcrumbs: true and when the current page has more than one crumb. It uses Hugo ancestors, respects breadcrumb_home_label, and marks the current page with aria-current="page".


Ownership Model

LayerOwns
Foundry CoreShell schemas, typed surface definitions, validators, helper partial
ThemeShell variant implementations (transparent header, minimal footer layouts)
SiteShell configuration (menu keys, CTA copy, contact info, route priorities)

Sites configure shell behaviour through the contract. They do not copy shell partials unless:

  1. The needed behaviour cannot be expressed through the contract
  2. The shadow is documented in .planning/shadow-copy-review.md with a reason and migration phase
  3. The shadow passes the override validator with an explicit allowlist entry

Validation

# 1. Validate Core contract artifacts
cd /path/to/likestyle-foundry-core
node scripts/validate-shell-contract.js

# 2. Audit a downstream repo for shell shadows
node scripts/validate-shell-overrides.js /path/to/downstream-repo

# 3. With allowlist (for documented temporary shadows)
node scripts/validate-shell-overrides.js /path/to/downstream-repo \
  --allowlist /path/to/downstream-repo/.planning/shell-shadow-allowlist.json

Shell Shadow Migration Path

If a downstream repo has temporary shell shadows (common during initial adoption):

  1. Document each shadow in .planning/shadow-copy-review.md under “Shell Shadows” with a reason and target phase.
  2. Create .planning/shell-shadow-allowlist.json listing the shadow paths.
  3. Run validate-shell-overrides.js --allowlist in CI to catch any new unreviewed shadows.
  4. Retire the shadow in the designated phase by adopting the Core contract field or theme variant.
  5. Remove the allowlist entry and confirm the validator exits 0.

Compatibility Mode

During migration, set shell_compat_mode: true in page front matter to enable legacy param resolution alongside the new contract. This allows incremental per-page migration without a big-bang rewrite. Remove shell_compat_mode once all pages in a section are migrated.


What This Phase Does Not Do

  • Move high-consideration service proof site route labels, CTA copy, or contact info into Core defaults
  • Implement final header/footer rendering for any specific theme
  • Expand into runtime personalization or non-shell product work
  • Promote any shell primitive to “shield” status before a second consumer proves genericity

These are targets for Phase 09 (Theme Capability & Shared Shell Rendering) and Phase 10 (high-consideration service proof site Pilot & Exception Retirement).

Static Pagefind search

Search Foundry documentation

Type at least two characters
Search the full documentation system

Results stay inside this build profile and can be filtered by version, component, audience, and lifecycle.