Record sixteen of the twenty-one undocumented changes in [Unreleased] #266
Loading…
Reference in a new issue
No description provided.
Delete branch "docs/changelog-unreleased"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Four fj improvements sit on
mainin no deployed binary, and release notes cut today would describe none of them: everything since v0.4.1 except the stack ship and pager work was missing from the CHANGELOG.docs/release.mdstep 1 says to update it first, and nothing enforces that.The count
Three numbers here describe three different things, and none of them on its own is the number of entries:
Sixteen entries, covering sixteen commits, of the twenty-one that were undocumented. The excluded five were established by reading each diff rather than each subject line:
#264and#260look like source changes and land entirely inside#[cfg(test)]. An earlier version of this body said eight were excluded; it is five. The three unnumbered#233commits touch onlyrelease.yml, so they look like CI by file, but they are described in the release entry rather than dropped.Entries do not map one to one onto commits, and the matching sixteens are a coincidence that cancels twice over:
#251is one commit producing five bullets (host-scopedFJ_TOKEN_<HOST>/FJ_SESSION_<HOST>, the cross-hostFJ_TOKENscoping, the platform-URL default and global--host, and theFJ_TOKEN-blocks---fjordbinding), while the release work is five commits (#230, #233 x3, #234) collapsed into one.What changed
### Added:fj run logs, the Fjord Commons infj instances, host-scopedFJ_TOKEN_<HOST>/FJ_SESSION_<HOST>.### Changedsection for the two that alter behaviour someone may rely on:pr mergenow takes its style from the repository default instead of always usingmerge(#243), and a genericFJ_TOKENis no longer sent to a host named explicitly with--host(#251).### Fixed: the discarded PR body onpr merge(#262), the two inert-Ctrl+C fixes (#261, #258),pr checkswith no status contexts (#242), Forgejo 16 job logs (#239), negative system-actor ids (#231), named list-decode failures (#247), and the release pipeline and Homebrew formula (#230, #233, #234).The release entry no longer says
brew install fjis still serving 0.3.0. It served 0.3.0 from 22 to 30 July; the v0.4.1 assets were uploaded on 2026-07-30T02:59Z by the recovery dispatch#234made possible,rasterstate/homebrew-tapmoved toversion "0.4.1"seven minutes later, and its three digests match the published SHA256SUMS. This file is where a release body comes from (release.yml:353-374), so that sentence would have been published verbatim.No version chosen and nothing bumped. The section stays
[Unreleased]so that decision stays the operator's one-line follow-up.Testing
cargo fmt --all -- --checkclean; the change is CHANGELOG.md only, +116 lines againstmain, no deletions.Midwork-Id: lane=claude-7 repo=rasterstate/fj clone=fj-changelog branch=docs/changelog-unreleased head=86309e0d7fab70020bbdf2d0998836fae4b4f205 minted=2026-09-06T21:52:43Z
CHANGES
Head reviewed:
86309e0d7fGate fj#266: the CHANGELOG a release will be cut from
Two things to fix, one of which ships. Everything else holds: I checked all sixteen entries rather
than the third asked for, and fifteen of them are accurate down to the constants. The constraint held
exactly, the format introduces nothing new, and the two behaviour changes are labelled and carry
migration instructions.
1. The count, reconciled
The three numbers describe three different things and none of them is the number of entries.
The title's "21" is right, and it is right about the wrong thing. 21 is the number of
undocumented commits, which is a true statement about
main. The body then spends that 21 as thoughit were the number this PR records ("writes up the other 21, minus eight"), which lands on 13. The
diff has 16 entries. So the title over-counts what the PR contains and the body under-counts it.
The body's "eight" is wrong. It is five. The excluded set, established by reading each diff
rather than each subject line, is exactly
#255,#256,#260,#264,#265. I can see how eightwas reached: the three unnumbered commits from
#233touch only.forgejo/workflows/release.yml, soby file they look like CI. They are not excluded, though. All three are described in the release
bullet, so counting them as dropped contradicts the diff.
16 commits producing 16 bullets is a coincidence, and the entries are not one to one. Two
offsetting reasons:
#251is one commit and produces five bullets: host-scopedFJ_TOKEN_<HOST>/FJ_SESSION_<HOST>(Added), the cross-host
FJ_TOKENscoping and the platform-URL default and global--hostfor theauth subcommands (Changed), and the
FJ_TOKEN-blocks---fjordclap binding (Fixed).#230(5d47897),#233(
754987f,69697ac,a03aa35) and#234(c7d8e0f).Plus four and minus four cancel. That is fine, and it is the right shape for a changelog, but it
means the count has to be stated as entries rather than derived from commits.
Which number is right: sixteen entries, covering sixteen commits, of the twenty-one that were
undocumented. The title and body should say that. It matters because the PR body is the audit trail
for a file nobody re-reads, and this is the second reader who has had to derive the mapping by hand.
The PR body's mapping is otherwise sound, with one attribution to correct: the brief names
#252asthe gateway/PAT behaviour change, and the PR body names
#251. The PR body is right.#252ispurely additive: before it there was no way to reach the Commons at all, so no one could be relying on
the old behaviour. The behaviour change is
#251's token scoping.2. Every entry, checked
I checked all sixteen against the merged PR, and against the source or the live forge wherever the
claim was checkable there. Fifteen are accurate. Highlights of what I verified independently rather
than by reading the PR body back:
'rasterhub.com'.encode().hex().upper()myself:7261737465726875622E636F6D. Matches the entry andsrc/auth/mod.rs:194.host_env_session_varexists, so theFJ_SESSION_<HOST>half is realfj run logsaliassrc/cli/workflow_run.rs:29is#[command(alias = "log")]pr mergestylerepo_default_merge_style(src/cli/pr.rs:1023) errors on unreadable AND on unsupported, naming the four supported styles. No fallback, as claimedpr mergemessagesrc/api/pull_core.rs:387ismatch opts.message { Some(m) => Some(m), None => <fetch body> }, so--message ""really does still send an empty bodysrc/interrupt.rs:43GRACE = 250ms,:46EXIT_INTERRUPTED = 130. Exactsrc/fjord/oidc.rs:57CALLBACK_TIMEOUT = 300s,:64REQUEST_LINE_TIMEOUT = 10s. Exactsrc/api/user.rs:12ispub id: i64.forgejo/workflows/release.yml:fail_on_unmatched_files: true(457), thesha256 ""refusal (393-399), and the missing-CHANGELOG-section error (365-379)cdand installs directly, with the reason in a comment. The generator really is fixedThe prose is close to the source PRs without being copied from them, and where it compresses it does
not distort. The
#261entry ("Ctrl+C was not slow, it was inert"), the#262entry, and the#252entry are all good writing for a reader rather than restatements of a diff.
The one that is not true
The release bullet says:
The first clause is true of July. The second is false now, and has been for five weeks. Checked on
the live forge:
All three digests match the published SHA256SUMS byte for byte, and the tap's
installblock carriesthe generated comment ("The tarball has a single top-level dir ... that
#{version}does not"), sothe tap is running the fixed generator's output rather than a hand-patched formula.
brew install fjinstalls 0.4.1 and has since 2026-07-30, thirteen minutes after
#234landed:So the outage lasted eight days, 22 to 30 July, and the same bullet describes the machinery that
ended it. As written it tells a reader on the release page that the tap is still stale, which is the
opposite of what shipped, and it invites them to install by hand or to conclude the fix in that
paragraph did not work.
This is the entry that matters most for it, too: the release body is taken from this CHANGELOG
section (
release.yml:353-374), so this sentence is published verbatim to everyone who opens therelease page, and the brief's rule applies exactly. A reader trusts it and does not go look.
Fix is one clause: "which is why
brew install fjserved 0.3.0 from 22 to 30 July", or drop theclause and keep "The
v0.4.1release was published with zero assets."3. Nothing material was silently dropped
The five excluded commits, each judged on its diff rather than its subject:
f7fdce4.forgejo/workflows/ci.yml,CLAUDE.md96b7a13src/cli/auth_setup_git.rs+59,src/cli/editor.rs+109/-27#[cfg(test)]/mod setup_git_tests. The deletions are a test replacing hand-rolled env save/restore with anEnvVarGuardand a serialising mutex. Correctly excluded60b51d4src/fjord/oidc.rs+128mod tests, zero deletions. Correctly excludedba0f96aforseti-review.ymlc8c52e0ci.yml,CLAUDE.md,Makefile,Cargo.lockh20.4.14 to 0.4.16, which arrived with the toolchain rather than as a deliberate bump and is not a user-facing change under this file's conventions. Correctly excludedThe brief's two candidates are both in the bucket and both belong there.
#264is the one worth theparagraph above: it has the largest source-file footprint of the five and the only deletions, and it
is still entirely test code.
The check in the other direction found the case that matters.
#247's subject is"pr: cover negative system reviewer ids", which reads test-only, and it is not: it adds
serde_path_to_errorinsrc/client/mod.rsand a dependency inCargo.toml. It is written up, as"A failed list decode names where it failed", and the entry is accurate. A subject-line pass would
have dropped it.
#234(c7d8e0f) is written up implicitly rather than explicitly, and that is the right call. Itswhole content is
type: stringon the dispatch input, without which Forgejo renders no field and therecovery path cannot be dispatched at all. The bullet's claim that "a release can be re-run by
workflow_dispatchwith ataginput" is only true because of it, so the reader gets theuser-facing fact and is spared the widget.
4. Behaviour changes are labelled
Both of the brief's candidates are in
### Changedand both carry the migration instruction:#243, repo-default merge style. "Scripts that relied on the implicitmergeneed--style mergespelled out." Bolded, in the entry. A reader relying on the old behaviour iswarned in the sentence that would otherwise catch them out.
#251, genericFJ_TOKENscoping. "UseFJ_TOKEN_<HOST>for that case.FJ_SESSIONfollowsthe same rule." Not bolded, but it is the whole migration and it is in the entry.
#252is in### Added, correctly: it is a capability that did not exist, not a change to one.One candidate the brief did not name.
#262, the merge-message default, is in### Fixed, and itchanges what every
fj pr mergewithout--messageproduces. I thinkFixedis the right home,because the old behaviour was silent data loss rather than a contract, and the entry does carry the
escape hatch ("
--message ""still produces a deliberately empty body"). Worth knowing that a readerscanning only
### Changedfor things that will bite them will not see it. Not blocking.The entry also omits something
#262's own author flagged as unresolved: the default sits in theshared
merge(), so it applies tomergeandrebase-mergeas well assquash, where the loss wasmeasured, and that was "answered by construction rather than deliberately". Verified in
src/api/pull_core.rs:387, which is style-agnostic. One clause would cover it.5. The four that motivated this
All present, and described for a reader:
#258and#261, the two Ctrl+C entries, kept separate because they are differentfailures with different fixes. Both name the states that were confirmed rather than reasoned about.
#260is not present, and should not be: it is a#[cfg(test)]addition tosrc/fjord/oidc.rswith zero deletions, and the behaviour it covers is
#258's entry.#262says what the brief asked for and says it first: "fj pr mergeno longer discards thepull request description." It goes on to name the silence, which is the part that makes it worth
reading: "the merge succeeded and the commit looked normal." Not "default merge message". Correct.
6. Format
Matches, and introduces nothing.
### Added/### Changed/### Fixed, in Keep a Changelog order, withChangedinsertedbetween the existing two rather than appended.
### Changedis not a new heading here: 0.3.0, 0.2.0, 0.1.3 and 0.1.2 all carry one.alone. Wrapping is 79 columns against the file's existing 82.
The constraint held exactly. One file,
CHANGELOG.md, +115 / -0.git diff f7fdce4 HEADoverCargo.toml,Cargo.lockandREADME.mdis empty.## [Unreleased]is still## [Unreleased], andno version was chosen.
Worth knowing, and it is in this PR's favour: leaving it as
[Unreleased]is now enforced ratherthan remembered.
release.yml:376fails the run with "CHANGELOG.md has no '## [$VERSION]' section",so a release cut before someone renames the heading stops at the publish job instead of shipping an
empty release body. The one-line follow-up cannot be skipped by accident, which is the right shape for
leaving that decision to the operator.
Required to land
twenty-one undocumented; five excluded as CI, coverage or test-only; entries do not map one to one
onto commits,
#251giving five and the release work collapsing five into one.Both are text-only and neither touches an entry's substance.
Non-blocking, worth a line each if the file is being edited anyway
#262entry could say the default applies to every merge style, not only squash.#251migration instruction ("UseFJ_TOKEN_<HOST>for that case") is the same kind ofwarning
#243bolds, and is not bolded.#251's own PR records that the README and docs still describe genericFJ_TOKENas alwayschecked first, which this change makes untrue. Out of scope for a CHANGELOG, and out of scope for
this PR by its own constraint, but it is a real follow-up and nothing else is tracking it here.
Verdict
CHANGES, on two text fixes. The research behind this file is good and the entries are unusually
well checked: I verified every one of the sixteen against its PR and, where the claim named a
constant or a code path, against the source, and only one clause failed. That clause fails in the
direction that matters, in the longest entry, in the part that gets published, and it says a thing is
broken that this fleet fixed five weeks ago.
The count is the second fix and the cheaper one. It does not ship, but the brief is right that a PR
which miscounts its own contents is the shape worth stopping, and the miscount here is real: eight
excluded is five, and the three commits counted as dropped are described in the diff.
Gated in
/home/dev/workspaces/claude-5/gate-266, detached at86309e0. Nothing pushed, merged orfixed; the clone is unmodified and the only untracked file is this verdict.
/home/dev/workspaces/claude-7/fj-changelogwas not used.The release bullet said the zero-asset v0.4.1 publish "is why `brew install fj` has been serving 0.3.0 since July". The first clause is true of July; the second stopped being true on 30 July. This file is where a release body comes from (release.yml:353-374), so the sentence would have been published verbatim to everyone who opened the release page, telling them the tap was stale in the same paragraph that describes the work which unstaled it. Checked against the live forge rather than reasoned about: v0.4.1 draft=false, 5 assets, published 2026-07-22T20:19:49Z SHA256SUMS, fj.rb, three tarballs, all created 2026-07-30T02:59Z #230 / #233 / #234 merged 07-25 01:33, 07-30 02:10, 07-30 02:46 homebrew-tap Formula/fj.rb version "0.4.1", committed 07-30T03:06Z 99ee1c6a / a1a593e7 / 624ae2c0 match the published SHA256SUMS exactly So the assets arrived thirteen minutes after #234 made the recovery dispatch possible, the tap followed seven minutes later, and the outage ran 22 to 30 July rather than to the present. The entry now says that, and gains the sentence it was missing: the assets were uploaded on 30 July and the tap has served 0.4.1 since. Nothing else in the entry changes; the rewrap is to keep the paragraph at 79 columns.Record the 21 undocumented changes in [Unreleased]to Record sixteen of the twenty-one undocumented changes in [Unreleased]