You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Wizard omitted-lifecycle default falls back to sdd for current templates (typed-sdd only for Workspace.Template 0.15.0) #4811
Observed (2026-10-22, read-only qualification run FS-GG/FS.GG.Templates 39859903416, independently verified): when the lifecycle is omitted, the public Wizard FS.GG.NewSddWorkspace0.21.0 with Workspace.Template 0.19.2 records lifecycle sdd. A direct provider or raw-template scaffold records typed-sdd.
Cause:scripts/NewSddWorkspace/Program.fs:160-170 (at 12480a20) returns typed-sdd only when the descriptor pins exactly FS.GG.Workspace.Template::0.15.0. PR #3947 scoped it that way, so once the 0.15.0 pin was superseded, the Wizard's omitted default fell back to sdd.
Why it matters:docs/roadmaps/svg-release-d.md:113-118 (D.5) promised that omitted SVG creation through the Wizard proves the root typed-sdd lifecycle. Public users creating through the Wizard have lost that activated D.5 default. This blocks #4644's default-activation claim. It does not block #4709's narrower "mapped" Done-when, which is accepted.
Requested (Wizard owner):
Make the Wizard's omitted-lifecycle default independent of an exact template-version pin (e.g. derive it from the descriptor's declared default lifecycle), so typed-sdd holds for current templates.
Add a regression test against the current descriptor.
Update the Templates verifier expectation (ReferencePublication / verifier line ~399, whose comment at ~382 is stale).
Related, lower priority: a pinned Wizard 0.21.0 with the default or typed-sdd lifecycle refuses unless the exact Workspace.Template 0.18.2 is preinstalled (pinnedGovernancePreflight, Program.fs ~3019). Unpinned users are unaffected.
Filed by fdev from the #4709 acceptance review. Linked to #4644.
fdev 2026-10-23: the #4811 source fix is merged. This comment asks for authorization of the Wizard (FS.GG.NewSddWorkspace) 0.22.0 release. Nothing has been dispatched or published.
Accepted source slice
#4813 merged as 74b852f1590ba0d58423a6c4d1253db91ba3e7fc. It was squashed from the exact head e3f5a177, which has the same tree.
Rule: when fable-game omits the lifecycle, the Wizard now uses the lifecycle default that the fetched descriptor declares. That is typed-sdd for Workspace.Template 0.15.0 and later, sdd for 0.14.0 and earlier. The old rule pinned typed-sdd to exactly FS.GG.Workspace.Template::0.15.0.
Unchanged:
An explicit --lifecycle is still forwarded unchanged.
Every other template keeps sdd.
A descriptor with no readable default keeps sdd and prints a warning.
pinnedGovernancePreflight is byte-identical, so the 0.18.2-overlay precondition is not widened.
Tests: they run against the unmodified, hash-bound tagged descriptors (0.14.0, 0.15.0, 0.19.2, 0.19.3), checking both the pure selector and compiled Wizard runs. The fixture passed 99/99, and all 5 mutation controls went red as expected.
Review: an independent fsgg-critic-best review first returned REJECT on two red non-required gates, atlas seed drift and the engine-build-siting fixture seal. Both were repaired on the same PR. The review then returned ACCEPT at 9e17f12a and again at the exact merge head e3f5a177.
CI: 57 passed and 2 skipped at e3f5a177. The merge used --match-head-commit.
Not yet true: the public Wizard 0.21.0 still records sdd. #4811 stays open until 0.22.0 is published and the Templates receiver is flipped. #4644 stays blocked on the same condition.
Publication request: Wizard 0.22.0
Release route. Read from source at 74b852f1; the 0.21.0 precedent is #4741, #4748 and run 39462099428.
Version bump and release-route PR needed first. The release code currently names 0.21.0, so one source PR must land before any dispatch. Following #4748, it would:
Bump scripts/NewSddWorkspace/NewSddWorkspace.fsproj to <Version>0.22.0</Version> and update PackageReleaseNotes.
Retarget both release workflows and new-sdd-workspace-selftest.yml from 0.21.0 / creator021 to 0.22.0 / creator022.
Add scripts/creator022-coord-dependencies.json and update scripts/creator-current-coord-dependencies.py.
Update tests: tests/new-sdd-workspace-successor/*, tests/release-effect-sealing/run.py (keep the 021 history, add 022), and tests/new-sdd-workspace/product-board.fsx.
Add a 022 amendment to docs/reports/gs2-08-9-release-route-dispositions.json.
Decision needed from root. The latest published, promoted coherent set is 0.112.0, while source builds 0.113.0. Choose which coherent set Creator 0.22 pins. 0.21 pinned published 0.110.0.
Then, in order (EHotwagner dispatches each run):
Run the candidate. Record the run ID, artifact ID and artifact digest.
Run the publisher with publish=false, as a read-only preflight. Optionally also set verify_nuget_login=true.
Run the publisher with publish=true, first attempt only. To recover, start a new dispatch against the existing journal; do not re-run.
Read back all 8 effects, both feeds' bytes and an isolated dotnet tool install.
Open a registry flip PR covering registry/dependencies.yml (package-version/package-tag), docs/registry/compatibility.md, docs/architecture.md and both publishing-and-deployment skill copies.
I could not confirm whether any repository-wide publication freeze still applies; see #4753.
Templates verifier change needed (Templates owner; not edited here)
After 0.22.0 is published, re-pin the current-public cohort to it. These line numbers are against FS-GG/FS.GG.Templates main7be0bcf5.
L103: change 'wizardLifecycle': 'sdd' to 'wizardLifecycle': 'typed-sdd'.
L112–113: replace the comment # Wizard019/020 forward the same sdd default: the omission rule names only015. with # Wizard 0.22.0+ forwards the descriptor's declared omission default (typed-sdd) (.github#4811). Change effective_lifecycle = lifecycle if lifecycle is not None else 'sdd' to ... else 'typed-sdd'.
L162–163, L184: replace current_wizard_sha, current_wizard_revision and "$wizard_version" == 0.21.0 with the published 0.22.0 archive sha256, source revision and 0.22.0.
L418–420: delete the two comment lines # Wizard 0.21.0 forwards its own omitted default \sdd` …and the linewizard_default_lifecycle=sdd. The wizard route then keeps L409's wizard_default_lifecycle=typed-sdd`, and the L403 comment ("Omitted lifecycle must resolve to typed-sdd …") becomes true again.
L451: change params.get('lifecycle') == 'sdd' to params.get('lifecycle') == 'typed-sdd'.
L469: in the comment, change Wizard sdd lifecycle to Wizard typed-sdd lifecycle.
L159: change 'wizardLifecycle': 'sdd' to 'typed-sdd'.
L289: the negative control's wrong value 'typed-sdd' becomes 'sdd'.
docs/roadmaps/staged-fable-game-adoption.mdL468: change "wizardLifecycle": "sdd" to "typed-sdd".
The pinned public-default receiver will now take the typed-knowledge path. Its hive already gets the 0.18.2 overlay (L424–426), so the pinned precondition is unchanged.
Status: no board item or Status for #4811 was found, so nothing was changed. Nothing was closed.
fdev 2026-10-23: the Wizard 0.22.0 candidate and its publish=false preflight both passed. Waiting for your GO before publish=true. Nothing has been published.
Release-route source.#4825 merged as 1065adc506c676e35a4cb9095437a2b71d15f780 (squash, --match-head-commit 23cbf2cb).
It sets NewSddWorkspace to 0.22.0 and adds CURRENT_022.
Dependency pin: fixed scripts/creator022-coord-dependencies.json on the published coherent 0.112.0 set:
release 419781177, source d5af6a98;
CLI 7f65b2d6…, manifest 0c9efdcc…;
81 members, 11 projects, 293 leaves.
Journal: fresh board-v2-product-creator-022.
Workflows: retargeted candidate, publisher and selftest.
Dispositions report: a closed creator022ProfileAmendment that inverts exactly to the accepted f7ebde70 workflow.
Seal: the source-compatibility epoch is resealed.
Review and checks.
The independent fsgg-critic-best review first returned REJECT: main had moved, so the seal no longer matched the squash tree. After a merge and reseal it returned ACCEPT at the exact head. Before merging I checked by simulation that the only later main commit, docs: report development progress at 2026-10-23 07:56 UTC #4827, is a progress-report addition outside the seal, and that the squash result keeps the seal and passes the successor suite (218 OK).
All 8 required checks passed. The non-required feed check fails on the unrelated wasm-shared-runtime 0.7.0 registry flip, and fails the same way on main.
Candidate. Run 39922602748 at 1065adc5: attempt 1, EHotwagner, success.
journal refs/heads/fsgg/v2/journal/release/board-v2-product-creator-022 (state/releases/board-v2-product-creator-022) is fresh: true, startingJournal: null, journalMutationMayHaveOccurred: false;
iterationsAttempted: 0, lastDispatch: null;
Authority calls: get 18, patch 0, post 0; quota remaining 4999 of 5000.
Independent readback afterwards:
tag new-sdd-workspace/v0.22.0 is absent (404) and there is no 0.22.0 release;
nuget.org returns 404 for 0.22.0, and the newest listed versions are still 0.20.0 and 0.21.0.
Main is still 1065adc5. The publisher refuses if main gains non-report changes before publishing. If that happens, it will need a fresh candidate rather than a rerun.
Your GO. The exact dispatch for publish=true, first attempt only, with no reruns (recovery is a new dispatch against the existing journal):
fdev 2026-10-23: Wizard 0.22.0: the second publish=false preflight was refused, by a race with concurrent writes to the Authority repo, not by the candidate. Nothing has been published, and publish=true has not been dispatched.
Why the first candidate became unusable. Main moved to 150d5c43 (#4824, the Wasm 0.7.0 registry reconcile). That commit changed non-report files, including registry/dependencies.yml. The publisher's source-compatibility rule (SourceCompatibility.compatible in scripts/new_sdd_workspace_successor_admission.py) accepts a moved main only when the change is a progress-report addition under the sealed graph. Otherwise candidate, publisher and current main must be identical. So candidate 39922602748 at 1065adc5 can no longer be admitted.
New candidate. Run 39923792809 at 150d5c43, attempt 1: success.
In the log, all eight effects observed as absent, and the last one logged was promote: release-absent.
Cause.prepare_publication (scripts/new-sdd-workspace-successor-publish.py:158) requires that the main of the protected journal repo, FS.GG.Coordination.Authority, has not moved between classifying the destination and admitting the journal.
The run classified Authority at 99c6d495, from a commit made at 08:27:52Z.
Another actor's "ordinary v2 settlement shard 5782a96c…" commit then moved Authority main to 1aae2927 at 08:28:03Z, about ten seconds before the check at 08:28:13Z.
These settlement writes come in bursts of about 30 seconds every few minutes (for example 08:23:59–08:24:33 and 08:27:31–08:28:03).
The source compatibility and candidate passed. The earlier preflight (39923388464) passed while Authority was quiet.
Readback. No new-sdd-workspace/v0.22.0 tag, no release, nuget.org 0.22.0 returns 404, and the creator-022 journal directory is untouched. Main is still 150d5c43.
Decision needed. The publication admission depended on a passing preflight, so I stopped. Options:
(a) Admit one more publish=false preflight against the same candidate 39923792809, timed between settlement bursts. If it passes and main is still 150d5c43, use the already-admitted single publish=true.
(b) Dispatch publish=true directly. Its preparation step makes the same check before any journal write, so a race refuses safely with no mutation. But that consumes the single admitted dispatch.
This refusal is a race between the publisher and concurrent ordinary-ledger writers, not a product defect. It belongs with the #4753 resource and writer-contract scope.
fdev 2026-10-23: Wizard 0.22.0 publish=true stopped mid-run. The protected journal now records a tag intent that was never sent. Nothing was published. I have NOT run the admitted recovery dispatch, because the engine cannot settle this state (see "Recovery assessment"). Your decision is needed.
Preflight, admitted rerun. Run 39925179125 on candidate 39923792809 was dispatched after Authority main had been stable for ≥75 s at 1aae2927.
Result: passed. preflightPassed: true, fresh: true, no journal mutation, Authority calls get 18, post 0.
Afterwards .github main was still 150d5c43 and Authority was quiet.
Publish. Run 39925400140 at 150d5c43, attempt 1, "Wizard 0.22 successor 39923792809": refused at stage: reconciliation in iterationsAttempted: 1, with firstCause.kind=Refused.
Authority counter: get attempted 52 / succeeded 51; patch 2; post 14.
Authority journal writes, all made by this run:
81c4f827 "Release successor generation 1" and 7874ba13 "Release directory generation 1", at 08:34:36–39Z.
ed5d0349 "Release successor generation 2" and 011386cf "Release directory generation 2", at 08:34:48–50Z.
state/releases/board-v2-product-creator-022/release-state.json at generation 2:
effects: {"tag": "intent"};
contentId sha256:68460389…, sourceSha 150d5c43, version 0.22.0, candidateArchiveSha256 9e727511….
Independent readback:
No new-sdd-workspace/v0.22.0 tag (404).
No 0.22.0 release.
nuget.org 0.22.0 returns 404.
Main is unchanged at 150d5c43.
What happened. The engine (full_transition in scripts/release_successor_execution.py) runs these steps for the first effect:
admit the intent;
compare-and-swap the journal to tag: intent (generation 2);
re-authorize the dispatch;
call provider.dispatch.
Step 4 never ran (lastDispatch: null, tag absent). So the refusal was step 3: "tag: dispatch admission denied", raised 2 s after the generation-2 write.
The cause is an inference from the counter: one Authority GET failed in that window (52 attempted, 51 succeeded). ProtectedPublisherAdmission.authorize (scripts/release-successor-publish.py:613-625) re-reads Authority protection there, and maps any KeyError/ValueError/OSError/RuntimeError to False. A single transient read failure is therefore a hard dispatch denial after the intent is committed.
Recovery assessment. For an effect in intent whose observation is absent, the engine returns "waiting" and never resends (release_successor_execution.py:283-285: "A 404 after a send is not proof of no effect"). A recovery dispatch against this journal would therefore:
only observe tag absent on each pass;
hit the bound of 136 steps (about 11 min), then refuse;
make no progress or effect.
#4805's opt-in BoundIntentFence does not help either: by design it never re-permits an inherited intent. So the admitted recovery cannot complete 0.22.0, and I am holding it.
Options (your call).
(1) Fresh journal identity. A small reviewed source PR moves the Wizard publisher to a new logical journal, for example board-v2-product-creator-022r1, with a matching summary/report row and a reseal. The abandoned …-022 journal is recorded as non-current history whose only effect is an unsent tag intent. Then: a new candidate, a preflight, and publish=true with its fresh path. The 0.22.0 tag, release and feeds are all still unused. Optionally harden the dispatch re-authorization against one transient read failure, but that is the shared engine and protected admission, so it needs its own review.
(3) Run the admitted recovery anyway, purely to document the stranded state. Expected outcome: no progress.
Merges to main can resume, as far as 0.22.0 is concerned: any of the options above needs a new candidate in any case. The Authority-race and stranded-intent findings are filed on #4753.
fdev 2026-10-23: correction to the 39925400140 diagnosis. There was no failed GET. The 52/51 Authority GET gap is the expected 404 that the publisher gets when it checks that the fresh journal ref is absent. Every fresh preflight shows the same gap, including the passing ones: 39923388464, 39925179125 and 39938911336 (18 attempted / 17 succeeded).
Evidence:
Authority PATCHes: 2 attempted / 2 succeeded, so generation 2 landed on main (011386cf).
The summary's lastObservedJournal is still generation 1.
No other Authority commit occurred between 08:34 and 08:36Z.
What fits: a stale GitHub read right after the write.
ProtectedReleaseJournal._compare_state PATCHes, then self.read() (scripts/release_successor_journal.py:830).
That read observed the previous head.
Either the compare-and-swap returned False (the engine then raises "journal intent CAS conflict"), or read()'s two-GET check raised "journal head moved during read".
fdev 2026-10-23: Wizard FS.GG.NewSddWorkspace 0.22.0 is PUBLISHED and read back. An omitted fable-game lifecycle now gives typed-sdd on current templates. This issue stays open for the Templates verifier flip and qualification run, which fdev has routed to the Templates owner.
Each PR had an independent fsgg-critic-best ACCEPT on its exact head and green required checks, and was merged with --match-head-commit.
Publication
Candidate:39936317651 at 6e6fb9b9, artifact 12494691636, sha256:d9001652d005edb4ad88bdf3bccd2ef6886706f8efd5ba4efae629c859555377.
Preflight:39938911336 passed with a fresh 022r1 journal and no writes.
Publisher:39939741711, first attempt, publish=true.
complete: true after 89 iterations; the last dispatch was promote, applied.
Journal 022r1 is at generation 17 with all 8 effects verified: tag, draft, github, nuget, package-asset, manifest-asset, publication-journal-asset, promote.
Summary artifact 12496641389.
Every dispatch was gated on REST quota ≥3000, Authority main stable for ≥60 s, and .github main unchanged under a merge hold.
Independent readback
Tag:new-sdd-workspace/v0.22.0 points at 6e6fb9b9f7677e26f0c7d58cab1646323e81df58.
Release:421718245 is not a draft or prerelease, and "latest" is unchanged. Assets:
FS.GG.NewSddWorkspace.0.22.0.nupkg5a34a5cd…
manifest.json1bd58d36…
publication-journal.jsonebb35464…
nuget.org: 0.22.0 is listed. The signed archive caa91285… has a producer payload equal to the manifest's sha256:ef06eab2… (payload-only verify).
GitHub Packages: observed by the hosted publisher with the archive equal to 5a34a5cd…, per the publication-journal asset. A local read returns 403, a known limit.
Isolated install:dotnet tool install FS.GG.NewSddWorkspace --version 0.22.0 from nuget.org only, in a clean HOME and cache. The stored nupkg equals the nuget.org bytes.
Behaviour (this issue): I ran the installed 0.22.0 against Templates main, whose fable-game descriptor declares source: FS.GG.Workspace.Template::0.19.3, using a stub fsgg-sdd that logs the scaffold arguments.
No --lifecycle forwards --param lifecycle=typed-sdd and bundle=player.
Explicit --lifecycle sdd forwards sdd.
Abandoned journal.board-v2-product-creator-022 holds an unsent tag: intent from publisher 39925400140. It stays history and is never resumed. The diagnosis is read-after-write staleness after the write, not a failed GET; see #4753. Its follow-up, proposal (ii) on #4753, is assigned to fdev.
Still open
The registry package-version reconcile and Atlas record are in #4838, under review.
The Templates verifier flip, then a public qualification run on Wizard 0.22.0, belongs to the Templates owner. The exact line changes are in my earlier comment above; re-pin the Wizard identity to the 0.22.0 values listed here.
fdev 2026-10-23, Templates owner: a defect in the "Templates verifier change needed" spec (6359655043), found by the independent review of Templates#760, and how I am handling it.
The defect. The spec's verifier L103 and L112–113, preflight-test L159 and L289, and staged-fable-game-adoption.md L468 are in the verifier's --mode current-publicmetadata route (L34–144), not in full mode.
That route admits only Wizard 0.19.0 and 0.20.0 (wizard_packages).
Those Wizards pick typed-sdd on omission only for source: FS.GG.Workspace.Template::0.15.0 (scripts/NewSddWorkspace/Program.fs L166–168 at 699f6085 and cc1d3c12). For the provider 0.19.0 descriptor f5fbd06e, they forward sdd.
Flipping those lines would claim that Wizard 0.19 and 0.20 forward typed-sdd, which is false. It would also contradict the roadmap's own L476–479.
It applies every full-mode edit at re-verified current lines: L162–163, L184, L530–532 (the deleted sdd override), L563 and L581. These lines moved by +112 because of Templates#756.
It leaves the metadata-route lines at main's bytes.
It makes the changes the full-mode edits require: the fixture re-pins to 0.22.0, and the superseded 0.21.0 is now refused.
It fixes the stale "Wizard 0.21.0" comments.
Pin: nuget.org signed archive caa91285e5370edc7a8a14a5a46f6cfef236d1db95f1e186357e6591b9ec7bd5, revision 6e6fb9b9f7677e26f0c7d58cab1646323e81df58. The tag new-sdd-workspace/v0.22.0 and the nuspec commit agree, and the pin form matches 0.21.0's.
The full run that follows the merge exercises exactly the changed full-mode path: the Wizard default typed-sdd receiver, plus the player public default built with typed-sdd. If the spec owner wants the metadata route changed anyway, that needs a separate decision.
fdev 2026-10-23, Templates owner: default Wizard SVG creation is now typed-sdd, qualified hosted. This is read-only full run 39946080162 on Wizard 0.22.0 + Workspace.Template 0.19.3 + SDD 2.4.0: passed.
Verifier flip:Templates#760 merged as a3b5476b85a1630b84c5b8bae40916a575a21219.
Pin: Wizard 0.22.0, nuget.org signed archive caa91285e5370edc7a8a14a5a46f6cfef236d1db95f1e186357e6591b9ec7bd5, revision 6e6fb9b9f7677e26f0c7d58cab1646323e81df58 (the tag new-sdd-workspace/v0.22.0 and the nuspec commit agree).
Full mode:
the Wizard 0.21.0 sdd override is deleted;
the Wizard route and the public default (player bundle) now assert typed-sdd;
readback.sha256 lists exactly those four identities.
The D.5 activation evidence. These are the Wizard scaffold effectiveParameters, compared with the Wizard 0.21.0 run 39915065069 on the same template and SDD:
receiver
lifecycle requested
0.21.0 recorded
0.22.0 recorded
wizard-public (player, the exact public default)
omitted
sdd
typed-sdd
wizard (complete)
omitted
sdd
typed-sdd
wizard-typed
typed-sdd
typed-sdd
typed-sdd
wizard-none
none
none
none
What the typed-knowledge path adds: the default-created workspaces gain exactly four files that 0.21.0 did not create: .fsgg/knowledge/records/project-knowledge.json, .fsgg/knowledge/schema.json, .github/workflows/project-knowledge.yml and scripts/check-project-knowledge.py. Nothing was removed.
The checker's own assertion passed: the public default's scaffold-provenance.json has lifecycle typed-sdd, bundle player and generator SDD 2.4.0.
Builds and browser: all four receivers (direct, provider, wizard, wizard-public) built with 0 warnings and 0 errors. Every per-project test total is identical to 0.21.0's: for example, wizard-public has Domain 18, Protocol 26 and Server 20, all passing. The browser runs on direct, provider and wizard each passed.
Hives: all four Wizard hives (wizard, wizard-public, wizard-typed, wizard-none) resolved Workspace.Template 0.19.3.
Limits:
n = 1.
The public default (player) is built and its tests run; the browser runs cover direct, provider and the wizard complete receiver, as in every earlier full run.
For #4811 and #4644: the Templates receiver flip is merged, and the published Wizard 0.22.0 now creates typed-sdd by default on the current public SVG template, proven hosted. I am not closing or changing the status of anything; closure is for the coordinator.
Wizard 0.22.0 published: run 39939741711; readback of tag, release, nuget.org payload and isolated install.
Templates verifier flip: Templates#760 (a3b5476b), with the spec defect recorded: the older 0.19/0.20 route correctly stays sdd, and the superseded 0.21.0 is refused.
Hosted full run39946080162: the public default (player) and the Wizard complete workspace now record typed-sdd, explicit none still records none, and builds and tests are identical to 0.21.0. Evidence.
The pinned-precondition quirk (a pinned Wizard needs the 0.18.2 overlay) is unchanged and remains recorded.
Activity
EHotwagner commentedon Oct 23, 2026
fdev 2026-10-23: the #4811 source fix is merged. This comment asks for authorization of the Wizard (
FS.GG.NewSddWorkspace) 0.22.0 release. Nothing has been dispatched or published.Accepted source slice
#4813 merged as
74b852f1590ba0d58423a6c4d1253db91ba3e7fc. It was squashed from the exact heade3f5a177, which has the same tree.fable-gameomits the lifecycle, the Wizard now uses thelifecycledefault that the fetched descriptor declares. That istyped-sddfor Workspace.Template 0.15.0 and later,sddfor 0.14.0 and earlier. The old rule pinnedtyped-sddto exactlyFS.GG.Workspace.Template::0.15.0.--lifecycleis still forwarded unchanged.sdd.sddand prints a warning.pinnedGovernancePreflightis byte-identical, so the 0.18.2-overlay precondition is not widened.atlasseed drift and theengine-build-sitingfixture seal. Both were repaired on the same PR. The review then returned ACCEPT at9e17f12aand again at the exact merge heade3f5a177.e3f5a177. The merge used--match-head-commit.github/wizard-omitted-lifecycle-descriptor-default.Not yet true: the public Wizard 0.21.0 still records
sdd. #4811 stays open until 0.22.0 is published and the Templates receiver is flipped. #4644 stays blocked on the same condition.Publication request: Wizard 0.22.0
Release route. Read from source at
74b852f1; the 0.21.0 precedent is #4741, #4748 and run 39462099428..github/workflows/release-new-sdd-workspace-successor-candidate.yml.workflow_dispatchonmain, with no inputs.EHotwagnerand attempt 1..github/workflows/release-new-sdd-workspace.yml.candidate_run_id,candidate_artifact_id,candidate_archive_sha256,verify_nuget_login,publish.github.ref == refs/heads/main && github.actor == 'EHotwagner'.release-successor: custom branch policy, no required reviewers.NuGet/login@v1withuser: Paradigma11. The policy matches on this workflow filename, so do not rename it.github.token. The protected journal uses the ordinary-ledger App token.newSDDFullStackenvironment in FS-GG/.github.draft:false,make_latest:false).Version bump and release-route PR needed first. The release code currently names 0.21.0, so one source PR must land before any dispatch. Following #4748, it would:
scripts/NewSddWorkspace/NewSddWorkspace.fsprojto<Version>0.22.0</Version>and updatePackageReleaseNotes.SOURCE_022/CURRENT_022bindings and moveVERSION/TAG/the journal ref (…creator-022) in:scripts/creator_source_qualification.pyscripts/new_sdd_workspace_successor_{execution,admission,provider}.pyscripts/new-sdd-workspace-successor-{publish,artifact}.pyKNOWN_GRAPH_SEAL.new-sdd-workspace-selftest.ymlfrom 0.21.0 / creator021 to 0.22.0 / creator022.scripts/creator022-coord-dependencies.jsonand updatescripts/creator-current-coord-dependencies.py.tests/new-sdd-workspace-successor/*,tests/release-effect-sealing/run.py(keep the 021 history, add 022), andtests/new-sdd-workspace/product-board.fsx.docs/reports/gs2-08-9-release-route-dispositions.json.Decision needed from root. The latest published, promoted coherent set is 0.112.0, while source builds 0.113.0. Choose which coherent set Creator 0.22 pins. 0.21 pinned published 0.110.0.
Then, in order (EHotwagner dispatches each run):
publish=false, as a read-only preflight. Optionally also setverify_nuget_login=true.publish=true, first attempt only. To recover, start a new dispatch against the existing journal; do not re-run.dotnet tool install.registry/dependencies.yml(package-version/package-tag),docs/registry/compatibility.md,docs/architecture.mdand both publishing-and-deployment skill copies.I could not confirm whether any repository-wide publication freeze still applies; see #4753.
Templates verifier change needed (Templates owner; not edited here)
After 0.22.0 is published, re-pin the current-public cohort to it. These line numbers are against FS-GG/FS.GG.Templates
main7be0bcf5.tests/composition/fable-game/verify-fable-reference-public.sh(sha256ebc51a5e…):'wizardLifecycle': 'sdd'to'wizardLifecycle': 'typed-sdd'.# Wizard019/020 forward the same sdd default: the omission rule names only015.with# Wizard 0.22.0+ forwards the descriptor's declared omission default (typed-sdd) (.github#4811).Changeeffective_lifecycle = lifecycle if lifecycle is not None else 'sdd'to... else 'typed-sdd'.current_wizard_sha,current_wizard_revisionand"$wizard_version" == 0.21.0with the published 0.22.0 archive sha256, source revision and0.22.0.# Wizard 0.21.0 forwards its own omitted default \sdd` …and the linewizard_default_lifecycle=sdd. The wizard route then keeps L409'swizard_default_lifecycle=typed-sdd`, and the L403 comment ("Omitted lifecycle must resolve to typed-sdd …") becomes true again.params.get('lifecycle') == 'sdd'toparams.get('lifecycle') == 'typed-sdd'.Wizard sdd lifecycletoWizard typed-sdd lifecycle.Matching edits are needed elsewhere:
tests/composition/fable-game/test-fable-reference-public-preflight.py:'wizardLifecycle': 'sdd'to'typed-sdd'.'typed-sdd'becomes'sdd'.docs/roadmaps/staged-fable-game-adoption.mdL468: change"wizardLifecycle": "sdd"to"typed-sdd".The pinned public-default receiver will now take the typed-knowledge path. Its hive already gets the 0.18.2 overlay (L424–426), so the pinned precondition is unchanged.
Status: no board item or Status for #4811 was found, so nothing was changed. Nothing was closed.
EHotwagner commentedon Oct 23, 2026
fdev 2026-10-23: the Wizard 0.22.0 candidate and its
publish=falsepreflight both passed. Waiting for your GO beforepublish=true. Nothing has been published.Release-route source. #4825 merged as
1065adc506c676e35a4cb9095437a2b71d15f780(squash,--match-head-commit 23cbf2cb).NewSddWorkspaceto 0.22.0 and addsCURRENT_022.scripts/creator022-coord-dependencies.jsonon the published coherent 0.112.0 set:419781177, sourced5af6a98;7f65b2d6…, manifest0c9efdcc…;board-v2-product-creator-022.creator022ProfileAmendmentthat inverts exactly to the acceptedf7ebde70workflow.Review and checks.
feedcheck fails on the unrelatedwasm-shared-runtime0.7.0 registry flip, and fails the same way on main.Candidate. Run 39922602748 at
1065adc5: attempt 1, EHotwagner, success.12487459467,new-sdd-workspace-successor-candidate-1065adc5…-39922602748, 33,297,430 bytes.sha256:2a130cdfdfa6f7a4fc7e2ec21b0bd87b661cbd406d10feaae837ab79c238bd69.fsgg.creator022-release-qualification/1: 0.22.0, coherent 0.112.0, releaseEligible.Preflight. Publisher run 39923388464, "Wizard 0.22 successor 39922602748", attempt 1, at
1065adc5: success.publish=false,verify_nuget_login=false,promotion_recovery=off. The NuGet login steps were skipped.12488755984(creator022-publication-summary, digest672d1e8e…):mode: preflight,preflightPassed: true,stage: terminal,firstCause: null;1065adc5;refs/heads/fsgg/v2/journal/release/board-v2-product-creator-022(state/releases/board-v2-product-creator-022) isfresh: true,startingJournal: null,journalMutationMayHaveOccurred: false;iterationsAttempted: 0,lastDispatch: null;new-sdd-workspace/v0.22.0is absent (404) and there is no 0.22.0 release;1065adc5. The publisher refuses if main gains non-report changes before publishing. If that happens, it will need a fresh candidate rather than a rerun.Your GO. The exact dispatch for
publish=true, first attempt only, with no reruns (recovery is a new dispatch against the existing journal):It must be dispatched by EHotwagner from
main.After publication, still to do:
package-versionflip;creator022boundary record (capture gap, owner fdev);EHotwagner commentedon Oct 23, 2026
fdev 2026-10-23: Wizard 0.22.0: the second
publish=falsepreflight was refused, by a race with concurrent writes to the Authority repo, not by the candidate. Nothing has been published, andpublish=truehas not been dispatched.Why the first candidate became unusable. Main moved to
150d5c43(#4824, the Wasm 0.7.0 registry reconcile). That commit changed non-report files, includingregistry/dependencies.yml. The publisher's source-compatibility rule (SourceCompatibility.compatibleinscripts/new_sdd_workspace_successor_admission.py) accepts a moved main only when the change is a progress-report addition under the sealed graph. Otherwise candidate, publisher and current main must be identical. So candidate 39922602748 at1065adc5can no longer be admitted.New candidate. Run 39923792809 at
150d5c43, attempt 1: success.12489061170, digestsha256:9e7275110f8501675aaaa9b17cea2f74186991416addf999081cf80bf41f016a.Preflight. Run 39924649699 at
150d5c43, attempt 1,publish=false: refused atstage: preparationwithfirstCause.kind=Refused.creator022-publication-summaryreports:fresh: true,journalMutationMayHaveOccurred: false;iterationsAttempted: 0,lastDispatch: null;promote: release-absent.Cause.
prepare_publication(scripts/new-sdd-workspace-successor-publish.py:158) requires that the main of the protected journal repo, FS.GG.Coordination.Authority, has not moved between classifying the destination and admitting the journal.99c6d495, from a commit made at 08:27:52Z.1aae2927at 08:28:03Z, about ten seconds before the check at 08:28:13Z.Readback. No
new-sdd-workspace/v0.22.0tag, no release, nuget.org 0.22.0 returns 404, and the creator-022 journal directory is untouched. Main is still150d5c43.Decision needed. The publication admission depended on a passing preflight, so I stopped. Options:
publish=falsepreflight against the same candidate 39923792809, timed between settlement bursts. If it passes and main is still150d5c43, use the already-admitted singlepublish=true.publish=truedirectly. Its preparation step makes the same check before any journal write, so a race refuses safely with no mutation. But that consumes the single admitted dispatch.This refusal is a race between the publisher and concurrent ordinary-ledger writers, not a product defect. It belongs with the #4753 resource and writer-contract scope.
EHotwagner commentedon Oct 23, 2026
fdev 2026-10-23: Wizard 0.22.0
publish=truestopped mid-run. The protected journal now records a tag intent that was never sent. Nothing was published. I have NOT run the admitted recovery dispatch, because the engine cannot settle this state (see "Recovery assessment"). Your decision is needed.Preflight, admitted rerun. Run 39925179125 on candidate 39923792809 was dispatched after Authority main had been stable for ≥75 s at
1aae2927.preflightPassed: true,fresh: true, no journal mutation, Authority calls get 18, post 0..githubmain was still150d5c43and Authority was quiet.Publish. Run 39925400140 at
150d5c43, attempt 1, "Wizard 0.22 successor 39923792809": refused atstage: reconciliationiniterationsAttempted: 1, withfirstCause.kind=Refused.12488744225(digeste0cbceb2…):journalMutationMayHaveOccurred: true,lastDispatch: null,complete: false.Authority journal writes, all made by this run:
81c4f827"Release successor generation 1" and7874ba13"Release directory generation 1", at 08:34:36–39Z.ed5d0349"Release successor generation 2" and011386cf"Release directory generation 2", at 08:34:48–50Z.state/releases/board-v2-product-creator-022/release-state.jsonat generation 2:effects: {"tag": "intent"};contentId sha256:68460389…,sourceSha 150d5c43,version 0.22.0,candidateArchiveSha256 9e727511….Independent readback:
new-sdd-workspace/v0.22.0tag (404).150d5c43.What happened. The engine (
full_transitioninscripts/release_successor_execution.py) runs these steps for the first effect:tag: intent(generation 2);provider.dispatch.Step 4 never ran (
lastDispatch: null, tag absent). So the refusal was step 3: "tag: dispatch admission denied", raised 2 s after the generation-2 write.The cause is an inference from the counter: one Authority GET failed in that window (52 attempted, 51 succeeded).
ProtectedPublisherAdmission.authorize(scripts/release-successor-publish.py:613-625) re-reads Authority protection there, and maps anyKeyError/ValueError/OSError/RuntimeErrortoFalse. A single transient read failure is therefore a hard dispatch denial after the intent is committed.Recovery assessment. For an effect in
intentwhose observation isabsent, the engine returns"waiting"and never resends (release_successor_execution.py:283-285: "A 404 after a send is not proof of no effect"). A recovery dispatch against this journal would therefore:tagabsent on each pass;#4805's opt-in
BoundIntentFencedoes not help either: by design it never re-permits an inherited intent. So the admitted recovery cannot complete 0.22.0, and I am holding it.Options (your call).
board-v2-product-creator-022r1, with a matching summary/report row and a reseal. The abandoned…-022journal is recorded as non-current history whose only effect is an unsent tag intent. Then: a new candidate, a preflight, andpublish=truewith its fresh path. The 0.22.0 tag, release and feeds are all still unused. Optionally harden the dispatch re-authorization against one transient read failure, but that is the shared engine and protected admission, so it needs its own review.lastDispatch nullplus an absent effect. This is broader and fits under Remove repository-wide publication freezes and reduce release reconciliation overhead #4753.Merges to main can resume, as far as 0.22.0 is concerned: any of the options above needs a new candidate in any case. The Authority-race and stranded-intent findings are filed on #4753.
EHotwagner commentedon Oct 23, 2026
fdev 2026-10-23: correction to the 39925400140 diagnosis. There was no failed GET. The 52/51 Authority GET gap is the expected 404 that the publisher gets when it checks that the fresh journal ref is absent. Every fresh preflight shows the same gap, including the passing ones: 39923388464, 39925179125 and 39938911336 (18 attempted / 17 succeeded).
Evidence:
011386cf).lastObservedJournalis still generation 1.What fits: a stale GitHub read right after the write.
ProtectedReleaseJournal._compare_statePATCHes, thenself.read()(scripts/release_successor_journal.py:830).False(the engine then raises "journal intent CAS conflict"), orread()'s two-GET check raised "journal head moved during read".Consequences:
EHotwagner commentedon Oct 23, 2026
fdev 2026-10-23: Wizard
FS.GG.NewSddWorkspace0.22.0 is PUBLISHED and read back. An omitted fable-game lifecycle now givestyped-sddon current templates. This issue stays open for the Templates verifier flip and qualification run, which fdev has routed to the Templates owner.Source chain
74b852f1): the Wizard derives an omitted fable-game lifecycle from the descriptor's declared default.1065adc5): the release routeCURRENT_022on genuine promoted coherent 0.112.0.6e6fb9b9): adds a bounded admission-read retry and moves the publisher to the fresh journalboard-v2-product-creator-022r1. The abandoned…-022journal is recorded as history.--match-head-commit.Publication
6e6fb9b9, artifact12494691636,sha256:d9001652d005edb4ad88bdf3bccd2ef6886706f8efd5ba4efae629c859555377.publish=true.complete: trueafter 89 iterations; the last dispatch waspromote, applied.12496641389.Independent readback
new-sdd-workspace/v0.22.0points at6e6fb9b9f7677e26f0c7d58cab1646323e81df58.FS.GG.NewSddWorkspace.0.22.0.nupkg5a34a5cd…manifest.json1bd58d36…publication-journal.jsonebb35464…caa91285…has a producer payload equal to the manifest'ssha256:ef06eab2…(payload-only verify).5a34a5cd…, per the publication-journal asset. A local read returns 403, a known limit.dotnet tool install FS.GG.NewSddWorkspace --version 0.22.0from nuget.org only, in a clean HOME and cache. The stored nupkg equals the nuget.org bytes.main, whose fable-game descriptor declaressource: FS.GG.Workspace.Template::0.19.3, using a stubfsgg-sddthat logs the scaffold arguments.--lifecycleforwards--param lifecycle=typed-sddandbundle=player.--lifecycle sddforwardssdd.Abandoned journal.
board-v2-product-creator-022holds an unsenttag: intentfrom publisher 39925400140. It stays history and is never resumed. The diagnosis is read-after-write staleness after the write, not a failed GET; see #4753. Its follow-up, proposal (ii) on #4753, is assigned to fdev.Still open
package-versionreconcile and Atlas record are in #4838, under review.EHotwagner commentedon Oct 23, 2026
fdev 2026-10-23, Templates owner: a defect in the "Templates verifier change needed" spec (6359655043), found by the independent review of Templates#760, and how I am handling it.
The defect. The spec's verifier L103 and L112–113, preflight-test L159 and L289, and
staged-fable-game-adoption.mdL468 are in the verifier's--mode current-publicmetadata route (L34–144), not in full mode.wizard_packages).typed-sddon omission only forsource: FS.GG.Workspace.Template::0.15.0(scripts/NewSddWorkspace/Program.fsL166–168 at699f6085andcc1d3c12). For the provider 0.19.0 descriptorf5fbd06e, they forwardsdd.typed-sdd, which is false. It would also contradict the roadmap's own L476–479.What #760 does instead:
sddoverride), L563 and L581. These lines moved by +112 because of Templates#756.Pin: nuget.org signed archive
caa91285e5370edc7a8a14a5a46f6cfef236d1db95f1e186357e6591b9ec7bd5, revision6e6fb9b9f7677e26f0c7d58cab1646323e81df58. The tagnew-sdd-workspace/v0.22.0and the nuspec commit agree, and the pin form matches 0.21.0's.The full run that follows the merge exercises exactly the changed full-mode path: the Wizard default
typed-sddreceiver, plus theplayerpublic default built withtyped-sdd. If the spec owner wants the metadata route changed anyway, that needs a separate decision.EHotwagner commentedon Oct 23, 2026
fdev 2026-10-23, Templates owner: default Wizard SVG creation is now
typed-sdd, qualified hosted. This is read-only full run 39946080162 on Wizard 0.22.0 + Workspace.Template 0.19.3 + SDD 2.4.0: passed.Verifier flip: Templates#760 merged as
a3b5476b85a1630b84c5b8bae40916a575a21219.caa91285e5370edc7a8a14a5a46f6cfef236d1db95f1e186357e6591b9ec7bd5, revision6e6fb9b9f7677e26f0c7d58cab1646323e81df58(the tagnew-sdd-workspace/v0.22.0and the nuspec commit agree).sddoverride is deleted;typed-sdd;sddis correct, so those lines staysdd(#4811 comment 6363447499). The second review gave ACCEPT on1a017d46.The run:
a3b5476b. Success at 11:44:34Z.sha256:df3132da607f310f3d847514fa0ccb8cc7fbea4baf765fcb4f490b21ed80bf0c.qualification.json:disposition: passed,wizardQualification: passed, Wizard0.22.0/caa91285/6e6fb9b9, SDD 2.4.01df2e74f, Workspace.Template 0.19.39594ec20(tag at7be0bcf5), descriptor6b3d8f2d.readback.sha256lists exactly those four identities.The D.5 activation evidence. These are the Wizard scaffold
effectiveParameters, compared with the Wizard 0.21.0 run 39915065069 on the same template and SDD:wizard-public(player, the exact public default)sddtyped-sddwizard(complete)sddtyped-sddwizard-typedtyped-sddtyped-sddtyped-sddwizard-nonenonenonenone.fsgg/knowledge/records/project-knowledge.json,.fsgg/knowledge/schema.json,.github/workflows/project-knowledge.ymlandscripts/check-project-knowledge.py. Nothing was removed.scaffold-provenance.jsonhas lifecycletyped-sdd, bundleplayerand generator SDD 2.4.0.Limits:
completereceiver, as in every earlier full run.For #4811 and #4644: the Templates receiver flip is merged, and the published Wizard 0.22.0 now creates
typed-sddby default on the current public SVG template, proven hosted. I am not closing or changing the status of anything; closure is for the coordinator.EHotwagner commentedon Oct 23, 2026
fdev 2026-10-23: ACCEPTED, complete.
74b852f1).a3b5476b), with the spec defect recorded: the older 0.19/0.20 route correctly stayssdd, and the superseded 0.21.0 is refused.completeworkspace now recordtyped-sdd, explicitnonestill recordsnone, and builds and tests are identical to 0.21.0. Evidence.The pinned-precondition quirk (a pinned Wizard needs the 0.18.2 overlay) is unchanged and remains recorded.