scripts/release-after-suite.mjs runs the release-checks suite and then the
release action (npm publish, or the Python sdist and wheel build that the PyPI
step uploads) from one process, and releases only if the suite passed. No step
condition can release what the suite did not pass, so the pin that read if:
conditions (status functions, multi-line if:, the leading-conjunct rule) is
deleted with its tests and docs. What remains compares each job's release steps
with their expected text exactly, less their if: line, and refuses
continue-on-error, shell and defaults in the workflow.
Ruling asura:ruling:suite-gate-structural-not-parsed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Soul s2 found the CultMath bytes follow the checkout's line endings (an LF clone
built 53084D94, not the tracked 6781BF20) and its path when no .git maps the root
to /_/. .gitattributes pins packages/cultmath/src/** to eol=crlf, which the
tracked DLL was built from, so no re-release. The build script refuses up front
without .git, and the refusal and docs name line endings beside source and
toolchain.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Soul s2 found 'success() || c' and plain or quoted if: values continued on a
following line passing the pin. Any status function now refuses, and stepCondition
reports an if: whose value continues (block scalar or a deeper-indented next line)
as multi-line, which the pin refuses. Soul's four probe forms are asserted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Publish if: calling always(), cancelled() or failure() runs after the suite failed, the
continue-on-error bypass by another name; a block-scalar if: was compared by its indicator, so
'>-' equalled '>-' whatever followed. Both are now refused. The third refusal no longer calls
sound conditions narrower: it names the three accepted shapes, and the code comment and
docs/semver-policy.md list the sound forms textual matching refuses and why.
(Soul findings cut-3-gate.s1.status-function-bypass, block-scalar-if-compared-as-text,
pin-refusal-cost-undocumented.)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Unchanged CultMath source built on another SDK or host gives other bytes (Linux sdk:10.0:
db2a11cc against tracked 6781bf20), so the refusal no longer sends the operator to release a
CultMath with no change (Soul finding cut-3-gate.s1.toolchain-drift-named-as-source-change).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Directory.Build.props puts CultMath's obj at obj\packages\cultmath\src\CultMath, which the
obj\src-only clean left in place, so an old-mtime CultMath source change could reuse a stale
CultMath.dll and pass the byte gate (Soul finding cut-3-gate.s1.cultmath-obj-not-cleared).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The suite step's if: is absent, equal to Publish's, or a leading conjunct of
a Publish condition that has no ||. A disabled or narrowed suite step fails
the pin. Closes asura:follow_up:suite-step-condition-pin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The declared org.gamecult.cultmath dependency must equal the CultMath package
version (-ne, not -gt), and every CultMath.dll a managed publish produced must
equal the DLL that package tracks. The type-name check and its helper,
scripts/check-cultmath-types.cs, are gone: the byte gate subsumes them.
$managedPublishes is the single owner of publish-root identity for the clean
step, the publish loop, $publishedByName, the byte gate and --api-refs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release check measures each package against its predecessor tag instead of
trusting caller-declared flags. First releases are proved by a managed assembly,
the suite runs in CI and the Unity scripts before publish, and the Caching Unity
prefix is its own tag family. Verdict asura:verdict:cut-semver-measured.s7 holds;
one Low finding (suite-step-condition-unpinned) is deferred.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
publish-packages.yml runs the suite in both jobs, after .NET setup on a full-depth
checkout and before any check or publish step; the three Unity release scripts run
it before the checker. A test reads each file and fails when the step is removed,
moved, or made non-fatal. The Caching Unity pin now needs a prefix declared once
whose exact tags hold the package's own manifest at the tag's version. No NUL byte
in the checker is a test. The policy records that releases run from a full clone.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Resolves Soul's five findings on cut-interval-ops.h2 and carries the rulings
operator-wells-contract-vs-ceiling and operator-analytic-wall-body. glsl-lowering
r2 and site-ground r3 now depend on interval-ops r3; the site-ground spec names
the one shipped void with (Rc, e) derived from (Rh, S) and the body-start word.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Also defines the PE fixture before the tests that use it, so a filtered run no
longer reaches it before initialization.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Monorepo snapshot tags track every package's directory, so tracking a file
proved nothing about a package's own releases. A package with an assemblies
directory is a first release only when no tag under any prefix tracks a managed
assembly there (decided by PE bytes, once per blob). Assembly-less packages are
a first release when no tag of their own prefix exists; their prefix is pinned
by the suite test tying each declared prefix to a workflow trigger or an
existing tag, which now fails on a typo for every assembly-less package.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The changelog-heading guard missed 12 of 17 heading shapes and a first changelog
entry. It and its parsing are deleted. A release with no same-prefix baseline is
a first release only when no tag in the repository, under any prefix, tracks a
file under the package's folder (declared assemblies dir, else the changelog's
directory); otherwise it refuses naming the tag. A tag whose tree cannot be read
refuses. Tests pin the mistyped prefix for CultMath 0.3.1, cultlib 1.0.61 and a
Python package, a genuine first release, the moved-folder choice, and an
unreadable ancestry and tree.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The previous release is chosen by version order among same-prefix tags strictly older than the version, and must be an ancestor of HEAD, so a later backport on another branch never moves a rebuild's predecessor. A release with no previous tag is refused when the changelog already lists an earlier version, so a mistyped prefix cannot make an unmeasured first release. The declaration is validated as a whole: two packages sharing a prefix, or an entry without a string tagPrefix and changelog, refuse.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
One owner per store decision per runtime (header, existence and links, zero-byte,
directory at path, lock, replace, soft write), with pinning tests and open gaps by
follow-up id. Written by a Modeling pass against 705ab669.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The checker reads each package's tag prefix, changelog and assemblies directory
from scripts/release-packages.mjs and derives the release record from git tags.
A first release is the absence of any older tag in a checkout that holds other
tags; a malformed same-prefix tag, a checkout without tags and an unreadable
repository refuse. The measured set is every managed assembly (CLI header in
the PE bytes) tracked at the previous tag at any depth; an unbuilt one is a
break, a built assembly with no namesake is an addition.
Deleted with their branches, refusals and tests: --first-release, --api-new,
--tag-prefix, --changelog, --api-baseline-path and the workflow first-release
decision line. Any unknown option is now a usage error.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Every assembly the previous tag tracks that the build does not hand over is a break, whatever its name; a run that compared nothing is refused (the --api-new rename of a lone assembly). The cultlib build now hands over every shipped assembly. --first-release is believed only with no other same-prefix tag and the prefix its changelog directory names. git ls-tree/show failures and an unreadable changelog become refusals. Tests pin the CultMath-shaped rename, the left-reference scenario (a dependency's netstandard base chain changes), the first-release probes and the workflow's own first-release line.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The march is footprint-aware: step = max(k z theta_px, min(S/4, lambda_fine/2)),
one smooth weight per octave, the bound enclosing the truncated field. The
cavity cost model is a grid, not a number; the shipped point needs about 6
steps and 12 snoise per pixel against about 35 fixed steps.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Ruling operator-void-true-cavity: the void is a 3D hollow in a cloud volume,
not the 2021 bowl. The outer volume is an unbounded fill so every ray ends in
a wall; Rc grows to 640 so the hollow (198) holds the camera at 186. With no
sky the evaluation ratio for the shipped scene is predicted 1.0-1.2x; the
pre-pass's gain there is sample placement (2.0-2.6x), raised as Q8.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Ruling operator-ground-void-brush answers Q6 outside the options. The
original main menu's brush, floor, sun, orbit, camera follow, authored light
and stardust rule are read from Aetheria at e6181c11 and carried in their
units; the lighting is the original's analytic pulse made 3D; the TAA
reprojects by camera and flow; the saving test gains the void scenario and
asserts 2x on it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Revision 2 specs for the two CultLib cuts of cultmath-tapes, as follow-ups on
hands/cultmath-interval-ops (c9bd003b) and hands/cultmath-glsl-lowering
(5ae207e8), under the rulings operator-tile-amortized-march,
operator-split-phacelle, operator-compiler-downloads and
self-exp-measure-in-site, and the operator's challenge to the march.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The ApiCompat tool runs from scripts/api-gate, so a relative --api-built or --api-refs
failed as an unreadable assembly. The release scripts pass absolute paths; any other
caller does not have to.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A malformed --version fell into the tag-reading catch and was reported as unreadable
tags. It is now validated first and refused without repeating the value. A canary test
runs seven refusals (measured break, unreadable built DLL, unreadable baseline blob,
missing entry, skipped version, breaking under too small a bump) with a canary in the
changelog and the assemblies and asserts it never appears in the output.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- A missing or moved baseline path, a previous tag that does not track the DLLs, and a built DLL
with no namesake at the tag (unless declared with --api-new) refuse, naming what is missing.
- First release is declared with --first-release, never inferred: no previous tag, or tags that
cannot be read, refuse without it.
- The "already published" skip is removed; a local tag of the released version exempts nothing.
- ApiCompat and the pinned NETStandard.Library.Ref 2.1.0 live in scripts/api-gate and are restored
there, so the root manifest (dotnet-stryker) is no longer needed by a release. Both sides resolve
netstandard through the reference assemblies.
- Tests: refusals, netstandard false breaks, cross-assembly references, restore diagnostics.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Folds in the operator's rulings: Q1 cultmath-tapes, Q2 samples then
resolution, Q3 the shader owns a dynamic ground and the CSS wash is sampled
from its result. The nebula is flow-warped (two-phase flow map) with one
flow texture owning motion for the warp, the TAA motion vectors, the hue and
the stardust. Interval culling encloses the warp by enlarging the ball;
interval-ops gains that test. New fourth cut site-stardust: stateless
instanced particles plus an opacity-driven gather on the stardust layer, the
web form of the raymarch-driven DoF. Budget re-checked: the full stack lands
a mid-range phone at S = 4-6, not 8. Docs only.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Three cuts under a proposed cultmath-tapes campaign: a textual HLSL -> GLSL
lowering pinned by test, interval ops with enclosure tests and a committed
Lipschitz constant for snoise, and the site's per-pixel interval-culled,
TAA-accumulated cloud ground driven by body tokens with the CSS wash as the
fallback. Docs only.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The checker now runs with the target repo as its working directory in tests,
so the tool manifest is found from the script's own location as it is in the
release scripts. Adds tests for usage errors, a missing changelog, backslash
and trailing-slash baseline paths, temp-file cleanup, a restore failure and a
missing dotnet failing closed, the five-line failure excerpt and the
five-diagnostic cap. Drops two unreachable defaults and an unreachable
spawn-error branch from the checker.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The check moves from before the build to once the assemblies under judgement
exist, and receives every shipped GameCult.* DLL (cultlib) or the fresh
CultMath.dll with the baseline path of the previous tag's tracked plugins.
The early calls are deleted; each script keeps exactly one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>