# www.agentic-first.co — CHANGELOG Record of notable releases on the marketing site and the downloadable skills it serves. The directory MCP and the canonical schemas have their own versions (`directory_version`, `schema_version`) reported live by ; this file tracks **website + skills** changes only. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). We use ISO-8601 dates throughout. The site does not yet follow strict SemVer at the page level — page-level changes accumulate into periodic site releases, dated below. --- ## [2026-04-22b] — Dogfooding: agentic-first publishes itself as a sub-brand of YQUP The standard now eats its own food: `www.agentic-first.co` — the agentic-first standard's own marketing surface — is the **first real-world consumer of the schema 0.2.0 sub-brand support shipped this morning**. It declares `parent_brand: yqup.com` and the live directory shows the full umbrella linkage with the trust boost applied. `profiles_indexed` went from 1 (just YQUP) to 2. ### Added - **`www/.well-known/agentic-profile.json`** — Mode 1 profile served at the canonical well-known URL. - `schema_version: 0.2.0`, `profile_kind: company`, `tier: public`. - `parent_brand: yqup.com`. - `legal_name: YQUP LTD` and the same `companies-house: 04811754` registry block as YQUP — agentic-first is a brand of YQUP, not a separate legal entity. Both pointing at the same Companies House record is honest and earns the parent-trust boost. - Evidence pointing at GitHub (the open-source repo), the Companies House record (the registry claim), and `directory.agentic-first.co/healthz` (the standard's own running directory is its own evidence). - Contact through the existing `/feedback/` form on the same site — quarantine file, no LLM in the read path. - **Caddy `handle` block for `/.well-known/agentic-profile.json`** — pins `Content-Type: application/json; charset=utf-8` regardless of the Caddy version's mime sniffing on `/.well-known` paths (it's bitten other publishers in the wild). Adds a 5-minute cache header so reading agents don't hammer the origin. ### Verified live (in this order) ``` HTTP/2 200 content-type: application/json; charset=utf-8 cache-control: public, max-age=300 ``` `submit_website` returned `ok: true`, `discovery.method: "well-known-profile"`, zero validation errors, zero validation warnings. `score_inputs` standalone: `{completeness: 0.727, evidence_density: 0.6, verifiability: 0.667}`. `search_companies { parent_brand: "yqup.com" }` returned the sub-brand with every relationship signal lit: ```json { "domain": "www.agentic-first.co", "name": "agentic-first", "parent_brand": "yqup.com", "parent_brand_indexed": true, "parent_brand_name": "YQUP", "parent_brand_verified": true, "brand_role": "sub_brand", "score_inputs": { "completeness": 0.727, "evidence_density": 0.6, "verifiability": 0.767, "parent_brand_boost": 0.1 }, "brand_role_notes": [ "verifiability boosted by +0.1 because parent_brand 'yqup.com' is indexed and externally verified." ] } ``` `get_company { domain: "yqup.com" }` now inflates `brand_relationships.sub_brands: [{domain: "www.agentic-first.co", name: "agentic-first", verified: true}]`. `get_company { domain: "www.agentic-first.co" }` inflates `brand_relationships.parent: {domain: "yqup.com", indexed: true, name: "YQUP", verified: true, trust_boost: 0.1}`. ### Why this matters Two reasons: 1. **Strongest possible social proof for any agent reading the standard.** When an agent fetches `www.agentic-first.co/llms.txt` and follows it to the directory, the standard is itself indexed in the directory using the standard. There is no "do as I say not as I do" gap. 2. **First end-to-end exercise of the sub-brand path on real internet traffic.** Every previous verification of schema 0.2.0 was against fixtures or in-process tests. This run went through real DNS, real TLS, real Caddy, real well-known fetch, real SSRF guard, real schema validator, real reverse-index lookup, real trust-boost calculation. All clean. The sub-brand contract is now production-load-bearing, not just unit-test-load-bearing. --- ## [2026-04-22a] — Schema 0.2.0: sub-brand support The first minor schema bump since launch. Adds the ability for a brand to declare itself a sub-brand of an umbrella brand, so a single legal entity (or a portfolio) can publish multiple discoverable brands and have the directory understand the hierarchy. Worked example for the `agentic-first.co` family below. ### Added - **Schema `company-profile/0.2.0`.** New optional top-level `parent_brand` field — a bare lowercase domain (`yqup.com`, rejected: `https://yqup.com`, `YQUP.com`). Presence of the field marks the profile as a sub-brand; absence marks it as a standalone or umbrella brand. The 0.1.0 schema URL keeps serving for back-compat but the directory's canonical version is now 0.2.0; profiles still declaring 0.1.0 continue to validate without warnings via the new `SUPPORTED_SCHEMA_VERSIONS = {0.1.0, 0.2.0}` set. - **`search_companies { parent_brand: "" }`.** Returns only the indexed sub-brands pointing back to that umbrella. AND-combines with every existing filter (`q`, `industry`, `jurisdiction`, …). - **`search_companies { brand_role: "sub_brand" | "umbrella" | "standalone" }`.** Slice the index by topology when the parent's domain isn't known up front. `umbrella` matches any indexed profile that at least one sub-brand currently points back to. - **`get_company` brand-relationship inflation.** Fetching an umbrella surfaces a `brand_relationships.sub_brands[]` array of every indexed child; fetching a sub-brand surfaces a `brand_relationships.parent` block with the umbrella's name, indexed status, verified status, and the trust boost applied. - **Trust boost: `+0.1 verifiability` for verified-parent sub-brands.** A sub-brand whose declared parent is *also indexed* AND has its own external ID (Companies House registry record or GLEIF LEI) earns `+0.1` on `verifiability`, capped at `1.0`. Surfaced transparently on every search result as `score_inputs.parent_brand_boost` and noted in `brand_role_notes[]`. If the parent is unverified or not indexed yet, no boost is applied — stops the trust signal from being earnable by squatting on a domain. - **Mode 5 colophon support for `parent_brand`.** Sub-brands on text-only hosts paste one extra `parent_brand: ` field into their colophon; the existing parser handles it without code change because `parent_brand` is a flat string. Documented in the Mode 5 spec and the Gamma host recipe with a worked sub-brand example. - **New example:** `agentic-first/examples/company-public-sub-brand.json` showing `Acme Pick` as a sub-brand of `acme-robotics.example`. ### Changed - **`/healthz` now reports `schema_version: 0.2.0`** and `/schemas/company-profile-0.2.0.json` is the canonical company schema URL. The 0.1.0 file is still mirrored in the `agentic-first/schemas/company-profile/` directory for any publisher who has a `$ref` pinned to the older URL. ### Tests - `pkg/schema/tests/test_validator.py` — four new cases for `parent_brand`: valid bare domain passes, URL-with-scheme rejected, uppercase rejected, omission still passes. - `apps/api/tests/test_mcp_server.py` — six new cases covering `parent_brand` filtering, `brand_role` filtering, the trust boost applying, the boost *not* applying when the parent is unverified, the `parent_brand_indexed: false` signal when the parent hasn't published, and the `get_company` brand-relationship inflation in both directions. - 254 tests pass (was 244). ### Notes for publishers If you already have a `0.1.0` profile published, you don't have to do anything — it continues to validate and the directory continues to serve it. Bump to `schema_version: "0.2.0"` only when you want to add a `parent_brand`. The validator will flag *unsupported* versions with a soft warning (`schema_version_mismatch`) but accepts both `0.1.0` and `0.2.0` silently, so there's no churn from the bump itself. The umbrella brand publishes a normal profile and **does not** declare a `parent_brand` of its own — that would create a cycle. Sub-brands point at the umbrella, not the other way round (registry-style reverse index). --- ## [2026-04-21j] — Mode 5 hotfix: gzip-decoding + multi-marker bounding Two regressions surfaced the moment we tried to submit yqup.com end-to-end through the just-shipped Mode 5 path. Both are now fixed and pinned by regression tests so they cannot silently come back. ### Fixed - **`safe_request` no longer double-decompresses gzipped responses.** Production hosts (Gamma, Vercel, Cloudflare-fronted sites) gzip their HTML. `httpx.Response.aiter_bytes()` yields bytes that httpx has already decompressed; we were re-using the original `Content-Encoding: gzip` header on the materialised response, so any caller touching `.text` got a `DecodingError: incorrect header check`. The materialiser now strips `content-encoding`, `content-length`, and `transfer-encoding` after the body has been read — the bytes are plain text and the headers now say so. This unblocks every Mode 5 submission against a gzip host (which is most of them). - **Mode 5 parser bounds the colophon body so JSON in `__NEXT_DATA__` doesn't pollute the last field.** Single-page apps (Next.js / Gamma) inline a giant JSON dump in a `