Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 1b558050f453634f3f1fdcd3abb8db2ee23c4766
parent 1b6d4e9da3121fbca6ddbdbf31ecd13a01eccc49
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Mon, 28 Sep 2026 01:56:32 -0400

plans: slice O4 as shipped — the homepage builds and deploys from /sites (three job kinds, the refusals, a preview box, two ops verbs), JobLane's Strict Mode bug found and fixed; the plan's "As shipped" note (ops preview is a body key, no jobKinds entries, homepageOutDir exported)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Mplans/homepage-deploy-from-ui.md | 27+++++++++++++++++++++++++++
Mplans/release-11.md | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 155 insertions(+), 0 deletions(-)

diff --git a/plans/homepage-deploy-from-ui.md b/plans/homepage-deploy-from-ui.md @@ -116,3 +116,30 @@ Numbers tool: none. The live :3001 editor must be restarted to show the section, which fits the next editor restart. After it: Build homepage with Deploy after build unticked, then Deploy homepage, and the job's log ends with the Pages URL. + +## As shipped (2026-09-28, release 11 slice O4) + +Built as planned; record: [`release-11.md`](release-11.md), "Slice O4, as shipped". What the +build corrected here: +- **The ops preview is a body key, not a flag.** `pnpm ops deploy-homepage [--preview <branch>]` + (decision 4) is `pnpm ops deploy-homepage --json '{"preview":"<branch>"}'`: the ops client has no + per-verb flags, and `deploy-hub` takes its preview the same way. +- **No job-kind registry entries.** The hub's three kinds have none in `common/jobs/jobKinds.ts`, + and neither does any publish kind (`build-export`, `deploy-export`, `build-deploy`, `build-all`, + `build-deploy-all`). A kind with no entry shows its raw name on `/jobs` and is not drainable, not + replayable and needs no media, which is right for all three. Mirrored: the kinds are declared + where the hub's are, in the action's `kind` and in `/sites`' `BUILD_KINDS` comment. +- **`homepageOutDir(paths)` is exported from `common/publish/build.ts`.** The editor needs + `homepage/out` for `builtHomepageProblem` and for "built <when>", and `homepageDir` was private. + `buildHomepage` and `deployHomepage` are unchanged, so the job's own refusal keeps its sentence + ("… — run archilyzer build homepage first"). The refusal before the job says "… — build the + homepage first". +- **`JobLane` needed a fix to be testable at all.** Under `next dev`, Strict Mode's + mount → cleanup → mount dropped every update of a lane's one launch, so it sat on "Starting…" + while its job ran. Production mounts once and never showed it; no spec had clicked a lane + button before. +- **How the e2e avoids a real `next build` and wrangler.** There is no fake wrangler, and the hub's + buttons have no spec. The Build homepage spec holds the `build` queue with `/api/test/stuck-job`, + so its job only queues, and cancels it from the lane before it starts. The deploy-homepage + refusals run with the `deploy` queue held the same way. The missing-build refusal is asked only + when the checkout has no `homepage/out/index.html`, and asked as a preview. diff --git a/plans/release-11.md b/plans/release-11.md @@ -36,6 +36,134 @@ merges `main` once O1–O5 have landed, then does its `E2E_` rename. Then one in ## Record +### Slice O4, as shipped — deploy the homepage from /sites (2026-09-28) + +The operator's ask (2026-09-26): **"Is there a way to redeploy archilyzer.pages.dev from the UI?"** +There was not: `/sites` built and deployed the hub, and the homepage was a CLI +(`archilyzer build|deploy homepage`) with no job, no `/jobs` row and no `pnpm ops` verb. Plan: +[`homepage-deploy-from-ui.md`](homepage-deploy-from-ui.md), decisions 1–5, now with an "As shipped" +note. Branch `r11/homepage-deploy-ui` off `main` `2162db92`, worktree +`/home/user/Projects/r11-homepage-deploy-ui`, one Opus implementer. Scratch files `o4-*` in the +job's `tmp/overnight`. + +**What shipped.** +- **A Homepage section on `/sites`, after Hub.** The Hub paragraph lost its homepage sentence, and + the new section says it instead: the `homepage` package, `homepage/out`, the project `archilyzer`, + and the same code as `archilyzer build|deploy homepage`. Its group, **Homepage build**, is + `HubBuildButtons`' shape: **Build homepage**, **Deploy after build** (unticked), **Deploy + homepage**, one `JobLane` at a time (**Build homepage** / **Build & deploy homepage** / + **Deploy homepage**). +- **A preview branch box** (textbox "preview branch", empty = production). It is judged by + `previewBranchProblem`, the function the action and the route refuse with. A bad name greys out + Deploy homepage, and Build homepage when Deploy after build is ticked, and shows the sentence + (`role="status"`, "preview problem"). +- **One line saying what a deploy ships:** "Deploy homepage ships `homepage/out`, built <when>, to + `archilyzer` (production): https://archilyzer.pages.dev." (`PROJECT_URL`). With no build it says + "`homepage/out` holds no build yet …". With a preview it gives the alias and says "the live site + is left alone". Under it: the homepage reads the index as it stands, so run Build index first. +- **Three job kinds,** via `runManagedFunction` in `editor/app/sites/lib/homepageDeployActions.ts`: + - `build-homepage` on queue `build`; + - `deploy-homepage` and `build-deploy-homepage` on queue `deploy`; + - the bodies are `buildHomepage` / `deployHomepage`, unchanged. The build-deploy deploys only + on exit 0. +- **Refusals before any job:** a bad preview name, and for a deploy-only, + `builtHomepageProblem(homepageOutDir(paths))` ("homepage/out holds no build — build the homepage + first"). `deployHomepage` re-checks both inside the job with its own sentences, untouched. +- **Ops:** + - `/api/ops/build-homepage` `{deploy?, preview?}`: a preview without deploy is a 400. + - `/api/ops/deploy-homepage` `{preview?}` answers `previewUrl` = + `previewAliasUrl(HOMEPAGE_PAGES_PROJECT, preview)`. + - `pnpm ops build-homepage` / `deploy-homepage`, in the verb list, the header examples and the + usage. +- **common:** `builtHomepageProblem` and `builtHomepageAt` (index.html's mtime) beside + `builtHubProblem` in `builtExport.ts`. `homepageOutDir(paths)` exported from `publish/build.ts`, + so the editor does not re-derive the path. +- **Found and fixed: `JobLane` under Strict Mode.** The launch effect gated its updates on a flag + local to it, set by its cleanup. `next dev`'s mount → cleanup → mount set that flag, and the + second run returned early on `startedRef`, so the job ran while the lane sat on "Starting…" + forever. Liveness is now a ref kept by its own effect. Production mounts once and is unchanged. + No spec had ever clicked a lane button (batch, specific sites, hub), which is how it went unseen. + +**Corrections to the plan** (also in its "As shipped" note): +- The ops preview is `--json '{"preview":"<b>"}'`, not a `--preview` flag. +- No `jobKinds.ts` entries: the hub's kinds have none, and neither does any publish kind. +- `homepageOutDir` had to be exported. + +**How nothing in e2e builds or deploys.** There is no fake wrangler, `homepage/out` is the +checkout's own directory (the primary's holds the live homepage's build), and the hub's buttons have +no spec to copy. So: +- **No spec clicks Deploy homepage.** None ticks Deploy after build and then clicks Build. +- **Build homepage is clicked only with the `build` queue held** by `/api/test/stuck-job`, which is + never released in the spec. The `build-homepage` job only queues, and the spec cancels it from its + lane. Its `start()` never runs: no log file, no child, nothing written under `homepage/`. +- **If that spec fails before its Cancel,** the next `resetData` cancels live jobs newest first + (`registry.list()` sorts by `queuedAt` descending). The queued build is removed before the + holder's slot is freed, so nothing is ever promoted. +- **The deploy-homepage refusals run with the `deploy` queue held the same way.** A deploy a refusal + failed to stop would only queue, and the spec's job-list check would fail. +- **The missing-build refusal is asked only when the checkout has no `homepage/out/index.html`,** as + `deploy-hub`'s is (`211d4666`), and it is asked as a preview. +- **Checked after every run:** the worktree has no `homepage/out`, and `homepage/public` holds only + its tracked `_headers`. Its gitignored data was not copied, because nothing here builds the + homepage. + +| sha | what | +|---|---| +| `b047b1be` | `common:` `builtHomepageProblem` + `builtHomepageAt` (`builtExport.ts`), `homepageOutDir` (`publish/build.ts`); +3 unit tests | +| `7ba41164` | `sites:` `homepageDeployActions.ts`, `HomepageBuildButtons.tsx`, the Homepage section; the Hub paragraph loses its homepage sentence | +| `54021099` | `ops:` `/api/ops/build-homepage`, `/api/ops/deploy-homepage`; `archilyzer-ops.mjs` verbs + usage (+1 test) | +| `ba4ff0bb` | `e2e:` `ops-api.spec` +1 (the refusals), `sites-homepage.spec` (3) | +| `d52d017d` | `sites:` `JobLane` survives Strict Mode | +| `d9218cb7` | `sites:` the group stamps `data-hydrated`; the specs wait for it | +| `40b6a0d7` | `changelog:` `[Unreleased]` above `[0.9.4]` in `editor/CHANGELOG.md` | +| _this_ | `plans:` this record; the plan's "As shipped" note | + +**Gates** (logs `o4-*.log`): +- **tsc** clean before every code commit (the last run on `d9218cb7`'s tree). +- **common 2,041/2,041** (2,038 + 3), editor unit **85/85**, `test:scripts` **175 + 1 skipped** + (174 + 1, +1), mcp **269/269**. +- **Editor build** ok (59 s); `/api/ops/build-homepage` and `/api/ops/deploy-homepage` are in the + route list. +- **e2e:** + - Run 1 on `ba4ff0bb` (`ops-api`, `sites-homepage`, `sites-crud`, `site-publish-preview`, + `deploy-page`, `build`, `settings`): **63 passed, 1 failed** (2.8 min). The failure was + `sites-homepage`'s Build homepage test: the lane stayed on "Starting…", which is the `JobLane` + bug above. + - `sites-homepage` ×3 with the old `JobLane`: **6 passed, 3 failed**. + - The same ×3 on `d9218cb7`: **9 passed** (27 s). + - The final list on `d9218cb7` (the same seven specs): **64 passed** (1.8 min). + - No spec here greps `deploy-hub|build-hub|HubBuild` except `ops-api`, which is in the list. +- **Numbers tool:** none. + +**They bite:** +- **Unit, against `2162db92`'s source:** + - `builtExport.test.ts` and `build.test.ts` fail to load (no `builtHomepageAt` / + `homepageOutDir` export). + - A mutation, `builtHomepageProblem` checking the directory instead of `index.html`, fails 1 of 8. + - `archilyzer-ops.test.mjs` against the old script: 1 of 33 fails, the new test. +- **e2e, against `2162db92`'s `page.tsx`, `builtExport.ts` and `build.ts`,** with the new action, + component and routes moved out: **4 of 4 new tests fail.** `ops-api` hits a 404 page ("Unexpected + token '<'"), and `sites-homepage` finds no Homepage group. The tree was restored by a trap + afterwards. +- **The `JobLane` fix:** the Build homepage test fails 3 of 3 with the old lane and passes 3 of 3 + with the fix. + +**Found and left** +- **A job cancelled while still queued keeps `"status":"queued"` in its `.meta.json`.** The + `onCancel` path never rewrites the sidecar. The registry says cancelled, and the boot pass settles + the sidecar. This is pre-existing and was not touched. +- **The "built <when>" line is read when `/sites` renders,** so a lane that finishes a build does + not refresh it. The Hub's lanes do not refresh the page either. +- **`/jobs` shows the three kinds by their raw names,** as it does the hub's. +- **Nothing has been built or deployed through the new jobs:** no build and no deploy tonight, by + rule. The proof is the rollout below. + +**Rollout (owed):** the section and the routes exist only on an editor built from this code, so it +waits on the :3001 restart. After it: +1. **Build homepage** with Deploy after build unticked, or `pnpm ops build-homepage --wait`. +2. **Deploy homepage**, or `pnpm ops deploy-homepage --wait`. The job's log ends with + `[deployed] https://<hash>.archilyzer.pages.dev`. + ## Rollout Nothing is rolled out tonight. The morning runbook lists what is owed: the :3001 editor restart,