Skip to content

feat!: SYS-440 move the frontend stack here as its own repository - #7

Merged
kiro-systemf[bot] merged 10 commits into
mainfrom
sys-440-frontend-sovereignty
Oct 22, 2026
Merged

kiro-systemf[bot] merged 10 commits into
mainfrom
sys-440-frontend-sovereignty

Conversation

@systemfsoftware-maker

@systemfsoftware-maker systemfsoftware-maker commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Fixes SYS-440

systemfsoftware/frontend now owns the frontend stack. The UI packages, their compound packs and the UI lint rules move here from systemfsoftware/systemfsoftware. The generic toolchain stays there and comes in as pinned tarballs through its flake.

What moved

Copied with git archive from systemfsoftware/systemfsoftware main at d1ab631935c9439bcd16abf2894b09b843494701. Files changed by PR #763 (head c08bc10b4005a8fc70d84d0f49e5de26232136d7) are taken from #763's head. #763's docs/plans/*.md are not carried, and neither is anything from #751.

Source Here Notes
packages/atom/effect-atom same path @systemfsoftware/effect-atom 6.0.0, name and version unchanged
packages/atom/effect-atom-react same path @systemfsoftware/effect-atom-react 2.0.0, with #763's useSyncExternalStore rewrite; useAtomSubscribe leaves the public API
packages/gherkin/storybook-gherkin same path @systemfsoftware/storybook-gherkin 5.0.0, unchanged
compound-packs/ui-state, compound-packs/storybook-testing same paths ui-state carries #763's react-runs-no-effect.md and README
UI rules in oxlint-config-recommended and no-react-effect in oxlint-plugin-effect-platform packages/oxlint-presets/oxlint-config-frontend new @systemfsoftware/oxlint-config-frontend 0.1.0

Every moved file matches its source byte for byte (CR stripped), except for these edits:

  • Manifests: repository, homepage and bugs point at this repo. Every dependency on systemfsoftware packages becomes a version range backed by a .sfs-deps tarball instead of workspace:. Each package's lint preset becomes @systemfsoftware/oxlint-config-frontend (workspace:^). The two exact "playwright": "1.64.0" pins become catalog: (1.63.0, the version the Nix browsers provide).
  • Three oxlint.config.ts files import the new preset.
  • Five pack Lint: lines name the new preset.
  • Rule ID: @systemfsoftware/effect-platform/no-react-effect becomes @systemfsoftware/ui-state/no-react-effect in the moved rule, its config, tests and directive fixtures.

The new preset

@systemfsoftware/oxlint-config-frontend spreads the default export of the pinned generic @systemfsoftware/oxlint-config-recommended 4.0.0. It then:

  • enables the React plugin and #763's React rules;
  • loads no-react-effect as a local JS plugin (dist/plugin.mjs);
  • rebuilds no-restricted-imports at the root and in every inherited override, so the server-state and React import bans can't be dropped by a later override;
  • re-adds the .tsx fetch ban and the story page.screenshot ban.

Nothing is removed from the generic preset here; that removal is a separate lane. The moved tests come along unchanged apart from the rule-ID and import-path edits: fetch-in-tsx, server-state-imports, story-screenshot, react-effect, react-rules, no-react-effect, and the ui-state-fixture/ directory.

Toolchain and flake

  • Pinned input: systemfsoftware is pinned at d1ab631935c9439bcd16abf2894b09b843494701. The pnpm store comes from its lib.mkConsumerStore over 24 SYS tarballs: the generic set plus its runtime dependencies. The stryker-js-effect and xstate tarballs ride in the store's src.
  • attw: @systemfsoftware/arethetypeswrong-cli is built as a tarball from the are-the-types-wrong-effect input, at the revision xstate's lock pins, the same way xstate's flake builds it. It is not taken from the npm registry. check:sfs-sources is unchanged and green.
  • Exports: the flake exports this workspace the way SYS does: packages.<system>.{effect-atom, effect-atom-react, storybook-gherkin, oxlint-config-frontend, workspace-tarballs} plus lib.mkConsumerStore.
  • Dev shell: the dev shell copies the tarballs into .sfs-deps from its existing shellHook. No shell script is added.
  • Browser tests: the shell also sets FONTCONFIG_FILE (DejaVu). Without it, sandboxed chromium lays text out at zero height and the moved storybook-gherkin visibility story fails.

