advance live-docs on a release, and track it from a packaging workspace - #3877
Merged
Conversation
MattDHill
force-pushed
the
feat/pin-workspace-to-sdk-release
branch
from
August 31, 2026 23:11
279ef3c to
76f8845
Compare
A packaging workspace cloned `master`, which carries the SDK that has not shipped: today its `projects/start-sdk` is 2.0.10 while every published package pins `@start9labs/start-sdk` 2.0.9. The guide, the package template and the SDK source a packager reads therefore ran ahead of what `npm install` resolves, and the local copy of the guide disagreed with docs.start9.com. `live-docs` is the branch that should answer this — it is what is published — but nothing has ever advanced its code. It was branched off master's tip on 2026-08-10 (#3652) and only `projects/<p>/docs` has moved since, so its `projects/start-sdk/lib` is still that day's in-progress 2.0.10, and `shared-libs/`, `.github/` and the repo root are all three weeks stale and drifting. docs-sync-on-tag now takes the tagged tree whole and puts every *other* `projects/*` back on the release it is on. A tag advances its own project, the shared libraries beneath it, and the repo root; it speaks for nothing another product owns. `projects/start-docs` rides along only with a product that ships a book, so a bookless release still refreshes the tree without triggering a site deploy. The stale-tag guard now covers the whole tree rather than the site alone: a backfilled tag still publishes its book and nothing else. `init-workspace` then clones `live-docs`, so `git pull --ff-only` stays the session-start sync and a workspace gets published-guide corrections the moment they go live, rather than at the next release. This does not repair the tree live-docs inherited on 2026-08-10; each project converges at its own next tag. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
live-docs now carries published code as well as published books, and nothing gated a pull request into it. A PR touching code would put a tree there that no release produced, and docs-backport pushes whatever merges into live-docs onto master unattended — so it would land on master unreviewed as a code change. The predicate is a rule rather than a mirror of docs-deploy's paths, so a new product's book is covered the moment it exists. The package template is the one thing under docs/ that it rejects: `s9pk init-package` scaffolds from it, and `manage-release.sh pre-check start-sdk` verifies its SDK pin against the release being cut, which an edit landing on live-docs would never face. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
start-cli installs outside the workspace, so nothing tied it to the guide the workspace carries. On Debian the installer adds an apt repo and `apt upgrade` carries it forward; on macOS and every other Linux it drops a binary in ~/.local/bin with no update path, and the guide never said to re-run the installer. Those packagers drift indefinitely against a guide that keeps advancing. The checkout tracks published releases and `projects/start-cli` only moves on a start-cli tag, so its manifest names exactly the version a packager should be running. Comparing it to the version baked in at build time is a file read with no network, printed once per process, and silent on anything unreadable. It rides on the workspace lookups s9pk work already does — signing (pack, publish, edit) and init-package — so it fires where a stale binary would bite and nowhere else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
MattDHill
force-pushed
the
feat/pin-workspace-to-sdk-release
branch
from
September 3, 2026 02:08
4449e23 to
53d5fe5
Compare
The rollback guard compared every tag against the newest sync of any product, but deb releases tag the commit alpha built, which is routinely behind a tag cut before it. Such a release was judged stale and never advanced its own tree; a bookless one crashed on the book-only path. The watermark was also read only from commits touching projects/start-docs, which a bookless sync no longer touches, so an older tag arriving after one rolled shared-libs and the root back. Two watermarks now. A product's own tree is behind only if an earlier release of the same product was synced from a descendant of the tagged commit. The shared trees are behind if any release was, and then stay where the newer release put them. Every earlier sync is consulted, not the newest, because syncs land out of ancestry order. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
check-pr-retarget-workflows.py audits every workflow with a pull_request trigger, and the guard was not registered. It is a direct listener like conflict-markers rather than a retarget-called target: its verdict depends on the base, and the branch filter is evaluated against the new base, so taking `edited` is what checks a PR moved onto live-docs before its next push. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
dr-bonez
approved these changes
Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A packaging workspace cloned
master.mastercarries the SDK that hasn't shipped: itsprojects/start-sdkis2.0.10while every published package pins@start9labs/start-sdk2.0.9. So the guide a packager reads, the templateinit-packagescaffolds from, and the SDK source they grep all describe an SDKnpm installcannot resolve — and the local guide disagrees with docs.start9.com.live-docsis the branch that should answer this. It doesn't yet, because nothing has ever advanced its code: it was branched off master's tip in #3652 on 2026-08-10 and onlyprojects/<project>/docshas moved since. Itsprojects/start-sdk/libis still that day's in-progress 2.0.10 (5 files / 170 lines of post-v2.0.9 work), andshared-libs/,.github/and the repo root have not moved a single file in three weeks.Change
docs-sync-on-tag.ymlnow advanceslive-docsto the release, not just its book. It takes the tagged tree whole, then restores every otherprojects/*to the release it is on. A tag therefore speaks for its own project, the shared libraries beneath it, and the repo root — and for nothing another product owns.projects/start-docs(shared site tree,versions.confincluded) rides along only with a product that ships a book. A bookless release — start-cli, start-registry — now refreshes its own project and the shared tree instead of being skipped whole, anddocs-deploy.yml's paths filter is what keeps it from firing a needless deploy.shared-libs/, the root,projects/start-docs/) against every product's. So a deb release, which tags the commit alpha built and is routinely behind a tag cut before it, still advances its own project while the shared trees stay where the newer release put them. A tag behind its own product's last release publishes its book alone, or nothing if it has none. Every earlier sync is consulted, not the newest, because syncs land out of ancestry order.[skip-backport]is unchanged and load-bearing — none of the newly-synced paths can bounce onto master.s9pk init-workspacecloneslive-docs.git pull --ff-onlystays the session-start sync, so there's no new command; a workspace now picks up corrections to published pages the moment they go live, and a release brings that product's whole tree with it.live-docs-guard.ymlfails a PR intolive-docsthat changes anything but a published book. The branch now carries code, and only the tag sync may write it — a PR that carried code would put a tree there that no release produced, anddocs-backport.ymlwould push it onto master unattended, unreviewed as a code change. Nothing gated PRs into that branch before. It takeseditedalongside itslive-docsbranch filter, so a PR retargeted ontolive-docsis checked at once rather than at its next push, and it is registered withcheck-pr-retarget-workflows.pyas a direct listener, likeconflict-markers.The predicate is a rule (
projects/<product>/docs/,projects/start-docs/) rather than a mirror ofdocs-deploy.yml's paths, so a new product's book is covered the moment it exists. It rejects one path underdocs/: the package template, whichinit-packagereads out of the workspace's checkout at scaffold time rather than from the binary — so a merge there would change what every new package is built from at once, without facingmanage-release.sh pre-check start-sdk's gate on its SDK pin.An
s9pkcommand says whenstart-cliitself is behind.start-cliinstalls outside the workspace, and the two halves drift differently: on Debian the installer adds an apt repo andapt upgradecarries it forward, while on macOS and every other Linux it drops a binary in~/.local/binwith no update path the guide ever mentioned. Sinceprojects/start-clionlive-docsonly moves on a start-cli tag, its manifest names exactly the version a packager should be on — so the check is a file read against the version baked in at build time. Printed once per process, silent on anything unreadable, and hung off the workspace lookups s9pk work already does (signing,init-package) so it fires where a stale binary would bite.Verification
Sync logic, against a synthetic repo: two products,
awith a book andbwithout,live-docsbranched at C0, master C0 → C1 → C2 → C2b → C3, tags applied in the order below.shared-libs/+ rootprojects/start-docsa/v1at C2b/v1at C1 (behinda/v1, no earlierb)b/v0at C0 (behindb/v1)a/v0at C0 (behinda/v1)b/v2at C3 (ahead of everything)a/v2at C2b (ahead ofa/v1, behindb/v2)a/v9off mastera/v2againThe same harness against the previous revision of this branch:
b/v1andb/v0failed the job on the book-only path, anda/v2rolledshared-libs/and the root back to C2b.Guard predicate, eight cases: book pages,
versions.conf,book.tomland a straydocs/*.mdpass;shared-libs/,projects/start-sdk/lib/, rootAGENTS.md, andpackage-template/fail, including when mixed into an otherwise-clean docs PR.Not covered
The tree
live-docsinherited on 2026-08-10 is not repaired here — each project converges at its own next tag. A one-off reset oflive-docsto per-project release state is a separate change against a protected branch.Docs
environment-setup.md,agent-context.md,workflow.md,cli-reference.md, the root andstart-docs/start-sdkAGENTS.mdrelease and branch descriptions, and the unreleasedstart-cli2.0.0 changelog.🤖 Generated with Claude Code