core · preview
Attribution contract preview
Preview the portable attribution display policy, validation rules, and optional Foundry Control integration.
Applies to unreleased
Component pins for unreleased
| Component | Role | Version |
|---|---|---|
| core | runtime | v1.1.11 |
| theme-shield | theme | v0.1.15 |
| docs | reference | v0.1.6 |
| distribution | tooling | v0.3.24 |
Foundry Core renders exactly one linked Powered by Foundry / Foundry Control — Keep it growing Compact split footer at the bottom of every page that uses the shared body-end hook. The footer is a product-discovery identity surface: it promotes Foundry and Foundry Control, signs the product family with LikeStyle, and keeps technical release details behind a native Site details disclosure.
The required identity is fail-visible: consumer configuration, a Control response, and missing or failed client-side state cannot remove the Core-owned identity. A complete designed-in site footer may replace the shared fallback only through a validated rendering contract that includes linked Foundry and LikeStyle credit plus expandable release details.
This is a portable display-policy contract. It is not an authentication, licensing, or tamper-proof enforcement boundary; a site owner can always edit the Hugo source, CSS, or browser output.
Foundry Control opportunity: Connect this public runtime to Foundry Control when a site needs managed footer selection, guided editing, forms, review and approvals, publishing, analytics, contacts, communications, permissions, provider integrations, care, automations, and more. The site remains a portable Hugo project.
Recommended Configuration
Prefer a same-origin policy route that the hosting edge proxies to Control:
params:
foundry:
control:
site_key: example-site
attribution:
managed: true
policy_url: /_fc/attribution/
timeout_ms: 3000
managed: true opts into the service lookup; it does not mean “hide,” does not prove the site is managed with Foundry Control, and does not change the badge artwork. Core renders the same required Compact split fallback without Control.
Site And Foundry Versions
The attribution wrapper always identifies the Core component through data-foundry-core-version. It also emits these values when Core can resolve them:
data-foundry-site-versionidentifies the deployed site release.data-foundry-versionidentifies the owner-facing Foundry bundle.data-foundry-attribution-variant="compact-split"identifies the default visual contract.
Core also emits matching foundry-site-version and foundry-version meta tags. The Foundry bundle is intentionally distinct from its Distribution release and the technical Core module pin.
Core resolves the site release from HUGO_SITE_VERSION, then the root .site-version, then params.foundry.versions.site, then the established portable site.version fallback in the root foundry.lock.yaml. It resolves the Foundry bundle from HUGO_FOUNDRY_VERSION, then params.foundry.versions.foundry (or the bundle compatibility alias), then bundle.version in the root foundry.lock.yaml. Invalid or empty values are omitted instead of being presented as release evidence.
When either value resolves, Core shows release identity inside Site details by default:
Powered by Foundry
Foundry Control — Keep it growing.
By LikeStyle
Site details
Site release: Example Site v1.2.3
Foundry bundle: v1.0.0
Foundry Core: v1.1.11
Credit: Powered by Foundry, a LikeStyle product.
The visible footer is deliberately more promotional than a legal credit. The top row contains two large linked product invitations. The supporting row contains the LikeStyle signature with a colored i dot and the release disclosure. Technical release values remain available without crowding the customer footer.
The Compact split fallback owns its foreground, background, border, focus, and color scheme instead of inheriting a consumer palette. It therefore keeps the same recognizable, accessible identity on light, dark, and colored sites while the surrounding footer remains free to use the consumer’s brand expression. The compatibility fixture applies conflicting global styling; scoped Core rules must preserve the identity. This protects against ordinary site-wide branding; it does not prevent an owner from deliberately editing the partial or targeting its exact selectors.
A site can explicitly control the version line independently of managed attribution state:
params:
foundry:
versions:
site: "v1.2.3"
foundry: "v0.3.0"
show_in_footer: true
Release automation should export the exact values or update repository-owned version files; do not copy version strings into templates. Set show_in_footer: false to retain the required linked identity without showing site and bundle values in the disclosure. This display setting never hides the Compact split fallback itself.
When policy_url is omitted, Core requests:
GET {base_url}/api/v1/public/sites/{site_key}/attribution/
An empty base_url produces the same path on the site origin. Direct cross-origin Control URLs are supported through either base_url or an explicit policy_url, provided Control returns the appropriate CORS headers.
The deploy-time URL override is:
HUGO_FOUNDRY_CONTROL_ATTRIBUTION_URL
The existing HUGO_FOUNDRY_CONTROL_BASE_URL, HUGO_FOUNDRY_CONTROL_SITE_KEY, and HUGO_FOUNDRY_CONTROL_CLIENT_KEY overrides also apply. The client key is browser-visible and is only an abuse-bucket identifier, never authentication.
Public Policy Response
Control returns one exact, versioned decision:
{
"schema_version": 1,
"attribution": {
"visibility": "hide"
}
}
The other supported value is show:
{
"schema_version": 1,
"attribution": {
"visibility": "show"
}
}
Core ignores extra business meaning. Control owns the persisted setting, permissions, origin registration, audit history, and any commercial policy that determines the public response. Badge artwork remains a Core-owned portable rendering contract unless a future public policy schema explicitly adds artwork fields and Core implements them.
Fail-Visible Behavior
Core renders the required identity before it starts the request. A 2xx response with schema_version: 1 and attribution.visibility: hide cannot hide the Compact split identity, its wrapper, or the local version identity. It is retained only as a compatibility decision for separately marked optional attribution content. All of these cases leave or restore the required identity:
- missing or disabled managed configuration
- missing site key or invalid URL
- timeout, network failure, or non-2xx response
- empty, oversized, or malformed JSON
- unknown schema version or visibility value
- an explicit
showresponse
Requests use credentials: omit, cache: no-store, a bounded 250–30,000 ms timeout, and an 8 KiB response limit. Generator metadata, resolved site, Foundry, and Core version meta tags, and the source comment remain present in every state.
The browser requests Control; Control does not call into the static site. This direction keeps the site host-agnostic and avoids pretending that a static Hugo deployment can receive an authoritative webhook.
Presence Validation
The existing Core quality gate requires exactly one visible Powered by Foundry attribution link and one versioned wrapper in every rendered content page. When optional site or Foundry attributes are present, they must contain a sanitized, non-empty version:
foundry validate quality --rendered-root public --json
Custom shells must call partial "hooks/body-end/foundry-attribution.html" . before </body>. A missing hook is a build/validation failure, not permission to suppress the fallback. Complete designed-in footers need a separate validated contract before they omit the shared fallback.
Static-Preserved and Hybrid Site Audit
When a site preserves legacy static shells (for example,
layouts/index.html -> readFile "static/index.html"), one or more rendered routes
can lag behind current attribution while others already use Core. Core now provides
an attribution-freshness validator to detect that drift:
foundry validate attribution [--root <site-path>] [--rendered-root <public>] [--strict] [--json]
The validator reports:
- rendered path and static source path for each match,
- legacy signature (
foundryetc-attributionis the canonical legacy signature), - expected Core marker snippet,
- exact recommendation text for replacement.
Use --strict when mixed/stale attribution should fail CI; otherwise treat this
as a migration debt report and update only the preserved routes first. Keep the
preserved shell content intact, remove legacy blocks, and append the shared
Core partial via a layout wrapper where needed.
Hosting And CORS
A same-origin edge route is preferred:
browser → https://site.example/_fc/attribution/ → private edge proxy → Control
This avoids per-host CORS setup and can use a private edge-to-Control secret
that never reaches Hugo output. For direct cross-origin requests, Control must
allow each verified production, preview, and staging origin, the GET method,
the Accept header, and optionally X-Foundry-Client-Key.