Gate changes

  • Suppression exemption (declared under CONST-W3; operator-approved): this edits a judgment surface, which CONST-E9 bans. lint:suppressions (package.json) excludes exactly two moved fixture paths from the no-inline-suppression check:

    • packages/oxlint-presets/oxlint-config-frontend/ui-state-fixture/src/react-effect/
    • packages/gherkin/storybook-gherkin/test/browser/scenario-title.deny.ts

    Their directives are the inputs the moved tests read to prove the bans. Every other tracked source file is still checked.

  • New turbo tasks: test:types, lint:tsgo and test:browser are added, mirroring SYS. gate:tasks now runs lint lint:tsgo lint:suppressions typecheck typecheck:node test:types test test:browser. typecheck depends on build (as in SYS) so the fixture can resolve the preset's dist.

  • build.inputs gains api-extractor.json, api-extractor.*.json and etc/*.api.md, as in SYS.

  • dprint.json excludes **/etc/*.api.md, as SYS does; api-extractor's api:check gates those reports.

  • .mergify.yml is added: the queue rules for this repo.

Verification (local, inside nix develop)

Exit codes at head 792645ae315fc20eca5b71a4cc5016aea252c5e8: pnpm format:check 0, pnpm check:ci 0. The pushed head a268ca700e74c64aa29d34a84a8d991ada03b620 changes only the author field of four manifests to TODO <todo@example.com> and adds the .changeset/hungry-doors-stare.md intent naming @systemfsoftware/oxlint-config-frontend that the changeset · shared tooling gate requires.

At 2f8a573aa, before the README and .mergify.yml commits: pnpm check:sfs-sources 0, pnpm lint 0, pnpm typecheck 0, pnpm test 0, pnpm gate:dist 0.

pnpm journeys can't run in the authoring container: curl there points outside the sandbox closure, and the same is true on main. The journeys check on this PR is the proof. nix build .#workspace-tarballs .#effect-atom .#effect-atom-react .#storybook-gherkin .#oxlint-config-frontend builds. The packed runtime fields of the three moved packages match SYS's published tarballs. Stryker was not run.

Code review receipt

ce-code-review covered the branch against base 949d20e, with reviewed head 14b91ccfe. The final pushed head is a268ca700e74c64aa29d34a84a8d991ada03b620. The commits after the reviewed head are only the .mergify.yml the conductor specified, the author-placeholder fix the conductor ordered, and the changeset intent the changeset · shared tooling gate required; the conductor reviewed all three at that final head.

Seven reviewers ran: correctness, project-standards, testing, maintainability, api-contract, adversarial and learnings. An independent validator confirmed all 6 findings it checked. Verdict: Ready with fixes. No P0.

Follow-ups (P2/P3 and settled items, not fixed here)

  • SYS-455: move apps/site onto @systemfsoftware/oxlint-config-frontend and replace its two useEffect call sites.
  • P2, changeset floor: the carried .changeset/effect-4-0-1-floor.md states a ^4.0.1 peer floor, and effect-4-0-5-peer-floor.md states 4.0.5. catalogs.peers.effect publishes ^4. The carried bodies are kept byte-identical by ruling.
  • P2, carried intents: full-version-dependency-ranges.md and funny-goats-repeat.md describe ranges for packages this repo does not release.
  • P2, storybook-gherkin/AGENTS.md: it says the package has no api-extractor; it has one. The moved text is unedited.
  • P2, plugin URL: under the @systemfsoftware/source condition, the preset's plugin URL resolves to src/plugin.mjs, which does not exist. Published consumers resolve dist/.
  • P2, version reuse: the pending major intent quiet-hooks-subscribe.md would publish effect-atom-react 3.0.0, because the manifest is already 2.0.0. The first releases from this repo reuse SYS's version numbers (6.0.0, 2.0.0, 5.0.0); that is accepted by ruling.
  • P2, prefix matching: the preset finds the inherited ui-state patterns by matching the ui-state/ message prefix. A reworded generic preset would double-report.
  • P3: the new preset's homepage points at a README that does not exist yet.

…d the ui-state and storybook-testing packs here

Copied from systemfsoftware/systemfsoftware main at d1ab631935c9439bcd16abf2894b09b843494701,
with every file systemfsoftware/systemfsoftware#763 adds or modifies taken from its head
c08bc10b4005a8fc70d84d0f49e5de26232136d7 (the effect-atom-react useSyncExternalStore
rewrite, its tests and fixtures, and the ui-state README and react-runs-no-effect rule) and
the four files #763 deletes left out. Package names and versions are unchanged.

Edits after the copy:
- package.json repository, homepage and bugs point at this repository.
- Every systemfsoftware dependency is the range that repository publishes, resolved to the
  pinned flake tarball by a root override, never a workspace link.
- The preset dependency and each oxlint.config.ts name @systemfsoftware/oxlint-config-frontend.
- effect-atom and effect-atom-react take playwright from the catalog (1.63.0), the
  version the Nix browsers ship.
- Five pack lint lines name the frontend preset and @systemfsoftware/ui-state/no-react-effect.
- The three etc/*.api.md reports carry CRLF bytes upstream; this repository's
  `* text=auto eol=lf` stores them as LF, and api:check passes on that form.
… UI rules

@systemfsoftware/oxlint-config-frontend@0.1.0 spreads the pinned
@systemfsoftware/oxlint-config-recommended@4.0.0 and adds what the UI packs mechanize:
the server-state import ban (ui-state/server-data-lives-in-atoms), the .tsx fetch ban
(ui-state/components-perform-no-io), the story page.screenshot ban
(storybook-testing/visual-evidence-comes-from-the-runner), and from
systemfsoftware/systemfsoftware#763 the React plugin rules, the useEffect /
useLayoutEffect / useInsertionEffect / useEffectEvent import ban and the
no-react-effect rule.

no-react-effect ships inside the preset as a local JS plugin loaded by URL from
dist/plugin.mjs, named @systemfsoftware/ui-state so it cannot collide with the
generic preset's @systemfsoftware/effect-platform plugin. The preset replaces the
generic preset's ui-state patterns in every no-restricted-imports value it inherits,
so each banned import is reported once and a later override cannot drop them.

Moved tests only: fetch-in-tsx, server-state-imports, story-screenshot, react-effect,
react-rules, the oxlint-diagnostics fixture, the ui-state-fixture directory and the
rule's RuleTester suite. Edits after the copy: the rule id
@systemfsoftware/effect-platform/no-react-effect becomes
@systemfsoftware/ui-state/no-react-effect in the rule config, its test, the
react-effect test's diagnostic code and four directive fixtures; three fixture
configs import @systemfsoftware/oxlint-config-frontend.
…export this workspace's

The systemfsoftware input is pinned to d1ab631935c9439bcd16abf2894b09b843494701 and
pnpm-release-management to its pin there. The sandbox store is that repository's
lib.mkConsumerStore over the 24 systemfsoftware packages this workspace installs;
every @systemfsoftware/* lockfile entry is a file:.sfs-deps tarball, none a workspace
link or registry fetch.

@systemfsoftware/arethetypeswrong-cli, which the moved packages' attw scripts run, is
built from source at the released 4.2.0 tag (the pinned are-the-types-wrong-effect
input) the way the xstate flake builds it, with the effect-cell-types 7 build it
resolves. Its builder, store and manifest overlays are copied from xstate; the two
overlay lockfiles record the integrity of the pinned tsconfig and npm-package tarballs.

The flake exports packages.<system> from mkPnpmWorkspacePackages (one tarball per
public package plus workspace-tarballs) and its own lib.mkConsumerStore, so another
repository consumes effect-atom, effect-atom-react, storybook-gherkin and
oxlint-config-frontend by flake input.

Workspace: globs for packages/atom, packages/gherkin and packages/oxlint-presets; the
catalog moves to the versions the moved packages are tested on (effect 4.0.5,
@effect/tsgo 0.51.1, vitest 5.0.5, vite 8.3.4, oxlint 1.87.0, oxlint-tsgolint 7.0.2003)
plus their own dependencies; peers, oxlint and stryker named catalogs; the
rolldown-plugin-dts 0.28.6 patch with an override that keeps it resolved.

Gates: turbo gains test:types, lint:tsgo and test:browser, and build inputs gain the
api-extractor config and etc/*.api.md. lint runs lint:tsgo, typecheck runs test:types,
test and gate:tasks run test:browser, gate:dist runs attw. lint:suppressions passes
every tracked source file except the two moved fixture paths whose directives the
tests read: oxlint-config-frontend/ui-state-fixture/src/react-effect/ and
storybook-gherkin/test/browser/scenario-title.deny.ts. dprint skips etc/*.api.md,
which api-extractor writes.

The dev shell gives the sandboxed chromium a fonts.conf (DejaVu); without one it lays
text out at zero height and the moved storybook-gherkin visibility story fails.
The six systemfsoftware/systemfsoftware intents still pending for effect-atom,
effect-atom-react and storybook-gherkin, bodies byte-identical, frontmatter narrowed
to those three packages: effect-4-0-1-floor, effect-4-0-5-peer-floor,
full-version-dependency-ranges and funny-goats-repeat (patch), loose-moons-assert
(storybook-gherkin minor), and #763's quiet-hooks-subscribe (effect-atom-react major:
useAtomSubscribe, HydrationBoundary and useAtomInitialValues leave the public API).
…ystemfsoftware packs they lean on

Local packs: ui-state, storybook-testing. From systemfsoftware/systemfsoftware at the
full sha d1ab631935c9439bcd16abf2894b09b843494701, chosen by applies_when:
cell-architecture (atoms, services and Layers in effect-atom and apps/site),
boundary-testing (AtomHttpApi and AtomRpc adapters, port fakes in stories),
schema-laws (Effect Schema and schema-law tests), package-topology (published
packages now live here), mutation-discipline (stryker configs of the moved packages),
turbo-task-graph (this turbo.json). ci-wall-clock stays out: turbo-task-graph's README
keeps its enrolment in systemfsoftware/systemfsoftware. path-trust names no
directory authorization root here.
… ranges as systemfsoftware does

oxlint-config-frontend's ui-state-fixture imports the package by name, which resolves
to its own dist, so typecheck depends on build as in systemfsoftware's turbo.json; under
gate:tasks' --continue it otherwise raced the build and failed with TS2307.

react, react-dom, type-fest and vitest reach published dependencies and
peerDependencies through catalog:, which pnpm pack writes literally. The catalog now
carries the caret ranges systemfsoftware's catalog has, so the exported effect-atom-react
and storybook-gherkin manifests read exactly like the ones systemfsoftware published.
Resolved versions are unchanged.

@kiro-systemf kiro-systemf Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at a268ca700 (10 signed commits, no AI trailers; the delta since the lane-reviewed 14b91ccfe is six files and I read all six).

Delta read: .mergify.yml (queue conditions + the declared bootstrap note), one changeset for the moved oxlint preset, and four package.json author fields changed from a personal address to a placeholder. The lane move itself carries a six-lens review receipt at 14b91ccfe; the delta is configuration and metadata only, and I found no correctness issue in it.

Non-blocking finding: the placeholder is "author": "TODO <todo@example.com>". It is faceless, which is right, but it ships a TODO in published package metadata; a follow-up should set the org identity (e.g. systemfsoftware) instead.

Merge path: check-success = rules is a queue condition and is red because .github/rulesets/gates.json is not installed as an active branch ruleset. Once an admin installs it and the check re-runs green, Mergify merges this on the approval — no bootstrap hand-merge is needed. I am not taking the --match-head-commit path.

Reviewed by the workstation root as its own read of PR #7 and the six-file delta since the lane-reviewed head 14b91cc; no omp-acp session reviewed that delta.

@kiro-systemf
kiro-systemf Bot merged commit 28e6126 into main Oct 22, 2026
19 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant