diff --git a/.agents/skills/ak-docs-release-audit/SKILL.md b/.agents/skills/ak-docs-release-audit/SKILL.md index 97888ac..7b52db9 100644 --- a/.agents/skills/ak-docs-release-audit/SKILL.md +++ b/.agents/skills/ak-docs-release-audit/SKILL.md @@ -43,11 +43,15 @@ outside its evidence and need matched manual passes on the same Beta PR: `agentkit-kit---.tar.gz` and comparing per-skill `SKILL.md` frontmatter (`user-invocable`, `disable-model-invocation`). Refresh `kit-catalog-identities.json`, add public skill pages EN+VI, - update `skills/meta.{json,vi.json}` and skill index tables, bump the - Kit overview `| Skills | N |` count. Mirror into - `content/docs/stable/**` so the tree stays whole-copy-ready for the - next promotion. `disable-model-invocation: true` without - `user-invocable: true` stays `internal` (no public page). Identity + update `skills/meta.{json,vi.json}` and skill index tables, and bump the + Kit overview `| Skills | N |` count in Beta only. Keep EN/VI route parity + inside Beta, but do not mirror Beta-only pages or prose into + `content/docs/stable/**`; Stable remains bound to `channels.stable.tag` + until a reviewed whole-copy promotion. The current `check:catalog` guard + still assumes identical Kit routes and counts across channels; if a + legitimate Beta-only Kit addition trips it, stop and fix the guard contract + rather than copying the addition into Stable. `disable-model-invocation: + true` without `user-invocable: true` stays `internal` (no public page). Identity checks alone miss body drift (existing pages that advertise a retired form when SKILL.md prose, `.env.example`, or `skill.yaml` change with identity stable). Run the body-diff pass in diff --git a/.agents/skills/ak-release-update/SKILL.md b/.agents/skills/ak-release-update/SKILL.md index bd7f347..2272772 100644 --- a/.agents/skills/ak-release-update/SKILL.md +++ b/.agents/skills/ak-release-update/SKILL.md @@ -69,8 +69,8 @@ examples, and error paths. impact-map returns `paths: []`). Await the exact statement `approve REQ-…`. 5. **Handle contract v1 blind spots.** Run the manual passes in one PR: - - **CLI prose** — V1 authoring inside the approved paths only. - - **Kits** — diff kit tar bundles, author public skill pages EN+VI, + - **CLI prose** — V1 authoring inside the approved Beta paths only. + - **Kits** — diff kit tar bundles, author public Beta skill pages EN+VI, refresh `kit-catalog-identities.json`, update meta and skill index. See [`references/default-tab-detection.md`](references/default-tab-detection.md) for the diff-first classification. Also run the body-diff pass in @@ -78,7 +78,12 @@ examples, and error paths. [`references/kit-prose-drift.md`](../ak-docs-release-audit/references/kit-prose-drift.md) against existing kit skill pages — identity checks miss prose drift when a skill's SKILL.md body, `.env.example`, or `skill.yaml` - changes while frontmatter stays stable. + changes while frontmatter stays stable. Do not copy Beta-only Kit or + CLI changes into Stable; `stable ⊆ beta` is the cross-channel contract, + and Stable changes only through promotion. The current `check:catalog` + guard still assumes identical Kit routes and counts across channels; if a + Beta-only Kit addition trips it, fix that guard contract instead of + mirroring the addition into Stable. - **Desktop** — Layer A bump automatically; Layer B semi-auto with owner gate; Layer C deferred. See [`references/desktop-3-layer.md`](references/desktop-3-layer.md). @@ -95,6 +100,10 @@ examples, and error paths. stable/desktop-app reflects the stable build, not the beta build. Skip if the run does not target that channel. 7. **Validate, commit, and open PR.** + Preserve exact EN/VI source, published, and searchable route parity within + each channel and `stable ⊆ beta` across channels. Per-channel route and search counts may differ when Beta contains + features awaiting promotion; update reviewed baselines only from a fresh + build, never by copying those features into Stable. Run `pnpm install --frozen-lockfile`, `test`, `typecheck`, `lint`, `check:catalog`, `check:reference`, `build`, `check:quality`, `check:assets`, `check:links`. Commit per pass with descriptive diff --git a/AGENTS.md b/AGENTS.md index 23968a6..8047bb6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,10 +59,13 @@ continuous with the marketing site. Do **not** invent colours, fonts, or radii. ## Content structure - **Two channels:** `content/docs/stable/` and `content/docs/beta/` are Fumadocs - root folders (`meta.json` `"root": true`) rendered as Sidebar Tabs. Their page - trees must stay **identical in shape** — promotion is a whole-copy, so any - asymmetry breaks it. Content is equal at launch and diverges only when the - release-sync pipeline writes into a channel. + root folders (`meta.json` `"root": true`) rendered as Sidebar Tabs. Within + each channel, EN and VI must publish the same route shape. Across channels, + Stable must remain a subset of Beta; Beta may add routes and prose ahead of + the next promotion. Never mirror Beta-only content into `stable/` to satisfy + parity checks — Stable changes only through the whole-copy promotion pipeline. + The executable contract lives in `scripts/release-quality-shape.mjs`, + `scripts/release-quality-metrics.mjs`, and the route tests. - **Bilingual:** Fumadocs i18n (`lib/i18n.ts`), locales `en` (default) + `vi`, URL-prefixed (`/en`, `/vi`). Files use `.en.mdx` / `.vi.mdx`; nav labels use `meta.json` + `meta.vi.json`. A missing `.vi.mdx` falls back to English diff --git a/CLAUDE.md b/CLAUDE.md index 041455e..aa23e99 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,6 +24,8 @@ Checked out as siblings of this repo (paths relative to the repo root): - Screenshots for those pages live in `public/gui/`; see [`public/gui/README.md`](./public/gui/README.md) for the capture and optimization manifest. -- `stable` is machine-generated from `beta` by the promotion pipeline, so keep - new docs channel-neutral (relative links only) and keep the two channels - byte-identical for any page authored in both. +- `stable` is machine-generated from an exact `beta` snapshot by the promotion + pipeline. Keep new docs channel-neutral (relative links only), author release + updates in Beta, and let Stable change only through reviewed whole-copy + promotion. EN and VI keep the same route shape within each channel; Beta may + contain routes and prose that Stable has not promoted yet. diff --git a/docs/workflows/post-launch-operations.md b/docs/workflows/post-launch-operations.md index bf23dcd..5c42c6b 100644 --- a/docs/workflows/post-launch-operations.md +++ b/docs/workflows/post-launch-operations.md @@ -40,37 +40,23 @@ as a deterministic gate. ## Committed baseline and budgets -The baseline is committed in `scripts/release-quality-metrics.mjs` and -`scripts/release-quality-shape.mjs`. Changing a baseline is a reviewed decision, -not an automatic response to a red check. - -| Signal | Reviewed baseline | Gate | -| --- | ---: | ---: | -| Published routes per locale/channel | 377 | Exact | -| Output files | 18,290 | 22,863 reviewed budget; Cloudflare hard limit remains below 100,000 | -| Total `out/` bytes | 2,251,685,582 | 2,814,606,978 (+25%) | -| Search bytes | 19,911,284 | 23,068,672 (22 MiB) | -| Largest individual asset | Search, 19,911,284 bytes | Strictly below 26,214,400 (25 MiB) | - -The route guard compares exact EN/VI and Stable/Beta published route sets. Its -source-to-output contract also requires exactly 378 authored routes and reviews -the only two source-only routes: `changelog` (navigation data) and -`reference/release-notes` (composed release data). Its reviewed non-native and -generated classifications are: - -- `reference/cli-conventions`: channel-neutral English source with an explicit - Vietnamese body; -- `reference/cli/ak`: generated legacy redirect in both locales. - -There are no live English-body fallbacks in the published matrix. A future -missing Vietnamese body becomes an unclassified `english-fallback` and fails -CI until a reviewer approves the exception and verifies that the page discloses -the fallback. This prevents silent language fallback. - -The search index must contain exactly 376 page routes in each EN/VI and -Beta/Stable partition, with exact route parity and an exact match to published -routes after removing the reviewed generated redirect. The only reviewed -searchable page outside a channel is `/_showcase`. +The executable baselines live in `scripts/release-quality-shape.mjs` and +`scripts/release-quality-metrics.mjs`; use `quality:receipt` to record their +current values. Changing a count, budget, exclusion, or reviewed variant is a +reviewed decision, not an automatic response to a red check. + +The shape gate requires exact EN/VI source and published-route parity within +each channel. Across channels, every Stable route must exist in Beta, while Beta +may contain additional routes awaiting promotion. The same `stable ⊆ beta` +invariant applies to searchable routes. Search still requires exact EN/VI +parity within each channel and an exact match between published and searchable +routes after the reviewed exclusions. + +Reviewed source-only routes, generated routes, locale variants, out-of-channel +search pages, output budgets, and Cloudflare limits are declared beside their +checks in those scripts. Do not copy Beta-only content into Stable to make a +count or parity check pass; fix the contract defect or update the reviewed +per-channel baseline from a fresh build. ### Fixed search relevance diff --git a/docs/workflows/release-and-deploy.md b/docs/workflows/release-and-deploy.md index 69d1884..6dc6606 100644 --- a/docs/workflows/release-and-deploy.md +++ b/docs/workflows/release-and-deploy.md @@ -67,9 +67,15 @@ content. Re-running the same bundle/tag is **idempotent**. +A Beta sync may publish routes that do not yet exist in Stable. EN and VI must +keep identical source, published, and searchable route sets within each +channel, while every Stable route in those sets must still exist in Beta. The quality gates in +`scripts/release-quality-shape.mjs`, `scripts/release-quality-metrics.mjs`, and +the route tests enforce this `stable ⊆ beta` contract. + ### What Beta sync does *not* refresh -`sync-release.mjs` is scoped to what the docs-bundle carries. Two surfaces +`sync-release.mjs` is scoped to what the docs-bundle carries. Three surfaces drift silently across releases and need their own manual passes on the same Beta PR (or an immediate follow-up): @@ -113,16 +119,20 @@ Beta PR (or an immediate follow-up): `skills/meta.{json,vi.json}` and `skills/index.{en,vi}.mdx`, refresh `kit-catalog-identities.json` (evidence anchor + bundle SHA256 + new identity entries), and bump the Kit overview `| Skills | N |` count in - `content/docs/beta/kits/{engineer,marketing}.{en,vi}.mdx`. Mirror the same - additions into `content/docs/stable/**` so the tree stays whole-copy-ready - for the next promotion. Skills marked `disable-model-invocation: true` - without `user-invocable: true` (for example `ak-common`) stay classified - `internal` in the catalog and get no public page. - - The `check:catalog` guard reads the frozen catalog as ground truth, so it - only fails when docs and catalog disagree. It does not detect upstream - drift on its own — refresh the catalog against the new bundle first, then - let the guard verify the docs match. + `content/docs/beta/kits/{engineer,marketing}.{en,vi}.mdx`. Keep EN/VI route + parity inside Beta, but do not copy new pages or prose into + `content/docs/stable/**`. Stable remains bound to its recorded tag until the + reviewed whole-copy promotion consumes the exact Beta snapshot. Skills marked + `disable-model-invocation: true` without `user-invocable: true` (for example + `ak-common`) stay classified `internal` in the catalog and get no public page. + + The current `check:catalog` guard reads one frozen catalog for both channels + and still requires identical Beta/Stable Kit routes, navigation, and overview + counts. Until that guard gains per-channel catalog state and `stable ⊆ beta` + checks, a legitimate Beta-only Kit addition will fail it. Stop and fix that + guard contract; never copy the new Kit page or count into Stable to obtain a + green check. The guard also does not detect upstream drift on its own — its + catalog evidence must first be refreshed against the new bundle. 3. **Desktop App section.** `content/docs/beta/desktop-app/**` describes product-state for a specific Desktop release: artifact filenames, sizes,