Skip to content

docs(releases): finalize the 17.6.0 notes after publish - #21362

Merged
hotlong merged 1 commit into
mainfrom
claude/objectstack-release-steps-ynhz3j
Oct 2, 2026
Merged

hotlong merged 1 commit into
mainfrom
claude/objectstack-release-steps-ynhz3j

Conversation

@hotlong

@hotlong hotlong commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

What this is

The release-time half of the 17.6.0 release notes, following #20623 for 17.5.0.

The page content/docs/releases/v17/17-6.mdx landed before publish (#21290) with a RELEASE-TIME TODO. 17.6.0 was published to latest on 2026-10-02 from the version commit 617f25f8 (#20639): @objectstack/cli at 02:53Z, @objectstack/spec at 03:03Z. This PR makes the TODO's edits, deletes both TODO comments, and updates content/docs/releases/v17/index.mdx.

Docs-only, two files under the release-owned content/docs/releases/. Nothing is published, hence skip-changeset.

Clause-②: no

What changed

17-6.mdx

v17/index.mdx (following #20623)

  • The frontmatter description runs through 17.6.0.
  • The status blockquote says 17.6.0 is released and current, published 2026-10-02, taking over from 17.5.0. A plain install resolves 17.6.0, and the minors warning names 17.6.0.
  • A new "17.6.0 stays in that register" paragraph links the breaking changes, the known issues and the checklist.
  • The per-release list marks 17.6.0 as current. The checklist callout records that 17.5.0 → 17.6.0 was exercised in part (19 lines, on HotCRM), and the checklist links lead with 17.6.0.
  • The top-level content/docs/releases/index.mdx already reads "current series: 17.6.0", stamped at version time.

Verification

Run locally on the head commit. All of these pass:

  • check-issue-citations --base origin/main
  • check-doc-anchors (406 links)
  • check-role-word
  • check-release-page-status
  • check-release-section-coverage, plain and --strict
  • check:release-index-currency-sync
  • check-docs-single-h1
  • check-release-notes
  • check-doc-frontmatter

Both pages compile as MDX with @mdx-js/mdx 3 + remark-gfm.

🤖 Generated with Claude Code

https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL


Generated by Claude Code

17.6.0 was published on 2026-10-02 from the version commit 617f25f. This
makes the release-time edits the draft listed and removes its TODO comments:
the publish date, the consumed-changeset count (337, cross-checked against
496 per-package CHANGELOG entries), an "Also shipped in 17.6.0" section for
748b240 (#21270, unconsumed; tracked in #21361), the zh-CN Console defect
the verification confirmed, a "Known issues found after publish" section
(#21349, #21321, #21322, #21323, #21324, #21350, #21332, #21158), the
upgrade-checklist lines exercised by the HotCRM upgrade
(objectstack-ai/hotcrm#1982), and the v17 index.

Clause-②: no

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL
@hotlong hotlong added documentation Improvements or additions to documentation skip-changeset PR has no user-facing published change; bypasses the changeset gate labels Oct 2, 2026 — with Claude
@hotlong
hotlong marked this pull request as ready for review October 2, 2026 07:40
@hotlong
hotlong enabled auto-merge October 2, 2026 07:41
@github-actions github-actions Bot added the size/m label Oct 2, 2026
@hotlong
hotlong added this pull request to the merge queue Oct 2, 2026
Merged via the queue into main with commit 9360df4 Oct 2, 2026
41 of 42 checks passed
@hotlong
hotlong deleted the claude/objectstack-release-steps-ynhz3j branch October 2, 2026 08:09
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Oct 7, 2026
…on commit did not consume (objectstack-ai#21373)

Fixes objectstack-ai#21361
Clause-②: no

## What this does

Triage's third direction, and only that one. When the
`release-integrity` audit queues a publish, it now reports every pending
`.changeset/*.md` in the version commit's tree. These are the changesets
the version commit did not consume. The report names each one with the
commit that added it, so the gap shows up when the release is cut, not
one release later.

- **Logic:** a new `unconsumed` mode in
`scripts/release-pending-publish.mjs`. That script already finds the
version commit (`select`) and already refuses a shallow clone. It gets
seven new `--self-test` batteries on throwaway repositories.
- **Wiring:** one call in the existing `id: audit` step of
`.github/workflows/release.yml`. The call sits in the branch that queues
the publish (`pending == true`, on a push or the repair dispatch), right
after the "waiting for your approval" summary. There is no new job and
no new gate.
- **Pin of the wiring:** battery 12 of `scripts/release-verify-npm.mjs`
already runs the audit step's real text, taken from `release.yml`, in a
throwaway repository. Its fixture now carries one consumed changeset,
one that landed behind the Version Packages PR, and a `README.md`. The
version push must warn about exactly the one that landed behind, and
must still queue the publish.

The 17.6.0 instance (`748b240`, objectstack-ai#21270,
`.changeset/21110-scheduled-work-host-reason.md`) is carried by the
maintainer's objectstack-ai#21362. That PR has since merged as `9360df4138` and put
the dated correction into `content/docs/releases/v17/17-6.mdx`. This PR
edits no `content/docs/releases/**` and no `CHANGELOG.md`.

## How the version commit is found, and what "unconsumed" means

The version commit is the one `select` already names for `publish` to
check out. It is the newest first-parent commit at which
`packages/cli/package.json`'s version differs from its first parent's
(`findVersionCommit`). The step passes that sha to the new mode.

"Pending" means whatever `changeset version` itself would read:

- a top-level `.changeset/*.md` that `@changesets/read` 1.0.1 (the
version pnpm-lock pins) does not skip;
- so not a dotfile, and not `README.md` (any case), `AGENTS.md`,
`CLAUDE.md` or `GEMINI.md`.

Pre mode is read in both of the shapes it has been stored in:

- the current cli moves a consumed changeset into `.changeset/pre/`,
which is not top-level;
- the 2.x shape that the 17.0.0 release candidates carry kept it in
place and listed its id in `.changeset/pre.json`. An id listed there
counts as consumed.

The add commit comes from `@changesets/git`'s own lookup, `git log
--diff-filter=A --max-count=1`, with `--no-renames` added and the walk
started at the version commit. So the named commit is always the version
commit or one of its ancestors. A changeset that lands after the version
commit is in a different tree.

## A shallow clone is refused, never answered

`--diff-filter=A` cannot be answered in a shallow clone. Below the graft
boundary, every older changeset reads as added by the boundary commit,
which is a confident wrong commit. The mode refuses a shallow clone in
the same way `select` does. Measured in this container's own shallow
checkout:

```
$ node scripts/release-pending-publish.mjs unconsumed --version-commit HEAD --json
::error::release-pending-publish: refusing to name the commits that added changesets in a shallow clone: at the graft boundary every older changeset reads as added by the boundary commit. Check out with fetch-depth: 0.
exit 1
```

The job's checkout already uses `fetch-depth: 0`, and `select` would
refuse a shallow clone before this point anyway. If the report still
cannot be measured, the script prints its own error annotation with the
reason. The step then writes **NOT MEASURED** to the log and the job
summary, and leaves the publish queued. The report never comes back
empty without saying so.

## Level: a warning, never a refusal

The finding is a `::warning::` plus a job-summary section. That is the
level this job already uses for every finding that leaves a release
incomplete without stopping it:

- GitHub Releases or the D4 asset are incomplete;
- the image is missing;
- the push range is unreadable;
- npm could not be read for part of the fixed group.

This step uses `::error::` only together with `exit 1`, for refusals.
The report must not fail the step: `publish` `needs` this job, so a
failure here would hold the npm publish, the tag and the image. That is
why it reports and never refuses.

It runs only on the event that queues the publish, because that is the
run the approver opens. A later landing during the approval window, and
every audit of an already published version, print nothing. Otherwise
the same warning would appear on every push to main for a whole release
cycle. Battery 12 pins this as well.

## Real history (a full-history clone, `--is-shallow-repository` false;
the script at head `27979b22f4`)

| release | version commit | pending in its tree | unconsumed | from
commits |
|---|---|---|---|---|
| 17.6.0 | `617f25f8a` | 1 | **1** | 1: `748b24072` (objectstack-ai#21270) |
| 17.5.0 | `8c87d26a5` | 8 | **8** | 7: `f11b5f20a` `e73ee2ddc`×2
`c876a7426` `7a1faf1a5` `c9d234c40` `24d521e53` `2123fcca3` |
| 17.4.0 | `7e6337007` | 13 | **13** | 13 |
| 17.3.0 | `8a1bad8b8` | 4 | **4** | 3 |
| 17.2.0 | `e7d2cc67f` | 0 | 0 (the control) | |
| 17.1.0 | `47d1ae89e` | 0 | 0 | |
| 17.0.0 | `24c1b91e4` | 0 | 0 | |
| 17.0.0-rc.6 | `e7e0a6dd9` | 1704 | 0 (all 1704 recorded in `pre.json`)
| |
| 17.0.0-rc.4 | `bd191338e` | 1277 | 8 (1269 recorded) | 8 |
| 17.0.0-rc.2 | `3cfd9f0b1` | 862 | 2 (860 recorded) | 2 |

- Triage's pins hold exactly: 8 changesets from 7 commits for 17.5.0,
and 1 (`748b240`) for 17.6.0.
- The control the dispatch suggested, 17.4.0, does **not** come back
clean. It left 13 changesets unconsumed, and 17.3.0 left 4. `git show
--name-status` shows each set deleted by the NEXT version commit:
17.4.0's by `8c87d26a5`, 17.3.0's by `7e6337007`. So those entries were
published one release late, under 17.5.0 and 17.4.0. The clean controls
are 17.2.0, 17.1.0 and 17.0.0. See the acceptance notes.

## Tests

- `node scripts/release-pending-publish.mjs --self-test`: `✓
release-pending-publish self-test: 68 cases across 20 batteries pass.`,
up from 13 batteries. The seven new batteries and their floors:
  - a Version Packages PR landing behind main (4);
  - the control (2);
  - only what `changeset version` reads (2);
  - the 2.x `pre.json` (2);
- the add commit: newest add, rename, a landing after the version commit
(3);
  - shallow clone and unresolvable sha refused (2);
  - the report text (4).
  The battery-count floor goes from 13 to 20.
- `node scripts/release-verify-npm.mjs --self-test`: `OK
release-verify-npm self-test: 96 cases pass across 13 batteries`.
Battery 12's floor goes from 14 to 17, with the three new cases.
- **Ablation (reverse verification), run once and not kept.** Through
`scripts/ablation-replace.mjs`, the call in `release.yml` was replaced
with `if ! true; then`:
- the anchor went from 1 hit to 0, and the blob from `c975b6f27bbf` to
`dd45fa2c88c1`;
- `release-verify-npm --self-test` then exited 1, with the two positive
battery-12 pins red ("the version push warns of the changeset its
version commit did not consume…" and "…the job summary carries the
section");
- the restore was proven by the blob equalling HEAD (`c975b6f27bbf`) and
`git diff HEAD` being empty.
- Gates: at head `27979b22f4`, `node scripts/pm/dispatch-gates.mjs
--repo objectstack-ai/objectstack --commands` (no paths, change set from
the merge base) derives 51 commands. All 51 were run and exited 0, and
`--ran` reconciles: `51 derived, 51 run, 0 NOT-MEASURED, 0 UNRUN` (a
derived zero, since every row recorded its exit code). That set includes
`check:self-test-wired` (`every one of the 232 script(s) CI runs that
ship a --self-test has that self-test run by CI`),
`check-self-test-workflow-commands` (no self-test prints a line the
runner would parse as a workflow command), `check:nul-bytes` and
`check:bash32-floor`. Lint: CI owns the repo-wide run. The narrowed run
`eslint --no-inline-config --format json` on the two changed scripts
reported 2 files, 0 errors and 0 warnings. The population comes from
`eslint.config.mjs`: its `**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}` object
covers `scripts/*.mjs`. That config never enables type-aware linting (no
`parserOptions.project`), so this diff cannot move a verdict on any
untouched file. No TypeScript package is touched, so no `typecheck` is
owed.

## Acceptance notes

- **17.3.0 and 17.4.0 have the same gap, and nothing says so yet.**
17.4.0 shipped 13 changesets' code with no 17.4.0 CHANGELOG entry, and
17.3.0 shipped 4. Their entries appear in 17.5.0's and 17.4.0's
CHANGELOGs respectively. The 17.3.0 and 17.4.0 notes carry no dated
correction of the kind 17.5.0 and 17.6.0 now have. That is release-owned
text, out of scope for a code PR, and left to the maintainer.
- NOT MEASURED: the NOT MEASURED fallback branch in the step (the script
exits non-zero inside the real step text) has no running pin. Battery
12's fixture has no way to make the mode refuse after `select`
succeeded. The mode's own refusals are pinned in its self-test.
- NOT MEASURED: no ablation moved the call out of the pending branch.
The negative pin ("a landing that does not queue the publish reports no
changesets") is therefore unablated.
- The mode would also report a changeset that `changeset version` skips
on purpose, meaning one whose every package is in `ignore` or is private
with `privatePackages.version: false`. `.changeset/config.json`
configures neither today. This is noted in the script's docblock.
- No changeset (`skip-changeset`): the diff touches `.github/workflows/`
and two repository-root `scripts/*.mjs`, and neither is in any package's
`files[]`.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01UtnxvdiN376GF3sgXwAw4d)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Oct 7, 2026
…objectstack-ai#21994)

Fixes objectstack-ai#21989
Clause-②: no

## What this is

This PR adds the curated release page for 17.7.0,
`content/docs/releases/v17/17-7.mdx` (1,402 lines). It was written after
the publish: npm `latest` moved on 2026-10-06, and
`@objectstack/spec@17.7.0` went out at 12:22:14Z. It also wires the page
in:

- `content/docs/releases/v17/meta.json`: `17-7` comes ahead of `17-6`.
- `content/docs/releases/v17/index.mdx`: the status blockquote, the
minors warning, the per-release list and the checklist links now name
17.7.0 as current. This is the same shape objectstack-ai#21362 used for 17.6.0.
- `scripts/docs-audit/handwritten-docs.json`: the page joins the
docs-accuracy audit scope.
- `content/docs/releases/v17/17-6.mdx`: one dated correction
(2026-10-06) on the anonymous-endpoints known issue. objectstack-ai#21158 was closed
as not planned on 2026-10-04.

The page follows the 17.6 page's structure:

1. Highlights.
2. What's new: the counts, and the runtime changes that happen silently.
3. Breaking changes and migration, triaged by door and subject. It
includes a coverage table that names the section carrying the migration
for every ADR-0087 entry added since 17.6.0 (8 conversions, 41 D3
entries).
4. New capabilities.
5. Notable fixes. Security fixes are described only as classes and
doors.
6. New in Console: each objectui declared-breaking change, with this
repo's answer.
7. The code that shipped but is not listed.
8. The upgrade checklist. Every line is marked *Not exercised.*

## Sources and counts

- The version commit `4e4e881427` (objectstack-ai#21352) consumed 323 changesets. 322
are new. One, `748b240` (objectstack-ai#21270), shipped in 17.6.0 and is listed again;
the page explains this in its own section.
- 69 CHANGELOGs carry a 17.7.0 section, and 48 of them have entries.
Their 444 entries (194 minor, 250 patch) de-duplicate to the 323
changesets.
- Two commits landed on `main` after the Version Packages PR's last
refresh and before it merged:
  - `8a399b2b15` (objectstack-ai#21977, for objectstack-ai#21923)
  - `04e776b39a` (objectstack-ai#21976, for objectstack-ai#21968)

Both are ancestors of the version commit (exit 0 for each), so the
17.7.0 packages carry their code. But the version commit did not consume
their changesets, so no 17.7.0 CHANGELOG line names them. The
release-integrity audit named both in a warning.
- objectui: the pin moved five times and ends at `0abd4f9f8769`:
  - `89cad75d5570` (objectstack-ai#21380)
  - `ab1879721595` (objectstack-ai#21625)
  - `2e818d0b51ec` (objectstack-ai#21710)
  - `9dfaca654311` (objectstack-ai#21800)
  - `0abd4f9f8769` (objectstack-ai#21827)

Across 173 commits, 254 changesets were added and 229 of them release
something. 65 are declared breaking, plus one commit marked `!`. The
Console table answers each.
- `PROTOCOL_VERSION` is still 17.0.0.

## Premise corrections

- The dispatch named two pin moves ending at `9dfaca654311`. The tree
has five, ending at `0abd4f9f8769` (`8832655`, objectstack-ai#21827). The page covers
all five.
- One new D3 id contains a word that `check:role-word` refuses on docs
pages, and release pages are not in its baseline. The coverage table
therefore names that entry by its subject and points at `os migrate meta
--from 17`.

## Fact-check

A second pass checked every cited SHA, PR number, key name and
behavioural claim against the commits, changesets and registry entries.
It corrected **31 claims** (commit `e4a6280b46`).

Two more corrections came earlier, while drafting:
- objectstack-ai#21361 is closed; it is not tracking the issue.
- There are seventeen `ui-object-*` members, not eighteen.

Mechanical checks on the final page:

- All 276 cited SHAs resolve, in objectstack or in an objectui clone
carrying the final pin's history.
- Each of the 216 distinct sha–PR pairs matches its commit subject.
- Every printable new D3 id (40) and all 8 conversions appear on the
page.
- The MDX for 17-7, 17-6 and index compiles with @mdx-js/mdx 3.1.1 and
remark-gfm 4.0.1.

After the fact-check, `main` gained `1abfc58` (objectstack-ai#21985), which lands the
read half of objectstack-ai#21922. It is not an ancestor of the version commit: the
test returned exit 1, and the control commit `753e7a1` returned exit 0.
So in 17.7.0, the metadata door's reads still serve a stored row under a
code-defined datasource name. Commit `8347e0d172` says so in the
datasource migration bullet.

## Independent fact-check and fix round

An independent, read-only fact-check of head `8347e0d172` returned
**FAIL** with 13 findings (record: objectstack-ai#21989 comment 6018402030): 2 wrong
facts (a flow's `get_record` node still reads the stored-metadata
tables, in projected form), 1 security line that named the filter shapes
and depth threshold evading 17.6.0's refusal, 1 breaking change missing
from the Breaking section (`0fc8087`, objectstack-ai#21626), 1 link whose label did
not match its target, 4 overstatements, 1 missing security fix
(`49524f6`, objectstack-ai#21420), 1 missing rollback caveat on `os secret rewrap
--apply`, and 2 minor wording issues.

All 13 were re-verified against their sources and applied in
`a53c972fa7`; none was refuted. A scan for any other line naming a
bypass shape of a fixed issue reduced two more lines to their class
(`0728cbf`, `fb69825`).

## Measured on `a53c972fa7`

- Derived gates: `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands` derives 57 commands; all 57
exited 0 (`--ran`: "57 run, 0 NOT-MEASURED (a DERIVED zero)"). The
verdicts include:
  - check-doc-anchors: 458 links resolve.
- check-issue-citations: 305 resolve as a PR, 9 resolve, 15 are
cross-repo; every citation this change adds resolves.
- `check:role-word`, `check:release-notes` and
`check:release-page-status`: OK.
- check-release-section-coverage: OK, both plain and with `--strict` (10
minors).
  - The docs-audit scope check and `check:nul-bytes`: OK.
- Docs production build: `TURBO_FORCE=true pnpm turbo run build
--filter=@objectstack/docs`, run under the verify lock, reports `Tasks:
2 successful, 2 total` and `Cached: 0 cached`. The built
`releases/v17/17-7.html` carries the corrected text and none of the
removed text.
- Mechanical checks: 231 distinct sha–PR pairs, 0 unresolved, 0 subject
mismatches; the MDX of 17-7, 17-6 and index compiles.
- Not measured locally: the repo-wide lint and the CI-only families. CI
owns them.

## Not in this PR

- No changeset. The PR touches only docs and a docs-audit list, nothing
a package ships (`skip-changeset`).
- Nobody has walked the 17.6.0 → 17.7.0 upgrade. The checklist says so
on each line.

---
_Generated by [Claude
Code](https://claude.ai/code/session_016tKoy8NJa35Yih1FdzrVmn)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants