Composes the FS.GG components into a ready-to-run workspace: the FS.GG.SDD spec-driven lifecycle, a runnable FS.GG.Rendering app, and FS.GG.Governance config.
From 0.8.0 the package also carries four first-class workspace identities — fs-gg-console,
fs-gg-web, fs-gg-fable-bindings and fs-gg-fable-game — each with its own provider descriptor
under providers/ and its own end-to-end composition lane. See
Release notes for what each one is, the minimum SDD/wizard versions, and the
package-id rename that release carries.
Acquire or update the template package through the standard dotnet new flow:
dotnet new install FS.GG.Workspace.Template
dotnet new updateComing from
FS.GG.Templates(0.7.1 or earlier)? The package id changed in 0.8.0, anddotnet new updatecannot cross a rename — rundotnet new uninstall FS.GG.Templatesonce first. See Upgrade behaviour.
Use the packaged fs-gg-governance overlay with an existing SDD-managed workspace:
dotnet new fs-gg-governance -o ./MyApp --appName MyApp --defaultProfile lightFS.GG.Workspace.Template is the thin governance/composition package; it does not vendor the
Rendering runtime or the SDD CLI. Full-stack workspaces are created through fsgg-sdd scaffold as shown below. The rendering provider pins a compatible
FS.GG.UI.Template release, while dotnet new update keeps this independently
versioned package current.
Platform vs. workspace. FS-GG is a platform of independently-owned components; Templates is the composition component of it. What you scaffold with the platform is a workspace: a generated repo with a runnable app, the
.fsgg/lifecycle, skills, and optional governance. For the platform vocabulary and the live component inventory see the vocabulary (ADR-0020) anddocs/architecture.md.
Per ADR-0002,
composition happens at scaffold time — fsgg-sdd scaffold installs and drives the
live, version-pinned upstream template; FS.GG.Templates is the thin composition +
registry layer (a provider descriptor, a populated governance overlay, and these
composition tests), not a fork host. This repo ships no vendored framework copy.
Drive the FS.GG.SDD CLI (fsgg-sdd, a dotnet tool)
with the rendering provider from this repo. Each component stays decoupled and
independently owned; the scaffold just glues them:
# 1. Register the rendering provider in your project (copy or merge the descriptor).
mkdir -p ./MyApp/.fsgg
cp providers/rendering.providers.yml ./MyApp/.fsgg/providers.yml
# 2. Selected lifecycle + the live FS.GG.Rendering app (omitted lifecycle defaults to sdd).
fsgg-sdd scaffold --root ./MyApp --provider rendering --param productName=MyApp
# 3. Activate Governance: drop the populated reference gate set into the project.
dotnet new install ./templates/fs-gg-governance
dotnet new fs-gg-governance -o ./MyApp --appName MyApp --defaultProfile light
cd ./MyApp && dotnet build && dotnet run # the runnable Skia/Elmish appFor the common case, the new-sdd-workspace <target> <product>
dotnet tool (in FS-GG/.github: dotnet tool install --global FS.GG.NewSddWorkspace) wraps these three
steps with no FS.GG.Templates checkout — it fetches the provider-pinned descriptor over the network.
Run the three steps above by hand only when working from a Templates checkout (e.g. testing an unpublished
Rendering build via the local feed / dev-repack-ui-feed.sh).
It produces:
- Rendering — the FS.GG.Rendering
fs-gg-uiapp (Skia/OpenGL, Elmish/MVU, Scene, SkiaViewer, Controls), installed live from the publishedFS.GG.UI.Templatepackage pinned by the provider (currentlyFS.GG.UI.Template@0.32.1, behind the immutable tagfs-gg-ui-template/v0.32.1). Every provider acceptsnone,sdd, andtyped-sdd; omission resolves tosdd. Product templates emit only product files — lifecycle artifacts always come from FS.GG.SDD, never a second template-owned copy. - SDD — the lifecycle skeleton:
.fsgg/project.yml,.fsgg/sdd.yml,.fsgg/agents.yml,work/,readiness/(drive it withfsgg-sdd charter …). - Governance — the populated reference gate set from the immutable
FS.GG.Governance.ReferenceGateSetauthority pinned intemplates/fs-gg-governance/.template.config/reference-gate-set.json:.fsgg/policy.yml,.fsgg/capabilities.yml(build/test/evidence plus the command-freegameplay:fr-coveredandgameplay:production-journeyorganization floors),.fsgg/tooling.yml, and the controlled-import verifier/manifest. The package'sschema-manifest.jsonis emitted beside.fsgg/.--defaultProfilesets the default profile;lightis the non-blocking inner-loop posture, whilestrict/releaseenforce block-on-ship gates.
dotnet new cannot include or depend on another template, so a one-invocation
"full-stack" template could only exist by vendoring a copy of the rendering payload —
a fork that goes stale when Rendering changes (this is exactly the FsGgUiVersion
staleness class that broke the old monolith). Composing at scaffold time installs the
pinned upstream package directly, so there is no fork to drift. See docs/design.md and
the architecture report.
With the monolith gone, the only thing that can go stale is the single
FS.GG.UI.Template version pin in providers/rendering.providers.yml (mirrored in this
README; the composition test asserts the two agree). The retired sync-from-rendering.sh
re-vendored a payload by hand; its successors only move that pin:
- Renovate — a custom manager tracks the pin against the
nugetdatasource and opens a groupedFS.GG.UI.*(rangeStrategy: bump) PR when Rendering publishes a newerFS.GG.UI.Template. The always-on path. upstream-bumpworkflow —repository_dispatch(fs-gg-ui-template-released) lets Rendering push a bump on a release tag;workflow_dispatchre-pins by hand. Both open a PR.scripts/bump-rendering-pin.sh <version>— the shared, human-runnable primitive both lean on; updates every coherence surface in one shot.
The fs-gg-governance overlay drops the populated FS.GG reference gate set into any
existing SDD-managed workspace:
dotnet new install ./templates/fs-gg-governance
dotnet new fs-gg-governance -o ./MyApp --appName MyApp --defaultProfile lighttests/composition/run.sh runs the standard packaging-repo checks
(pack → install → instantiate → build → verify pins/links):
tests/composition/run.sh # owned stages run fully; full scaffold/build is gated
FSGG_COMPOSITION_FULL=1 tests/composition/run.sh # require the fsgg-sdd scaffold+build stage
COMPOSITION_LANES="console web fable-bindings fable-game" tests/composition/run.sh # every identity
FSGG_TEMPLATES_NUPKG=./artifacts/FS.GG.Workspace.Template.<ver>.nupkg tests/composition/run.shCOMPOSITION_LANES selects which per-identity lanes (tests/composition/<lane>/run.sh) run.
It defaults to web fable-bindings — the pair the required composition check is measured to fit
inside its timeout-minutes: 30. The release gate sets all four, because "all four identities
install and instantiate through the packed artifact" is the release's acceptance and that job
carries no 30-minute budget. Whether the required check's default should grow, and what it costs,
is owned by #379. A lane named in
COMPOSITION_LANES whose script is absent is a hard failure — named lanes never skip — and lanes
that exist but were not selected are printed by name, so a reader can always see which identities a
given run did and did not exercise.
FSGG_TEMPLATES_NUPKG points every stage and every lane at one prebuilt archive instead of
packing from the checkout. This is what makes the release gate meaningful: it runs against the
downloaded, checksum-verified bytes that publish then sends to both feeds. If the variable names
a path that does not exist the run fails — it never quietly packs a substitute, because a gate
that reports on an archive nobody ships is worse than no gate.
It packs FS.GG.Workspace.Template, installs it, instantiates the fs-gg-governance overlay, and
asserts the pins/links: parameter substitution lands, the governance gate set is
populated (not the inert checks: []/commands: [] it used to ship), both gameplay
floors remain command-free, controlled-import/schema payloads execute and materialize, the
committed overlay matches its exact published authority with only declared template transforms, and the
rendering provider pin is internally coherent (version tag + lifecycle=sdd /
profile=game). The full scaffold + dotnet build of the live rendering app needs the
fsgg-sdd CLI and a reachable template feed; that stage runs when they are available and
otherwise skips with a reason (it never green-passes by omission).
In both composition lanes — orchestrated (fsgg-sdd scaffold) and standalone (direct
dotnet new fs-gg-ui, spec-kit) — the gate asserts the skill-union invariant (ADR-0014,
issue #49): the two agent-skill roots (.claude/.agents skills/) are the
byte-identical union of process + product skills (via the reusable FS-GG/.github
skill-union-assert.sh), every materialized manifest-declared skill matches its
canonical-body sha256, and nothing undeclared ships (dangling fails).
That shared script is fetched at a pinned FS-GG/.github commit SHA (SKILL_ASSERT_REF
in tests/composition/lib/skill-union.sh), never @main (issue #56): a full-SHA raw fetch is content-addressed, so the
gate is both deterministic (its semantics can't change under this repo without a reviewable
pin bump) and integrity-checked (GitHub can't serve different bytes for a SHA — no separate
content hash needed). Renovate moves the pin against the main head like the FS.GG.UI.*
pin. The gate also alarms on a frozen pin (#315): before any stage runs it resolves that
commit's date and reds if it is older than the threshold in lib/skill-union.sh, so a pin that
stops moving can no longer ride along under a green tick.
CI runbook note: this couples the gate to two distinct network dependencies, and they fail independently — an egress allowlist routinely permits one and blocks the other, and GitHub tracks them separately on its status page:
raw.githubusercontent.comat the pinned SHA — fetching the sharedskill-union-assert.shitself.github.comgit-over-HTTPS —git fetch --depth 1of that one commit, to read its committer date for the staleness alarm. (Deliberately notapi.github.com, whose unauthenticated 60/hour/IP budget is shared: a required check that reds because someone else spent it would be a worse outage than the staleness it watches for.)
Either being unreachable — or an offline host with no sibling ../.github clone at the ref —
fails the lane by design; it never green-passes unverified. The same escape hatch covers
both: git clone https://github.com/FS-GG/.github ../.github makes the whole thing offline.
Both dotnet and git are hard prerequisites the runner preflights, exiting 2 without them.
On a provisioned container the full path needs no extra setup. ~/.nuget/NuGet/NuGet.Config
binds FS.GG.* to the published FS.GG org feed (packageSourceMapping), and the container
entrypoint floats fsgg-sdd / fsgg-governance to the latest published version on every
start. The scaffold then resolves FS.GG.UI.Template::<pin> and the coherent FS.GG.UI.*
set straight from the org feed:
FSGG_COMPOSITION_FULL=1 tests/composition/run.sh # full scaffold/build + skill-union (both lanes) + enforcement(The run prints its own pass total on its == summary == line; no count is transcribed here.
This one had already rotted twice — #75 corrected 45/45 to 47/47, and #321 found 47/47
against an actual 76. See tests/composition/README.md.)
The org feed is private, so the full composition lane needs a GitHub token with
read:packages (baked into the
container's NuGet config — %GH_TOKEN%, read at restore time, never stored in an image
layer). Absent it the gated stages skip with a reason rather than green-passing. Because
FS.GG.* is pinned to the org feed, a stale local snapshot can never shadow the published
CLIs — that was the old drift class, and the source mapping closes it structurally.
The governance-overlay drift gate independently downloads its exact public nuget.org pin
and verifies the recorded archive digest, so it never follows a mutable latest version.
To test an unpublished local FS.GG.Rendering build before it reaches the org feed, use
scripts/dev-repack-ui-feed.sh (repacks the pinned FS.GG.UI.* set from a Rendering checkout
into the local cache; you then map FS.GG.UI.* to that cache in NuGet.Config so the test
consults it). It is a dev convenience, not part of provisioning, and per ADR-0002 it is not
a republish — the FS.GG.UI.* family already ships as one locked set behind
fs-gg-ui-template/v<ver>.
The generic Fable product skills — fable-project, fable-interop, fable-http-codecs,
fable-signalr, fable-testing, fable-bindings — are authored once, under
template/product-skills/, and projected into each provider template's packed
.agents/skills/ payload by package items in FS.GG.Templates.csproj. Nothing is copied into
templates/ in the working tree: there is one authored file per skill and no second file that can
drift. Which templates a skill lands in is declared by its materializes-when row in the producer
manifest template/skill-manifest/skill-manifest.json, which ships into every such product as
.agents/skills/skill-manifest.json and carries each skill's canonical-body sha256.
scripts/generate-skill-manifest.fsx owns all of it and has three arms:
| arm | what it grades |
|---|---|
| (no flag) | regenerates the manifest from the catalog |
--check |
the catalog, the checked-in manifest, and the csproj package items still agree |
--assert-product <dir> --template <id> |
a product instantiated from the packed archive received exactly the declared set — reds on an absent selected skill, a skill the manifest does not select for that template, an undeclared (dangling) skill directory, a drifted digest, a missing producer manifest, or one whose rows are not this catalog's |
Add --co-tenants "<glob> …" once another producer has written into the same root — after
fsgg-sdd scaffold or the governance overlay, .agents/skills/ also holds SDD's fs-gg-sdd-*
process skills and the five always .github driver skills. They are another producer's correct
output, so the producer manifest under template/ must not declare them; the glob list keeps
them legitimate while a skill belonging to nobody still reds. The globs are passed per call site
because which co-tenants to expect is a fact about the lane, not about this catalog.
A product's own .agents/skills/skill-manifest.json is a different file from the producer manifest,
and the product owns it (FS.GG.Templates#385). It is a shared, multi-producer, upper-bound
catalog: fsgg-sdd scaffold appends rows to it for the driver and product skills it seeds, and the
org-wide skill-union assertion already grades it under those set semantics. So
--assert-product requires this catalog's rows to appear in it field for field — exactly the
fields this catalog declares, same values, none missing and none added. Another "scope": "product"
row is foreign only when it carries a valid supplier path outside this producer's
template/product-skills root and descendants; public SDD 1.2.5 preserves that attribution when it adds
Rendering-owned rows. An unattributed/malformed row, or an unknown row claiming this producer's
namespace, is refused rather than guessed to be somebody else's, and every row must still carry a
scope. The assertion does not require the file to be byte-identical to the producer's copy,
which no product scaffolded
through a provider could ever satisfy. Explicitly supplier-attributed rows from another producer
are still graded for delivery; they are simply not required to match this catalog.
The product-side arm is the load-bearing one, and the reason it exists is worth keeping: the
catalog originally shipped in a tree no package item referenced. Every source-side check was green,
CI was green, and no generated product could receive a single declared skill — a source-side
check grades a repository file, and only instantiating the archive grades delivery. Both arms run
on the required composition job; fs-gg-fable-bindings is additionally asserted inside its own
lane, on the same product that then goes through npm/Fable/Node/Chromium/SDD/Governance.
The templates ship as a versioned NuGet template package, so the standard dotnet new
update path applies:
dotnet new install FS.GG.Workspace.Template # from the org feed
# or from a local pack: dotnet new install ./artifacts/FS.GG.Workspace.Template.<version>.nupkg
dotnet new update # upgrade to the latest published version
dotnet new update --check-only # see what would updateThe package is published by .github/workflows/release.yml, tag-driven and symmetric with
Rendering's fs-gg-ui-template/v<ver> flow — Templates publishes behind
fs-gg-templates/v<ver>. To cut a release, bump <Version> in FS.GG.Templates.csproj,
then push a matching tag:
git tag "fs-gg-templates/v<version>" && git push origin "fs-gg-templates/v<version>"Three jobs, and the split is the point — the archive is packed exactly once:
packasserts the tag version equals<Version>, reads<PackageId>, packs once,sha256sums that one archive intoSHA256SUMS, and uploads both as an immutable workflow artifact. It also asserts thatdotnet packproduced exactly the<PackageId>.<Version>.nupkgit derived — the workflow used to hard-code the project file's stem as if it were the package id, which stopped matching any file the moment<PackageId>becameFS.GG.Workspace.Template(#349).gatedownloads that artifact, re-verifies the checksum, and runstests/composition/run.shagainst those exact bytes (FSGG_TEMPLATES_NUPKG) withCOMPOSITION_LANESnaming all four workspace identities — so every identity is proved on the archive that is about to be published, not on a second one packed from the checkout.publishindependently downloads and re-verifies the same artifact, pushes the byte-identical file to the org feed (nuget.pkg.github.com/FS-GG) and to public nuget.org (ADR-0012 dual-publish, ADR-0013 Trusted-Publishing OIDC, gated onvars.NUGET_ORG_PUBLISH), then cuts the GitHub Release with the same archive attached.
Fail-closed throughout: a red gate or a version/id mismatch never reaches publish. This is the
producer side of the org publish-before-flip dance — the package is LIVE on both feeds before
any downstream registry/pin flip advertises it.
The explicitly selected svgFoundation profile now composes the public Rendering 0.31.0, Game 0.16.0, Net 0.6.0 and Audio 0.6.0 releases. It includes replay/rules analysis in the optional Studio, authoritative two-client reconnect/review, and bounded large-world scale behavior. The ordinary Player build remains free of Studio and replay-analysis code, and the default generated game remains unchanged.
The opt-in fs-gg-fable-game --svgFoundation true payload now carries the complete authoring,
input, fixed-step runtime, animation, browser-audio, save, and browser-storage composition. It pins
Rendering 0.30.0, Game 0.15.0, and Audio 0.6.0 and keeps the player bundle isolated from Studio,
geometry-worker, native rendering, and native audio modules. All four workspace provider descriptors
self-pin FS.GG.Workspace.Template::0.12.0; the ordinary arena and lifecycle defaults are unchanged.
The fs-gg-fable-game identity can now add the SVG game foundation with
--svgFoundation true. The opt-in path uses the public Rendering 0.29.0 package graph and is
qualified through fresh, retained-upgrade, browser, and typed-SDD receiver routes. The default
template output remains unchanged. All four workspace provider descriptors self-pin
FS.GG.Workspace.Template::0.11.0.
The fs-gg-fable-game identity now installs the accessible browser baseline merged in #417:
semantic controls and status output, keyboard-reachable play controls, deterministic focus and
reload behavior, and the two-client Playwright route that exercises those interactions. The
package id and all five template identities remain unchanged. The four workspace provider
descriptors self-pin FS.GG.Workspace.Template::0.10.0; external Game, Rendering, SDD, and npm
pins remain unchanged.
Every supported provider and profile accepts explicit none, sdd, and typed-sdd, while
omission remains equivalent to sdd. FS.GG.SDD.Cli owns Standard and Typed SDD artifacts;
the four workspace templates accept the choice only as orchestration metadata. Rendering is pinned
to FS.GG.UI.Template 0.28.0 and the coherent orchestrator floor is 1.4.0-preview.1.
The package id changed: FS.GG.Templates → FS.GG.Workspace.Template. Read the upgrade
note below before bumping; dotnet new update does not cross a package-id rename.
| identity | template id | provider descriptor | what it is |
|---|---|---|---|
| console | fs-gg-console |
providers/console.providers.yml |
production-shaped F# console workspace: build.fsx build/test, exit-code and cancellation seams, no npm lane at all. |
| web | fs-gg-web |
providers/web.providers.yml |
neutral F# ASP.NET Core + TypeScript workspace: server, Vite/TS front end, Vitest unit tests, Playwright browser smoke, build.sh publish with TRX/JUnit evidence. |
| fable-bindings | fs-gg-fable-bindings |
providers/fable-bindings.providers.yml |
Fable binding-library workspace parameterized over npmPackage/npmVersion/bindingTarget: packs a NuGet library, locks its TypeScript-declaration closure, and reviews declaration drift. |
| fable-game | fs-gg-fable-game |
providers/fable-game.providers.yml |
server-authoritative Fable game workspace over the published FS.GG.Game.Core Fable lockstep profile, with a Playwright two-client scenario and a cross-runtime codec proof. |
| governance (unchanged) | fs-gg-governance |
— | the populated Governance reference-gate-set overlay for an existing SDD workspace. |
| rendering (unchanged) | fs-gg-ui |
providers/rendering.providers.yml |
the Skia/Elmish app, installed live from FS.GG.UI.Template (this package ships no copy of it). |
Owner-sourced product skills. The Fable identities ship the generic Fable product skills —
fable-project, fable-interop, fable-http-codecs, fable-signalr, fable-testing,
fable-bindings — projected into each template's packed .agents/skills/ payload with the
producer manifest that digests them (see Owner-sourced product skills above). fs-gg-fable-game
receives five, fs-gg-fable-bindings four; each row's materializes-when in
template/skill-manifest/skill-manifest.json is the authority.
Game Skills are a different producer, and reach a different identity. The FS.GG.Game.Skills
rows (fs-gg-game-fable, fs-gg-game-core, …) are owner-sourced by FS.GG.Game and materialized by
fsgg-sdd itself, which embeds the pinned package as assembly resources at its own build time. They
gate on materializes-when: profile in [game, sample-pack], so they reach the rendering
identity — whose profile defaults to game — and not fs-gg-fable-game, which has no
profile parameter at all. That split is deliberate (#264: "game skills reach a game scaffold via
owner-sourcing, so FS.GG.Templates gains no game.providers.yml"); the Fable identities' own
owner-sourced skills are the fable-* rows above.
Which release arrives is upstream's to pin and is not frozen here — this repository floats
fsgg-sdd to latest stable by design (#317). The composition suite instead asserts that the
materializer delivered a non-empty set containing fs-gg-game-fable, then resolves by content which
published release those bytes are and prints it into the run log and step summary
(tests/composition/lib/game-skill-release.sh). Measured for this release: FS.GG.Game.Skills
0.7.0, delivered by fsgg-sdd 1.0.0 — 11 rows, every body byte-identical to 0.7.0. That is one
release behind the published 0.8.0, whose only content difference is fs-gg-mapcraft;
fs-gg-game-fable is byte-identical across both, so nothing this release ships is affected.
Minimum versions.
| component | minimum | where it is declared |
|---|---|---|
fsgg-sdd (FS.GG.SDD.Cli) |
1.4.0-preview.1 | minimumFsggSdd in every provider descriptor under providers/ |
new-sdd-workspace (FS.GG.NewSddWorkspace, the no-checkout wizard) |
0.10.0 | the first release carrying the Typed SDD workspace contract |
fsgg-governance (FS.GG.Governance.Cli) |
1.5.0 ReferenceGateSet authority | templates/fs-gg-governance/.template.config/reference-gate-set.json |
| .NET SDK | 10.0 | global.json in each generated workspace |
Compatibility. The scaffold-provider contract stays at 1.1.0 — lifecycle is an existing
value-preserving provider parameter, so an SDD at or above the 1.4.0-preview.1 floor resolves all
three lanes without a descriptor schema change. Generated workspaces
are unaffected by this release: composition happens at scaffold time (ADR-0002), so an already
scaffolded product keeps the payload it was created with until it is re-scaffolded. The rendering
and fs-gg-governance identities are byte-unchanged from 0.7.1 apart from the package they arrive in.
Upgrade behaviour — the package-id rename needs one manual step.
dotnet new update upgrades a package within an id; it has no way to know that
FS.GG.Workspace.Template succeeds FS.GG.Templates. A consumer sitting on FS.GG.Templates
0.7.1 will therefore keep reporting itself up to date forever. Uninstall the old id once:
dotnet new uninstall FS.GG.Templates # the pre-0.8.0 id; skip if never installed
dotnet new install FS.GG.Workspace.Template # the id from 0.8.0 onward
dotnet new update # normal updates resume from hereFS.GG.Templates 0.2.0–0.7.1 stay published and installable on both feeds; they are not unlisted,
and nothing that already depends on them breaks. New work should pin the new id. Anything that
pins the package by name — a provider descriptor's source:, a NuGet.Config mapping, a
scaffolding script — needs the same one-line change; the descriptors in providers/ already carry it.
| Path | What |
|---|---|
providers/rendering.providers.yml |
the SDD scaffold-provider descriptor, pinned to FS.GG.UI.Template and exposing none / sdd / typed-sdd (sdd by default). |
providers/console.providers.yml, web.providers.yml, fable-bindings.providers.yml, fable-game.providers.yml |
the four workspace-identity descriptors, each pinned to this package's own published FS.GG.Workspace.Template::<ver>. |
templates/fs-gg-governance/ |
the populated Governance-config overlay (fs-gg-governance). |
templates/fs-gg-console/, fs-gg-web/, fs-gg-fable-bindings/, fs-gg-fable-game/ |
the four packaged workspace identities. |
template/product-skills/, template/skill-manifest/ |
the owner-sourced generic Fable product skills and their producer manifest, projected into each template's packed .agents/skills/ payload. |
tests/composition/run.sh |
end-to-end composition test (pack→install→instantiate→build→verify pins/links) plus the per-identity lanes selected by COMPOSITION_LANES. |
tests/composition/<identity>/run.sh |
one isolated full-lifecycle lane per identity. |
tests/composition/lib/lane-package.sh |
resolves the archive a lane installs — FSGG_TEMPLATES_NUPKG when the caller supplied one, otherwise a fresh pack — and repoints a copied provider descriptor's source: pin at it. |
scripts/dev-repack-ui-feed.sh |
DEV-ONLY: repacks the pinned FS.GG.UI.* set from a local FS.GG.Rendering checkout into the local cache, for testing an unpublished UI build before it reaches the org feed. The CLIs and the published UI set come from the org feed (container provisioning), not this script. |
scripts/bump-rendering-pin.sh |
re-pins FS.GG.UI.Template coherently across provider + README (successor to the retired sync-from-rendering.sh). |
.github/renovate.json |
Renovate config that bumps the FS.GG.UI.* pin and the pinned FS-GG/.github skill-union-assert.sh ref (issue #56) automatically. |
.github/workflows/upstream-bump.yml |
repository_dispatch/workflow_dispatch auto-PR that re-pins on an upstream release. |
.github/workflows/release.yml |
tag-driven (fs-gg-templates/v*) publish: gate (composition + version⇔tag assert) → pack → push to the org feed → GitHub Release. |
FS.GG.Templates.csproj |
packs the templates into the updatable NuGet package. |
docs/design.md |
the composition-vs-monolith rationale (why the vendored monolith was retired). |
MIT.