commit 9cac97a440b99453691b2dd674f8b161477d1f1c
parent e0ea8e5261a46143b66bd24194c1a73b12c340e4
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Tue, 29 Sep 2026 21:46:22 -0400
plans: slice HS after the review — the commit table (rewritten trailers, the review fixes, the merge of main), the review's findings to their commits, the post-merge gates (tsc; common 2,229; the unlisted-site spec 3/3)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat:
| M | plans/release-14.md | | | 77 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
1 file changed, 54 insertions(+), 23 deletions(-)
diff --git a/plans/release-14.md b/plans/release-14.md
@@ -1019,12 +1019,21 @@ Scratch files `hs-*` in the job's `tmp`. The rulings (2026-09-29, not re-opened)
| sha | what |
|---|---|
-| `5918ba27` | `common:` `site.json` `listed` (schema, docs, parser, writer; `SITE.md`); `isListedSite` and `channelsOnlyOnUnlistedSites`; the footer drops an unlisted sibling |
-| `10378f7f` | `common:` the homepage summary (v6), `channel-sites.json` and the whole-pool stats leave out an unlisted site and the channels only it exposes |
-| `1491a7ab` | `common:` `hub-sites.json` (and through it the hub's `corpus.json` and `llms.txt`) lists listed sites only |
-| `ca22f0e6` | `sites:` the checkbox, and `saveSiteAction` carries the key; `sites-crud` e2e |
-| `e12515c2` | `homepage:` the e2e fixture's seventh, unlisted site; `unlisted-site.spec.ts` |
-| _this_ | `plans:` this record; the three changelogs |
+| `122b8879` | `common:` `site.json` `listed` (schema, docs, parser, writer; `SITE.md`); `isListedSite` and `channelsOnlyOnUnlistedSites`; the footer drops an unlisted sibling |
+| `77aa1456` | `common:` the homepage summary (v6), `channel-sites.json` and the whole-pool stats leave out an unlisted site and the channels only it exposes |
+| `cbd12a8b` | `common:` `hub-sites.json` (and through it the hub's `corpus.json` and `llms.txt`) lists listed sites only |
+| `5836d6ec` | `sites:` the checkbox, and `saveSiteAction` carries the key; `sites-crud` e2e |
+| `64ae9b47` | `homepage:` the e2e fixture's seventh, unlisted site; `unlisted-site.spec.ts` |
+| `30b3f486` | `plans:` this record; the three changelogs |
+| `e3ee2eb1` | `homepage:` the fixture's second list unlists every site in it; the spec proves the site is in the input (review L1, L2) |
+| `65675373` | `common:` a shared channel stays the listed site's when the unlisted id sorts first (review L3) |
+| `20ff9ecf` | `plans:` FACTS' naming hazards (L4); this release's slices table, Order and Rollout carry HS (L6) |
+| `7ea35dfb` | merge of `main` `ccf90892` (release 15 IG); `buildStats.ts` and `editor/CHANGELOG.md` merged clean, the HS bullet under `[Unreleased]` |
+| _this_ | `plans:` the commit table, the review and the post-merge gates |
+
+The six commits up to `30b3f486` were rewritten after the review for the release's commit trailer
+(`git filter-branch --msg-filter`, trees unchanged); their first shas were `5918ba27`, `10378f7f`,
+`1491a7ab`, `ca22f0e6`, `e12515c2`, `4eeb80ee`.
- **The key:** `listed?: boolean` in `site.json`, after `siteUrl`, in the type, `SITE_FIELD_DOCS`,
`siteFieldsSchema` and `siteToDisk`. Absent or anything but `false` reads `true`; only `false` is
@@ -1081,18 +1090,25 @@ Scratch files `hs-*` in the job's `tmp`. The rulings (2026-09-29, not re-opened)
not the unlisted one.
- Editor `sites-crud`: a `listed: false` file opens unticked; a save that changes only the title
keeps `false`; ticking removes the key; unticking writes it again.
- - Homepage `unlisted-site.spec.ts`: the summary the dev server reads equals the one built
- without the unlisted site, and `/` and `/stats/` (served HTML and DOM) name all six listed
- sites and not the unlisted one.
+ - Homepage `unlisted-site.spec.ts`: the builder's input holds the unlisted site (`listed:
+ false`, its own records, the shared channel), and listed it would add a card and its records;
+ the summary the dev server reads equals the one built without it; `/` and `/stats/` (served
+ HTML and DOM) name all six listed sites and not the unlisted one.
+ - `homepageSummary.test.ts`, after the review: an unlisted id that sorts BEFORE the listed one
+ (`aaa-hidden` < `beta`) still leaves the shared channel with the listed site.
- **The homepage e2e fixture** (`homepage/e2e/fixture-summary.ts`), for the slices that build on
it:
- `FIXTURE_SITES`: the six listed sites, unchanged.
- - `FIXTURE_UNLISTED_SITE`: `fixture-unlisted`, "Fixture Unlisted", `listed: false`, two channels
- of its own (`fixture-unlisted-ch1/2`, six a day, like the rest) and `fixture-one-ch1` shared.
- - `buildFixtureSummary(fixtureSites = FIXTURE_SITES, unlistedSites = [FIXTURE_UNLISTED_SITE])`.
- The unlisted sites' records are generated last, after the megaspike, so every listed record is
- the same with them or without, and `buildFixtureSummary()` equals
- `buildFixtureSummary(FIXTURE_SITES, [])`.
+ - `FIXTURE_UNLISTED_SITE`: `fixture-unlisted`, "Fixture Unlisted", two channels of its own
+ (`fixture-unlisted-ch1/2`, six a day, like the rest); it also exposes `fixture-one-ch1`.
+ - `buildFixtureInputs(fixtureSites = FIXTURE_SITES, unlistedSites = [FIXTURE_UNLISTED_SITE])`
+ returns the builder's inputs (`stats`, `channelSites`, `sites`). The first list is listed;
+ every site in the second is written with `listed: false`, whatever it carries (`FixtureSite`
+ has no `listed` field), and shares the first listed site's first channel.
+ - `buildFixtureSummary(…)` is the real builder over those inputs. The unlisted sites' records are
+ generated last, after the megaspike, so every listed record is the same with them or without,
+ and `buildFixtureSummary()` equals `buildFixtureSummary(FIXTURE_SITES, [])`. Passed in the
+ FIRST list, the same site is listed: 7 sites and 39,599 transcripts instead of 6 and 37,199.
#### Proof: a hidden fixture site through the real builds
@@ -1137,7 +1153,7 @@ Counts (files holding the string / occurrences, `grep -rF`):
`https://fixture-listed.example`. The listed site's footer links nothing: its only sibling is
unlisted.
-#### Gates (at `e12515c2`; logs `$T/hs-*.log`)
+#### Gates (at `64ae9b47`, the tree of the first `e12515c2`; logs `$T/hs-*.log`)
- **tsc** was clean before every commit (69 s, 33 s, 44 s — the last over the tip's code).
- **Unit:**
@@ -1162,22 +1178,37 @@ Counts (files holding the string / occurrences, `grep -rF`):
- **Builds:** the five above, in the proof. The editor's and umtool's `next build` were not run (no
route or bundled path changed; tsc covers the form and the action).
- **Numbers tool:** none.
+- **After the review and the merge of `main` (at `7ea35dfb`; `$T/hs-gates3.log`):** tsc clean
+ (183 s, the machine under load); common 2,229/2,229 (release 15 IG's 2,220, this slice's 8 and
+ the review's 1); homepage unit 12/12; homepage e2e `unlisted-site.spec.ts` 3 passed, 0 failed
+ (19 s). The fixture's second list unlisting a site that carries no key, and the listed variant's
+ 7 sites / 39,599 transcripts, were checked by a script (`$T/hs-fixture-check2.ts`).
+
+#### Review (verdict SHIP; `$T/hs-review.md`)
+
+| Finding | Fix |
+|---|---|
+| L1: the fixture's second list relied on each site's own `listed: false` | `e3ee2eb1`: `buildFixtureInputs` writes `listed: false` on every site in it; `FixtureSite` has no `listed` |
+| L2: the spec's first case would pass if the builder ignored the unlisted site | `e3ee2eb1`: it asserts the site is in the input (unlisted, its records, the shared channel) and that, listed, it adds a card and exactly its own records |
+| L3: every unlisted id sorted after the listed one | `65675373`: `aaa-hidden` sorts before `beta`; the summary is still the one without it |
+| L4: `unlisted` / `listed` already mean other things | `20ff9ecf`: a FACTS "Naming hazards" table of the three |
+| L5: the listed site's out not searched for the own channel's name; the export site suite and `e2e:2origin` not run | left: both changes are no-ops for a site without the key, and the unit test and the real build's footer cover them |
+| L6: this record's slices table, Order and Rollout did not name HS; the hub check's N | `20ff9ecf`: HS row and Order; the Rollout names HS, counts public LISTED sites and checks the new box |
#### Found and left
- **The unlisted site's own `/site.json` and `/corpus.json` still carry its `hubUrl`** (ruling 4:
it deploys exactly as before). A visitor who adds its origin to the hub by hand gets it as any
added origin, and the hub can read that `hubUrl` as a family member's.
-- **`listed` has another meaning nearby:** `useHubSites`' `listed` flag
- (`export/app/components/hub/useHubSites.ts`) says the hub's list has been answered. A grep for
- the key finds both.
+- **`listed` / `unlisted` mean three things:** a video's visibility, `useHubSites`' `listed`
+ flag (the hub's list has loaded), and a site the family lists. FACTS' "Naming hazards" has the
+ table since the review.
- **The Rollout's hub check** ("`hub-summary.json covers N official instance(s)`") counts public
LISTED sites; the Rollout says so since the review.
- **Unlisting takes effect at the next builds.** The homepage, the hub and every other site are
static: until each is rebuilt and deployed, it still lists the site.
- **The editor's `/sites` list** shows no marker for an unlisted site; the form's checkbox is the
one place (ruling 3).
-- **The commit trailer** is this implementer's own model line, not `implementer-rules.md`'s.
#### Decisions the operator could overturn
@@ -1194,9 +1225,9 @@ Counts (files holding the string / occurrences, `grep -rF`):
## Rollout
Release 14 is slice HP (merged, `bfa1ff3c`), `r14/two-grounds-headers` and slice HS
-(`r14/hidden-sites`), each after the parent's merge. Every command below is typed **from the primary checkout's root**. There is no
-`archilyzer` on PATH, so it is `pnpm archilyzer …`. The command forms are the ones verified in
-`plans/stats-cache-key.md`'s rollout.
+(`r14/hidden-sites`), each after the parent's merge. Every command below is typed **from the
+primary checkout's root**. There is no `archilyzer` on PATH, so it is `pnpm archilyzer …`. The
+command forms are the ones verified in `plans/stats-cache-key.md`'s rollout.
**Preconditions.**
1. `main` carries `r14/two-grounds-headers`.