Skip to content

fix(extractor): preserve falsy zero, scaled dynamic values and absence - #772

Draft
owjs3901 wants to merge 63 commits into
mainfrom
fix/dynamic-scaled-values
Draft

owjs3901 wants to merge 63 commits into
mainfrom
fix/dynamic-scaled-values

Conversation

@owjs3901

@owjs3901 owjs3901 commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Refs #694, #695, #685. #764 위에 쌓은 PR이며 #764를 먼저 병합해야 합니다. CI 실행을 위해 GitHub base는 main이고, #764가 병합되기 전까지 diff에는 #764의 변경도 포함됩니다. 이 PR은 초안으로 유지하며 #764의 명시적인 준비 완료 지시 전에는 ready로 바꾸지 않습니다.

요약

  • a && b에서 a = 0이면 이제 p={0}과 똑같이 padding 0을 적용합니다. 이전의 "falsy controller는 무조건 스타일 없음" 관례를 JavaScript의 실제 반환값 의미로 바꾸는 동작 변경입니다.
  • 해당 속성에 유효한 CSS를 만드는 동적 숫자와 숫자 문자열은 같은 리터럴의 정적 변환을 따릅니다. p={4}는 16px, w={100}은 400px, 시간 속성의 200은 200ms, opacity의 0.5는 0.5입니다.
  • 동적 값이 정적 경로에서 스타일 없음으로 처리되는 값이면 해당 선언의 클래스도 붙이지 않습니다. 이전 선언이 있는 경우에도 생략된 prop과 같은 computed style을 유지합니다.
  • 스타일 라이브러리 런타임이나 imported helper를 추가하지 않습니다. 아래 두 종류의 인라인 코드만 사용자 승인 예외입니다.
  • #764의 dcc7d906 병합에서 동적 identity가 기존 lowering 정보를 놓치지 않도록 conversion과 presence를 Identity/CounterIdentity 및 독립 reference의 마지막 필드로 추가합니다. Eq/Hash/Ord는 조건 없이 derived 필드로 처리하며, 기존 trace·순서·set assertion과 스냅샷은 그대로 유지합니다. metadata만 다른 세 선언은 분리되고 동일 선언의 복제본은 공유하는 회귀를 두 정책에서 확인합니다.
  • #764의 71ca61bc fixture를 W42의 source-type graph preflight에 맞춥니다. 타입 그래프 resolver는 SiteScope 전에 호출되므로 진짜 Counter parent를 실제 scoped at_role까지 보존합니다. 기존 site·policy·typed-error·allocator assertion은 그대로 두고, unsited preflight가 이름 슬롯을 할당하지 않고 candidate가 output으로 전달되지 않는 추가 관찰을 확인합니다. production scope 타이밍이나 resolver 호출 횟수 계약은 변경하지 않습니다.
  • 승인된 같은 fixture 조정은 counter_fixture_rejection_tests::unnumbered_site_rejects_when_public_at_role_runs_in_ordinary_resolver_scope와 cfbd5e06의 counter_kernel::rejection_tests::unnumbered_site_is_rejected_when_genuine_parent_is_attached_outside_fixture 두 테스트에만 적용됩니다. 모든 기존 assertion은 그대로 유지합니다.
  • W42e에서 승인된 scalar seam은 기존 wrapper의 배열 guard·scalar 성공·Evaluated fallback을 assignment_owner::capture_styles로 그대로 분리합니다. 두 visitor의 Vec::extend(Option)은 기존 optional push와 동등한 관용구이며, composition·capture 순서·outer guard·writeback을 바꾸지 않습니다. 모든 기존 assertion과 스냅샷을 유지합니다.
  • fix(extractor): stabilize names across build environments #764 c021e2b3와의 sheet 삽입 충돌은 승인된 그대로 W42의 dy.effective_value()와 #764의 raw insert_property·owned StyleSheetProperty 필드를 함께 유지하여 해결합니다. var/calc 단위 변환과 단 한 번의 !important, placement·own-element reset bookkeeping을 유지하며 생성된 선언을 authored literal evidence로 오인하지 않습니다. canonical counter 상태는 여전히 dormant이고 일반 Current 경로는 활성화하지 않습니다.
  • fix(extractor): stabilize names across build environments #764 U2 40e1aef3와 coverage 보완 7cdd0b3c를 지정된 그대로 true two-parent merge로 반영합니다. strict cache 6의 Rust export/admission API는 dormant 상태이며 일반 WASM cache 4·Current naming 경로는 바꾸지 않습니다. 이번 병합에는 source conflict·추가 preflight fixture 조정·기존 assertion 또는 스냅샷 변경이 없습니다.
  • fix(extractor): stabilize names across build environments #764 U3 f3c2d33a와 coverage 보완 4ef37bc3를 정확한 true two-parent merge로 반영합니다. Rust-only cache 6 companion/session restore·owned LiveCheckpoint·prospective Output seam은 dormant이며 public WASM은 cache 4·Current를 유지합니다. 기존 assertion·스냅샷이나 추가 fixture 조정 없이 검증했습니다.
  • W42g read-only audit의 후속 확인 사항: dormant raw6 fixture는 conversion 없는 color Dynamic을 사용하므로 scaled/presence-aware Counter production의 증거가 아닙니다. 향후 fix(extractor): stabilize names across build environments #764 activation에서 W42 단위 변환·conditional class metadata의 보존과 회귀를 별도로 확인해야 하며, 코디네이터가 #764에 전달합니다. 이번 U3는 activation하지 않고 현재 public Current 경로의 W42 검증은 그대로 통과합니다.

동작

1. Falsy Controller

JSX, 지원되는 jsx/jsxs factory, css()에서 같은 의미를 적용합니다. controller와 선택된 오른쪽 값은 원본의 순서 및 횟수대로 평가하며, falsy일 때 오른쪽은 실행하지 않습니다.

controller 이전 변경 후
0, -0 스타일 없음 같은 0 리터럴의 클래스
false, null, undefined, '', NaN 스타일 없음 스타일 없음
truthy 오른쪽 결과 오른쪽 결과의 정적 리터럴 의미

2. 동적 Scaled 값

빌드가 source AST와 로컬/모듈의 명시적 annotation으로 숫자를 증명하면 CSS에 calc(var(--site) * 4px)를 쓰고 변수에는 raw number를 둡니다. 시간 속성은 1ms, 단위 없는 속성은 원래 값을 유지합니다. TypeScript checker나 새로운 의존성은 없습니다.

숫자가 될 수 없는 문자열(auto, 단위가 붙는 문자열/union/template)은 그대로 전달합니다. 일반 string은 '4'일 수도 있으므로 static 경로와 공유하는 float grammar를 검사하는 인라인 변환을 적용합니다. string | number, any, unknown, 증명되지 않는 값은 number-or-numeric-string 변환을 적용합니다. 공백을 임의 trim하거나 JS Number()의 hex/coercion 규칙으로 넓히지 않습니다.

경로 입력 이전 선언 / inline 값 변경 후 선언 / inline 값
proven number p={n:number}, n=4 padding:var(--site) / 4 padding:calc(var(--site) * 4px) / 4
proven string `p={n:'auto' '10px'}` padding:var(--site) / n
numeric-capable string p={n:string}, n='4' padding:var(--site) / '4' padding:var(--site) / '16px'
unproven p={n}, n=4 또는 '4' padding:var(--site) / n padding:var(--site) / '16px'
responsive p={[n,null,n*2]} unit 없는 값 각 슬롯의 타입에 따른 변환
selector _hover={{p:n}} unit 없는 값 동일 shared 변환
unitless opacity={n}, n=0.5 0.5 0.5
time transitionDuration={n}, n=200 unit 없는 값 calc(... * 1ms) 또는 '200ms'

숫자의 정적 CSS가 해당 속성에 유효하지 않으면 리터럴 동등성의 예외입니다. 예를 들어 앞선 padding: 7px 규칙이 있을 때 정적 p={-0.5}의 padding: -2px는 파싱 시 버려져 7px이 남지만, 동적 변수 경로는 computed 단계에서 0px이 됩니다. 숫자로 증명된 calc() 경로는 음수 width를 0, overflow를 엔진 최댓값으로 clamp하고, invalid한 치환 값은 앞선 선언 대신 속성의 initial/inherited 값으로 계산됩니다. 음수 margin처럼 유효한 값은 그대로 동등하며, 숫자 유효성 클래스 정책이나 런타임 유효성 검사는 추가하지 않습니다.

custom shorthand가 서로 다른 단위를 소비하면 canonical target 순서로 그룹을 미리 계획합니다. 한 그룹만 있으면 기존 sparse role 이름을 그대로 유지하고, 여러 그룹이면 group * 256 + responsiveLevel의 disjoint 추가 역할을 사용합니다. 역할은 타입 증명이나 resolver 결과와 무관합니다. mixedScale: ['padding','opacity','animation-duration'], x=0.5는 각각 2px / 0.5 / 0.5ms이며 값은 한 번만 평가됩니다. #764의 D9 파일 번호, received-source offset, 개행/BOM 정규화와 own-element reset 계약은 유지합니다.

3. Absent 값의 Conditional Class

main과 published WASM 1.0.83에서 <Box className="base" p={null}/>는 dynamic class를 유지했습니다. React가 변수를 직렬화하지 않으면 padding:var(--site)는 computed-value 단계에서 invalid가 되어, .base{padding:11px}가 있어도 0px을 만들었습니다. 이번 변경은 같은 raw capture를 클래스 조건과 inline variable이 공유하여 dynamic class를 제외합니다. 결과는 실제 <Box className="base"/>의 11px입니다.

ordinary prop에서는 null, undefined, 두 boolean, exact empty string, numeric NaN/Infinity를 스타일 없음으로 처리하고 0/-0은 보존합니다. 문자열 'NaN'/'Infinity'나 공백 문자열을 새로운 garbage filter로 제외하지 않습니다. custom-property의 empty string은 ordinary empty와 구분합니다. Responsive 슬롯, selector, 논리 조건과 styled object의 creation-time capture에도 같은 정책을 적용합니다. absent 결과라도 원본의 call/getter/throw는 삭제하거나 render 시점으로 이동하지 않습니다.

사용자 결정 A에 따라 absent 요소에는 해당 사이트의 dynamic class와 own-element reset이 모두 없습니다. 따라서 부모의 generated custom property는 상속될 수 있지만 해당 요소의 자기 선언은 이를 읽지 않아 실제 prop 생략 요소와 같은 computed style을 유지합니다. 이는 #764의 unconditional reset 계약을 absent 요소에만 한정해 정정합니다. class가 적용되는 present 요소의 reset, 서로 다른 사이트 중첩 및 pseudo-element/descendant의 reset 위치는 그대로 유지합니다. 부모의 selectors={{ '& .child': { p: pad } }} 규칙은 같은 사이트의 absent 중첩 요소 안에 있는 .child에도 일반 정적 CSS와 동일하게 도달하는 것이 의도한 결과입니다. 기존 responsive/hover absent-reset 검증은 absent site class 없음·실제 생략 prop의 padding·상속된 변수 값을 함께 확인하도록 강화하며, present 값 assertion은 유지합니다.

런타임 예외

사용자가 승인한 범위는 (1) ambiguous scaled 값 및 numeric-capable string의 인라인 단위 변환, (2) captured raw 값에 따른 선언 클래스 선택입니다. 둘 다 기존 source-faithful lowering 안에서 원본 값을 한 번 평가하며 import/helper/state/effect/provider를 생성하지 않습니다. 일반 CSS-text interpolation과 aggregate StyleX namespace에는 ordinary prop presence 정책을 자동 확대하지 않습니다.

새로 생기는 오류

의도한 새 사용자 빌드 오류는 없습니다. 기존 오류의 위치/코드/이유 출력과 static-only API 제한은 유지합니다. 같은 received-source offset/role에 서로 다른 assignment를 넣는 내부 충돌 검사는 #764의 기존 오류 계약입니다.

남는 한계

  • 리터럴 동등성 보장 범위는 해당 속성에 유효한 정적 CSS를 만드는 finite 숫자와 CSS 문자열(정적 numeric-string 변환 포함), 승인된 falsy && 및 no-style primitive입니다. 숫자의 invalid CSS와 overflow는 위의 브라우저 규칙을 따릅니다. BigInt(0n 포함), 임의 객체/함수/symbol/boxed primitive는 지원하는 스타일 입력이 아닙니다.
  • CSS-wide keyword를 custom property로 전달할 때 custom property 자체의 상속 의미가 적용되는 기존 한계는 이 PR에서 바꾸지 않습니다.
  • empty custom-property가 React serializer/variable indirection을 통해 보존되는 문제도 별도 transport 범위입니다.
  • #750의 changed-binding/unknown-spread shadow collision, #756의 spread-only computed member 등 기존 stack 한계는 별도 수정 대상입니다.
  • 지원되는 factory alias와 실제 jsxDEV/react/jsx-dev-runtime/React.createElement는 다릅니다. 이 PR은 현재 visitor가 지원하지 않는 API를 새로 지원하지 않습니다.
  • 두 visitor의 optional scalar capture append는 공개 입력 경로를 통해 도달한다고 입증하지 못했습니다. extend 변경은 동등한 관용구일 뿐 도달 가능성 증명이 아닙니다. 새 CSS-parser descriptor 및 ordinary presence/array 회귀는 genuine helper/API seam 검증이며 공개 visitor regression으로 집계하지 않습니다.

검증

최종 HEAD는 bfecec9a7cd61a9a1ffb7cfd328caa88073f7892이며 #764 base 4ef37bc3까지 병합하여 push했습니다. 이 HEAD의 최신 CI 38036777104는 publish·landing-next-e2e·vinext-rsc-css-e2e·benchmark 네 job 모두 success입니다. publish 원본 로그에서 실제 Linux Rust 15293/15293 = 100.00%와 uncovered line 없음을 확인했으며 Bun 5,594건 통과·0 실패·함수/라인 100%입니다. PR은 명시적인 #764 준비 완료 지시 전까지 draft로 유지합니다.

실제 public WASM을 새로 빌드한 W42g 병합 트리에서 identity 수정과 type-graph preflight fixture 조정까지 확인했습니다. 현재 논리적 base는 코디네이터가 명시한 #764 4ef37bc3629c0df59143f8474e5efb6aa80e4428이며, dormant counter milestone을 활성화하지 않습니다. git log 4ef37bc3..HEAD로 확인한 이 PR 고유 커밋은 67809a08, 07f49e34, 39cbe810, identity repair abcc61a9, fixture merge 조정 fb655bbe와 2efb47c5, 사용자 결정 A 검증·문서 e86deabf, 평가 payload·source proof 회귀 02e8033e와 268dbdf7, 승인된 scalar seam 90d44885, U1 병합 및 승인된 sheet 충돌 해소 e1d852be, U2 병합 b4eff700, U3 병합 bfecec9a입니다. GitHub diff의 #764 부분과 이 13개 고유 커밋을 구분합니다.

첫 push는 abcc61a99a869ae453d7a3fd49bbaa65a432486d입니다. 실제 merge 부모는 정확히 39cbe810과 dcc7d906이며, CI unset·우회 없는 실제 pre-commit 훅이 lint/native 4,633건/Bun 5,594건을 다시 실행해 통과했습니다. Job Object kernel peak는 3,966,754,816 bytes로 12GB 제한 이내였습니다. 일반 포맷 Windows 훅 coverage 20078/20431 = 98.27%는 Linux 100% 증거가 아닙니다. 이 draft의 Linux CI는 생성 후 확인합니다.

두 번째 push는 fb655bbeeb26afcae86a884d2226ec93b2581cab이며 정확한 부모는 abcc61a9와 71ca61bc입니다. 승인된 fixture 조정을 포함한 실제 훅은 native 4,659건/Bun 5,594건/100%/lint를 통과했고, kernel peak 3,867,639,808 bytes로 12GB 이내였습니다. 첫 Linux CI 37937097870은 publish coverage 14059/14067 = 99.94%의 8라인과 Next의 기존 absent-reset assertion 8건 때문에 실패했습니다. benchmark와 vinext RSC는 통과했으며, 실패를 outage나 green으로 표시하지 않습니다. 후속 사용자 결정과 의미 있는 회귀로 해결할 예정입니다.

세 번째 push는 2efb47c5308d9530656399f8c282c0195d6882b1이며 정확한 부모는 fb655bbe와 cfbd5e06입니다. 실제 훅은 native 4,727건/Bun 5,594건/100%/lint를 통과했고 kernel peak는 4,127,842,304 bytes였습니다. workspace 검증에는 새 sheet doctest 10건도 모두 포함합니다. 첫 doctest 동시 컴파일은 6GB watchdog을 초과해 중단됐으므로 green으로 집계하지 않습니다. 동일 전체 Rust 게이트를 jobs 2와 --test-threads=2로 재실행해 kernel peak 2,906,767,360 bytes, 중단 없이 통과했습니다.

사용자 결정 A 단위는 e86deabf96b5a59374a6b795298b9de4a72e8283로 push했습니다. production 변경 없이 강화된 테스트와 docs 한 문장만 포함하며, 실제 Chromium 44건·CI unset 실제 훅 native 4,727건/Bun 5,594건/100%/lint가 통과했습니다. 훅 kernel peak 4,031,549,440 bytes로 12GB 이내입니다. 37972532158의 실패는 기존 absent-reset expectation과 같은 Linux gap 8라인(14503/14511 = 99.94%)이며, 이 단위 이후에도 커버리지 보완은 남아 있습니다.

37975216323에서 Next e2e·vinext RSC·benchmark는 모두 통과하여 사용자 결정 A의 실제 Next 빌드 검증도 green입니다. publish는 동일한 coverage 8라인 때문에 실패했습니다. 이후 평가 payload 회귀 5건(02e8033e)과 source proof 회귀 7건(268dbdf7)을 별도 exact-tree 실제 훅으로 push했습니다. 실제 getter 한 번 평가·raw/class/inline 변환과 parser가 만든 receiver type name·cooked 값 없는 tagged template·primitive/object intersection을 확인합니다. receiver/template는 명시적인 helper/API seam 검증이며 공개 adapter의 도달 가능성이라고 과장하지 않습니다. 두 훅은 각각 native 4,732/4,739건과 Bun 5,594건/100%/lint를 통과했습니다. W42d 종료 시에는 scalar 함수 분리안이 승인 대기였으나, W42e에서 그대로 승인되어 위의 behavior-preserving seam과 genuine CSS-parser/API 회귀 15건을 적용했습니다.

W42d의 HEAD 268dbdf7f6c45009f12dca4e8a434795e7b33780에서 CI 37987873005는 Next e2e·vinext RSC·benchmark success, publish만 Linux Rust coverage 14512/14516 = 99.97%로 실패했습니다. 남은 정확한 4라인은 CI-wide format의 extract_style_from_expression.rs:182-183, visit.rs:1304,1677이며, native 테스트·스냅샷 실패나 Codecov outage가 아닙니다. W42e 후속 push의 실제 Linux 결과로만 해결 여부를 판단하며, 확인 전에는 100%/전체 CI green으로 표시하지 않습니다. #764 준비 완료 지시 전까지 draft는 유지합니다.

승인된 scalar seam 단위는 90d44885c322107651376f16243b8645c7d0af97로 push했습니다(부모 268dbdf7). CSS parser가 실제로 만든 presence-free Dynamic과 원본 interpolation AST를 사용해 direct scalar·whole conditional·array fallback을 검증하고, 실제 ordinary extraction의 presence·변환·raw capture·getter 순서와 대비합니다. 새 테스트 15건은 작은 두 모듈로 분리했으며 기존 assertion과 스냅샷은 그대로입니다. 최종 fmt/Rust 1.99 clippy/native 4,754건 및 sheet doctest 10건, 새 WASM/root build, Bun 5,594건/100%/lint, 3엔진 3,816 비교·finite 576행, client 120 assertion/126관찰 및 Chromium 결정 A 44건이 모두 통과했습니다. CI unset·우회 없는 실제 훅은 같은 전체 파일 트리를 다시 통과했으며 Job Object kernel peak 4,158,337,024 bytes로 12GB 이내입니다. 일반 Windows 훅 coverage 20810/21177 = 98.27%는 Linux 100% 증거로 사용하지 않습니다.

scalar 단위의 CI 38008915697는 네 job 모두 success이며 Linux Rust coverage 14533/14533 = 100.00%입니다. 그 후 지정된 U1 c021e2b3를 true two-parent merge e1d852bea03cde80c8f4e8bd10307750d5406dc7로 push했습니다(정확한 부모 90d44885, c021e2b3). 위 sheet 충돌 해소 외에는 추가 fixture/assertion/snapshot 변경 없이 native 4,799건·doctest 10건과 모든 위 feature/browser 게이트가 통과했습니다. 기존 important full-pipeline/정확한 replay 회귀를 유지하고, 새 public WASM의 background·padding을 두 CSS 모드에서 확인하여 !important가 각각 정확히 한 번임을 검증했습니다. U1의 단 한 번의 CI unset 실제 훅은 native 4,799건/Bun 5,594건/100%/lint를 통과했으며 kernel peak는 4,023,951,360 bytes였습니다. 일반 Windows coverage 21045/21401 = 98.34%는 Linux 100%로 표시하지 않습니다. 병합 HEAD의 CI 38011596726에서 실제 Linux 14660/14660 = 100.00%와 네 job success를 확인했으며 남은 coverage gap은 없습니다.

지정된 U2의 true two-parent merge는 b4eff700f48a4af90427afb4897d2d3ce2d48676이며 정확한 부모는 e1d852bea03cde80c8f4e8bd10307750d5406dc7와 7cdd0b3ca6fb5e92f2451f2076b3f73728b2a0e0입니다. 34개 incoming whole-file의 qualified tree는 b5f72d133110034b6f6f22561e6823ba3d94e41b이며 conflict·fixture/assertion/snapshot 수정 없이 native 4,986건·sheet doctest 15건, Rust 1.99 clippy/fmt, fresh public WASM/root build, Bun 5,594건/100%/lint 및 위 실제 browser 게이트를 모두 다시 통과했습니다. 단 한 번의 CI unset·우회 없는 실제 pre-commit 훅도 동일 트리의 lint/native/Bun을 통과했고, Job Object kernel peak는 4,048,093,184 bytes로 12GB 이내이며 이번 W42f에는 새 memory cap stop이 없습니다. 일반 Windows 훅 coverage 21782/22148 = 98.35%는 Linux 100%로 표시하지 않으며 새 HEAD의 CI 38022288140에서 실제 Linux 15158/15158 = 100.00%와 네 job success를 별도로 확인했습니다. site bytes도 다시 측정하여 표의 값이 동일함을 확인했습니다.

지정된 U3 병합 bfecec9a7cd61a9a1ffb7cfd328caa88073f7892의 정확한 부모는 b4eff700f48a4af90427afb4897d2d3ce2d48676와 4ef37bc3629c0df59143f8474e5efb6aa80e4428입니다. 22개 incoming whole-file의 qualified tree는 9cf08db1211f2e21b203ee83151ad2d12afdeb80이며 source conflict·fixture 조정·기존 assertion/snapshot 수정 없이 native 5,088건·sheet doctest 19건과 위 모든 feature/browser 게이트를 통과했습니다. 단 한 번의 CI unset·우회 없는 실제 pre-commit 훅은 동일 트리의 lint/native/Bun을 통과했고, Job Object private peak 3,758,034,944 bytes·kernel peak 3,971,461,120 bytes로 12GB 이내였습니다. 일반 Windows coverage 21945/22297 = 98.42%는 Linux 100% 증거가 아니며 새 HEAD의 CI 38036777104에서 실제 Linux 15293/15293 = 100.00%와 네 job success를 별도로 확인했습니다. W42g에는 새 cap stop이 없고 site bytes는 표와 동일합니다.

게이트 결과
Rust 1.99 clippy / 일반 cargo fmt 통과, -D warnings
Linux Rust coverage 최종 HEAD bfecec9a CI 38036777104에서 15293/15293 = 100.00%, uncovered line 없음
native workspace 5,088 통과 / 0 실패 + sheet doctest 19건, 이번 병합의 기존 스냅샷 변경 없음
dynamic identity Current/CounterOriginal의 기존 red 2건 green, identity suite 24건 통과; 14 metadata 조합 및 복제본 dedup·기존 필드 순서 유지
fresh WASM 및 root package build 통과
Bun 5,594 통과 / 0 실패, 함수·라인 100%
전체 lint 0 오류, base의 기존 warning 2개만 유지
Chromium / Firefox / WebKit 212쌍, computed 비교 3,816건 통과
CSS 모드 / 반응형 / 순서 per-file 및 singleCss, 375/800/1440px, 전체 JS/CSS 역순 비교 18건 통과
client 업데이트 null -> 4 -> undefined -> false -> '' -> 4 -> null, 6 surface × 3엔진, 126 관찰 중 120 assertion 통과
finite-edge 실제 WASM/React SSR 576행 통과, literal parity 288행 + 문서화한 차이 288행, 전체 output 역순 비교 96건 통과
사용자 결정 A 실제 WASM/SSR Chromium 44건 통과, 4 CSS 모드의 강화된 absent 8건·새 descendant 시나리오 4건 포함, 모든 present/reset 위치 검증 유지

client 검증의 active numeric color 6관찰은 assertion 대상이 아니며, 이를 통과한 active-color 검증이라고 집계하지 않습니다. 숫자와 숫자 문자열, 고정 단위 문자열, 모든 9개 compile-time component, responsive·selector·jsx factory·css()의 falsy 0 및 모든 ordinary no-style primitive를 포함했습니다. mixedScale의 실제 computed 값은 padding 2px, opacity 0.5, animation duration 0.0005s입니다.

Windows의 CI-wide-format Rust tarpaulin은 병합 전 트리에서 12878/12905 = 99.7908%이고, 이미 실행된 일부 Windows line mapping도 zero-hit으로 남았습니다. 이를 100%라고 주장하지 않습니다. 코디네이터 승인 절차대로 실제 hook을 CI unset 상태에서 실행하고, push 후 Linux CI의 --fail-under 100을 최종 권위로 확인합니다. LSP는 Rust daemon timeout 및 설치되지 않은 TS/biome 때문에 clean 결과를 얻지 못했으며, 위 compiler·lint·실행 결과와 구분합니다.

실제 Proven-Number Output

다음은 byte fixture의 실제 WASM 출력이며 이름을 짧게 바꾸거나 생략하지 않았습니다. n은 한 번 읽고 같은 captured raw 값을 class 및 variable이 공유합니다.

import "df/devup-ui.css";
import { jsx } from "react/jsx-runtime";
function render(n: number) {
	return ((__devupAssignment120) => <div className={__devupAssignment120?.[0] ?? ""} style={{ ...__devupAssignment120?.[1] }} />)(((__devupValue) => [
		__devupValue !== null && __devupValue !== void 0 && typeof __devupValue !== "boolean" && __devupValue !== "" && (typeof __devupValue !== "number" || __devupValue === __devupValue && __devupValue !== 1 / 0 && __devupValue !== -(1 / 0)) ? "OHcsgiv6ionk_dqg8q" : "",
		{ "---Sa-ct": __devupValue },
		__devupValue
	])(n));
}
.OHcsgiv6ionk_dqg8q{---Sa-ct:initial;padding:calc(var(---Sa-ct) * 4px)}

사이트별 Bytes

UTF-8 emitted compiler JSX/TS source와 CSS를 각각 gzip level 9로 측정했습니다. minified production bundle이나 전체 사이트의 압축률이 아닙니다. before는 보존한 numeric-only WIP artifact이며 clean #764 baseline이나 absent-only 비용이 아닙니다. 특히 before의 proven-number CSS는 var였으므로 calc로 변경된 CSS 증가도 포함합니다. 현재 absolute 크기와 이 두 정확한 artifact 사이의 delta만 해석해야 합니다.

사이트 JS before raw/gzip JS after raw/gzip JS delta raw/gzip CSS before raw/gzip CSS after raw/gzip
unknown 426/291 824/416 +398/+125 127/135 127/133
number 172/166 570/312 +398/+146 127/133 139/144
string 380/285 778/414 +398/+129 127/135 127/133
unitless 164/157 562/305 +398/+148 127/132 127/133
captured source order 629/364 989/477 +360/+113 127/133 127/133
jsx runtime 478/312 836/421 +358/+109 127/135 127/133
selector 426/291 824/419 +398/+128 153/141 153/142
responsive 1313/472 1797/531 +484/+59 235/183 235/182
shorthand 445/306 1095/444 +650/+138 197/161 197/161
styled creation 557/350 907/454 +350/+104 127/134 127/133

빌드·테스트는 CARGO_BUILD_JOBS=2, 하나의 실행 슬롯으로 진행했습니다. Git/sh/MSYS descendants를 kernel Job Object에 포함하는 watchdog으로 merge hook과 이후 명령을 제한하고, 1초 private-memory 합계와 kernel PeakJobMemoryUsed를 별도로 기록합니다. fixture 6GB / real app 및 hook 12GB 제한을 지킵니다. 위에 기록한 doctest 동시 컴파일의 실제 cap stop 1건 외에는 중단 없으며, 실패 명령은 통과 검증으로 대체 집계하지 않습니다.

owjs3901 and others added 30 commits October 1, 2026 01:50
…nd StyleX imports

The generated stylesheet always resolved to an empty module, so Bun.build dropped every style, and the pre-parse gate only accepted import declarations of @devup-ui/react, so files using the alias packages, StyleX, subpaths or re-exports ran the runtime stubs. DevupUI() now serves the complete sheet to the CSS loader after defer(), and the gate reads the real imports with Bun.Transpiler.scanImports.

Refs #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
… built stylesheets

A stylesheet module is built on its first import, and the shared base is read from disk past the plugin, so styles extracted later were missing from webpack and Rsbuild output; Rsbuild also served a module-wide string kept only when it grew. The files the entries reach are now extracted before the build, the base on disk is kept current, and a compilation whose stylesheets changed is run once more, writing only the complete result. Rsbuild serves each stylesheet from the current sheet.

Refs #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…into feat/deterministic-numbering

# Conflicts:
#	packages/next-plugin/src/loader.ts
…ing order

Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
… forwarding alone

Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #686

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…tion

Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…e order

Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Preserve whole styled argument creation-time evaluation and qualify the inherited naming/extractor coverage union, including sticky getCss proof.

Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…l Linux branches

Cover final Linux semantic branches and reject unsupported css/styled argument spreads without executing iterators. Preserve optional producer coordinates and source-order literal-array composition.

The approved invalid-object-to-literal-array fixture correction changes whole-source identity in an unnumbered file (decisions 5 and 17): only two g classes and two g variables change in one reviewed snapshot, with entire-body forward/inverse proof; styles and JavaScript evaluation are identical.

Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Merge main history while preserving this PR implementation. No manual conflict resolutions.
No conflicted files. The exact original #703 head b6984e6 is already an ancestor; retain its implementation with the ours strategy.
No conflicted files. The exact original #704 head 71a5984 is already an ancestor; retain its implementation with the ours strategy.
Merge main history while preserving this PR implementation. No manual conflict resolutions.
Merge main history while preserving this PR implementation. No manual conflict resolutions.
…tion

Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
owjs3901 and others added 21 commits October 9, 2026 11:12
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Exercise FirstValue keyframe hashes, independently registered placement rejection, dynamic child and valid mismatched variable receipts, retained owner authority, keyframe identity, and exact font-face capture. The replacement-only combine fixture has one caller with identical placements, so assert that contract instead of maintaining an unused different-placement merge branch. Keep every existing assertion, production dispatch, and cache format 4 unchanged.

Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…estone

Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Reconcile counter_kernel::rejection_tests::unnumbered_site_is_rejected_when_genuine_parent_is_attached_outside_fixture with W42 type-graph preflight before SiteScope; preserve all assertions and prove no preflight class reservations.

Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Preserve the existing wrapper branch in capture_styles and use equivalent Option extend at both visitors; qualify genuine CSS parser descriptors and presence-sensitive API fallbacks without claiming public visitor reachability.

Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@github-actions

github-actions Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Changepacks

@devup-ui/wasm@1.0.83 → 1.0.84 - bindings/devup-ui-wasm/package.json

Patch

  • Keep JavaScript argument-spread semantics in css() and styled(): compose supported literal arrays statically, and reject strings, other iterables and unknown spreads with a located composition error instructing users to pass the value itself instead. No iterators execute at build time or at styling runtime. Preserve optional producer coordinates and checked prelude offsets for located collision diagnostics.
  • Make atomHoist class names deterministic and match generated references to emitted CSS, freeze hoisting from predeclared route reach, and preserve dynamic !important, keyframes, and first-value responsive-token identities. No new build errors.
  • Qualify authentic original-numbered counter constructors across Rust test crates through non-default dev-only fixture support. Normal extraction, generated JavaScript, CSS naming and cache format remain unchanged; no new build errors or runtime helpers.
  • Separate original CSS allocation ownership from naming policy so the counter naming restoration can retain deferred original owners. Generated CSS, JavaScript and cache behavior are unchanged. No new build errors.
  • Prepare typed access to actual CSS counter slots while preserving existing allocation keys, namespace streams and rollback behavior. Generated CSS, JavaScript, cache behavior and snapshots are unchanged. No new build errors.
  • Class names and file numbers no longer depend on the order files are processed in. Every plugin walks the files it can extract (the project's source and the included packages) before the first transform and numbers them in path order (a file collapsed into a bucket is numbered as the bucket, and only files that mention the package, StyleX or an aliased package take numbers) through the new seedFileMap, so identical builds give identical class prefixes, CSS file names and output hashes; in development, files that appear later are numbered after the existing ones. Styles are given class names in a fixed order, not the order of a hash set. The exported class, file and canonical maps are canonical JSON (sorted keys). Stylesheet evaluation (vanilla-extract) refuses Math.random(), Date.now(), new Date() and Date(), which differ between builds, with a build error; fixed dates such as new Date(0) are unchanged. resetBuildState starts a build from its own options: the prefix, atom hoisting, routes, buckets, names, numbers and styles an earlier build in the process left are cleared, and the prefix is set on every setup even when it is absent. Engine snapshots from concurrent transforms are written one after another per file, so an older snapshot is never written last. File lists are ordered by code point rather than the locale
  • Prepare the exact legacy counter allocator and captured, map-independent naming inputs for the authoritative counter-cache transition. The new path is dormant until activation; current CSS, JavaScript and cache behavior are unchanged. No new build errors.
  • Add a dormant Rust-only scoped prepared/live Counter kernel with independent retained evidence and exact rollback. Production Current extraction, cache4 and JavaScript output remain unchanged; no new activated JavaScript build errors.
  • Prepare dormant original-owned static, dynamic and keyframe counter producers with exact legacy allocation inputs and request order, retaining source-site variable separation. Current production naming, generated output and cache behavior remain unchanged. No new build errors.
  • Prepare dormant frozen-input declaration replay and complete counter expansion witnesses for the authoritative cache transition. The test-driven path preserves reset, typography, keyframe and cleanup evidence without changing current CSS, JavaScript or cache behavior. No new build errors.
  • Prepare dormant original-file numeric registration and numbered source-scope capture for the counter transition, preserving source positions, roles and ownership independently of delivery. Current production naming, generated output and cache behavior remain unchanged. No new build errors.
  • Prepare dormant construction-time producer policy so original counter ownership survives deferred style unions, including dynamic and keyframe producers. Current production naming, generated output and cache behavior remain unchanged. No new build errors.
  • Preserve zero-valued logical controllers like static literals, scale proven dynamic numbers in CSS, and inline-convert ambiguous numeric values and numeric strings using the static numeric grammar. Omit dynamic declaration classes for absent values through single-evaluation captures, including selectors and responsive values. Keep source evaluation order and sparse variable sites; separate mixed-unit shorthand consumers by canonical target-ordered roles, leaving single-unit names unchanged and additional groups disjoint from responsive levels. No new build errors.
  • Stabilize class and runtime-variable names across build environments, bound unnumbered source identities with compact deterministic names, reset generated variables on their owning elements, and preserve authored evaluation order and lazy selection. Exact content-name and source-name collisions report both contents and their best real source locations; conflicting source-variable roles and unprotected naming caches now fail closed without rejecting literal CSS content strings.
  • style-order-range only checks styleOrder where the build reads it: a prop of a Devup UI component and a top-level key of a style object passed to css/globalCss/keyframes. A styleOrder key in nested data, in a prop value such as an element passed as a prop, or in a call of a function sharing a name with an Object.prototype member is no longer reported. The array, typography and media rules already skip non-style data, and css-utils-literal-only accepts a css()/keyframes() result held in a const inside a function. No new build errors.
  • Enforce build-time exclusive ownership of naming state and exact rollback when extraction or output construction fails, without changing production naming or cache format. Native lock-held recursive callbacks and same-owner configuration administration during an active exact attempt fail synchronously as programmer-contract violations; normal compilation gains no new build errors.
  • Compile proven static responsive arrays directly to classes and isolate content-named atoms by their existing delivered sheet identity. Safe original sources keep independent D9 counter namespaces even when their CSS shares a collapsed bucket. Build adapters supply an independent names-only project root; resolver IDs, D9 numbering and stylesheet placement stay unchanged. Versioned self-contained naming snapshots ignore and rebuild obsolete or invalid cache data that reaches WASM; cache build errors are reserved for real exact name collisions with located diagnostics. Static Textarea font-size arrays retain their declarations and DOM while compiling directly to classes.
  • Evaluate supported conditional styled rule arguments once when the component is created, preserving branch laziness, authored field order, static selectors and layers, typography and runtime value associations. Keep rule capture outside attrs wrappers while authored attrs callbacks remain render-time. Responsive typography retains its shared base class and order-aware class selection without introducing empty styles for proven inert base-preset lookups. This scheduling repair adds no build errors or styling runtime.
  • Tailwind classes in a className: each class compiles on its own and every class Tailwind does not define (custom, plugin and analytics classes) stays as written, where any recognized class used to rebuild the whole className without them and could rewrite part of another class; a class touching a template interpolation (icon-${name}) is left as written, and template classNames no longer get spaces inserted around interpolations. A class whose variant is not understood stays as written instead of applying unconditionally; variants follow Tailwind v4: stacked variants compose (hover:focus: matches the element itself), hover is guarded by @media (hover: hover), group-/peer- use the group/peer marker classes (and group-hover/name), and data-, aria-, has-, nth-, , **, supports-[…] and [&…]/[@media …] variants compile. Utilities emit all their declarations (size-, rounded-t-, truncate, sr-only, not-sr-only, text-sm with its line height, text-sm/6, leading-), translate/rotate/scale/skew compose through Tailwind's individual properties and registered variables (@Property) with negative values kept negative, and arbitrary values follow Tailwind's grammar: spaces for underscores except in url() and var() names, _ for an underscore, spaces around math operators, type hints, [property:value] and (--variable) shorthands. Words that only share a utility's prefix (select-wrapper, order-summary, cursor-foo) are no longer compiled
  • Select dynamic typography and enum classes from the authored value exactly once in source order, without typography CSS variables or declarations. Preserve responsive and selector-scoped presets, conditional style order, template coercion and the existing spread contract. No new build errors or styling runtime are introduced.
  • Keep dormant Rust counter state owned by the sheet with pure linkage checks and explicit literal ownership. The doc-hidden CounterSheet constructor now takes only the sheet. Production Current naming and cache4 remain unchanged; no new JavaScript build errors.
  • Add dormant Rust strict snapshot6 export and consuming admission APIs without changing production cache4 or JavaScript extraction. Invalid candidates and stale installation authority return typed Rust rejections; no new ordinary JavaScript build errors.

@devup-ui/bun-plugin@1.0.22 → 1.0.23 - packages/bun-plugin/package.json

Patch

  • Bun plugin works with Bun.build: DevupUI() (from @devup-ui/bun-plugin/register) serves the generated stylesheet to the bundler's CSS loader once every other module is loaded, so the build emits a CSS output with the styles of the whole bundle instead of an empty module; class names are short there and readable under the runtime (debug option). Files importing the packages Devup UI takes the place of (@emotion/react, @emotion/styled, styled-components, @vanilla-extract/css), @stylexjs/stylex, or a subpath or re-export of these or @devup-ui/react, are compiled instead of skipped
  • Class names and file numbers no longer depend on the order files are processed in. Every plugin walks the files it can extract (the project's source and the included packages) before the first transform and numbers them in path order (a file collapsed into a bucket is numbered as the bucket, and only files that mention the package, StyleX or an aliased package take numbers) through the new seedFileMap, so identical builds give identical class prefixes, CSS file names and output hashes; in development, files that appear later are numbered after the existing ones. Styles are given class names in a fixed order, not the order of a hash set. The exported class, file and canonical maps are canonical JSON (sorted keys). Stylesheet evaluation (vanilla-extract) refuses Math.random(), Date.now(), new Date() and Date(), which differ between builds, with a build error; fixed dates such as new Date(0) are unchanged. resetBuildState starts a build from its own options: the prefix, atom hoisting, routes, buckets, names, numbers and styles an earlier build in the process left are cleared, and the prefix is set on every setup even when it is absent. Engine snapshots from concurrent transforms are written one after another per file, so an older snapshot is never written last. File lists are ordered by code point rather than the locale
  • Compile proven static responsive arrays directly to classes and isolate content-named atoms by their existing delivered sheet identity. Safe original sources keep independent D9 counter namespaces even when their CSS shares a collapsed bucket. Build adapters supply an independent names-only project root; resolver IDs, D9 numbering and stylesheet placement stay unchanged. Versioned self-contained naming snapshots ignore and rebuild obsolete or invalid cache data that reaches WASM; cache build errors are reserved for real exact name collisions with located diagnostics. Static Textarea font-size arrays retain their declarations and DOM while compiling directly to classes.

@devup-ui/components@0.1.60 → 0.1.61 - packages/components/package.json

Patch

  • Stabilize class and runtime-variable names across build environments, bound unnumbered source identities with compact deterministic names, reset generated variables on their owning elements, and preserve authored evaluation order and lazy selection. Exact content-name and source-name collisions report both contents and their best real source locations; conflicting source-variable roles and unprotected naming caches now fail closed without rejecting literal CSS content strings.
  • Compile proven static responsive arrays directly to classes and isolate content-named atoms by their existing delivered sheet identity. Safe original sources keep independent D9 counter namespaces even when their CSS shares a collapsed bucket. Build adapters supply an independent names-only project root; resolver IDs, D9 numbering and stylesheet placement stay unchanged. Versioned self-contained naming snapshots ignore and rebuild obsolete or invalid cache data that reaches WASM; cache build errors are reserved for real exact name collisions with located diagnostics. Static Textarea font-size arrays retain their declarations and DOM while compiling directly to classes.

@devup-ui/eslint-plugin@1.0.22 → 1.0.23 - packages/eslint-plugin/package.json

Patch

  • style-order-range only checks styleOrder where the build reads it: a prop of a Devup UI component and a top-level key of a style object passed to css/globalCss/keyframes. A styleOrder key in nested data, in a prop value such as an element passed as a prop, or in a call of a function sharing a name with an Object.prototype member is no longer reported. The array, typography and media rules already skip non-style data, and css-utils-literal-only accepts a css()/keyframes() result held in a const inside a function. No new build errors.

@devup-ui/next-plugin@1.0.90 → 1.0.91 - packages/next-plugin/package.json

Patch

  • Make atomHoist class names deterministic and match generated references to emitted CSS, freeze hoisting from predeclared route reach, and preserve dynamic !important, keyframes, and first-value responsive-token identities. No new build errors.
  • Isolate the coordinator port file per owning process when another live next dev/build holds it, record the owner pid, and report port, pid and recovery when the coordinator is missing or unreachable
  • Class names and file numbers no longer depend on the order files are processed in. Every plugin walks the files it can extract (the project's source and the included packages) before the first transform and numbers them in path order (a file collapsed into a bucket is numbered as the bucket, and only files that mention the package, StyleX or an aliased package take numbers) through the new seedFileMap, so identical builds give identical class prefixes, CSS file names and output hashes; in development, files that appear later are numbered after the existing ones. Styles are given class names in a fixed order, not the order of a hash set. The exported class, file and canonical maps are canonical JSON (sorted keys). Stylesheet evaluation (vanilla-extract) refuses Math.random(), Date.now(), new Date() and Date(), which differ between builds, with a build error; fixed dates such as new Date(0) are unchanged. resetBuildState starts a build from its own options: the prefix, atom hoisting, routes, buckets, names, numbers and styles an earlier build in the process left are cleared, and the prefix is set on every setup even when it is absent. Engine snapshots from concurrent transforms are written one after another per file, so an older snapshot is never written last. File lists are ordered by code point rather than the locale
  • Stabilize class and runtime-variable names across build environments, bound unnumbered source identities with compact deterministic names, reset generated variables on their owning elements, and preserve authored evaluation order and lazy selection. Exact content-name and source-name collisions report both contents and their best real source locations; conflicting source-variable roles and unprotected naming caches now fail closed without rejecting literal CSS content strings.
  • Compile proven static responsive arrays directly to classes and isolate content-named atoms by their existing delivered sheet identity. Safe original sources keep independent D9 counter namespaces even when their CSS shares a collapsed bucket. Build adapters supply an independent names-only project root; resolver IDs, D9 numbering and stylesheet placement stay unchanged. Versioned self-contained naming snapshots ignore and rebuild obsolete or invalid cache data that reaches WASM; cache build errors are reserved for real exact name collisions with located diagnostics. Static Textarea font-size arrays retain their declarations and DOM while compiling directly to classes.

@devup-ui/plugin-utils@1.0.17 → 1.0.18 - packages/plugin-utils/package.json

Patch

  • Webpack and Rsbuild builds hold every style in their stylesheets: a stylesheet module is built on its first import, so styles extracted later (the global styles of files webpack or Rsbuild reached late, often outside src) were missing from the output. The files the entries reach under src are now extracted before the build, the shared base on disk is kept current, and when a stylesheet still changed during the build it is compiled once more, writing only the complete result. Rsbuild serves each stylesheet from the current sheet instead of a module-wide string kept only when it grew, which left edits that shortened the CSS and later builds in the same process stale. plugin-utils adds computeReachableFiles
  • Class names and file numbers no longer depend on the order files are processed in. Every plugin walks the files it can extract (the project's source and the included packages) before the first transform and numbers them in path order (a file collapsed into a bucket is numbered as the bucket, and only files that mention the package, StyleX or an aliased package take numbers) through the new seedFileMap, so identical builds give identical class prefixes, CSS file names and output hashes; in development, files that appear later are numbered after the existing ones. Styles are given class names in a fixed order, not the order of a hash set. The exported class, file and canonical maps are canonical JSON (sorted keys). Stylesheet evaluation (vanilla-extract) refuses Math.random(), Date.now(), new Date() and Date(), which differ between builds, with a build error; fixed dates such as new Date(0) are unchanged. resetBuildState starts a build from its own options: the prefix, atom hoisting, routes, buckets, names, numbers and styles an earlier build in the process left are cleared, and the prefix is set on every setup even when it is absent. Engine snapshots from concurrent transforms are written one after another per file, so an older snapshot is never written last. File lists are ordered by code point rather than the locale

@devup-ui/react@1.0.44 → 1.0.45 - packages/react/package.json

Patch

  • Stabilize class and runtime-variable names across build environments, bound unnumbered source identities with compact deterministic names, reset generated variables on their owning elements, and preserve authored evaluation order and lazy selection. Exact content-name and source-name collisions report both contents and their best real source locations; conflicting source-variable roles and unprotected naming caches now fail closed without rejecting literal CSS content strings.

@devup-ui/reset-css@1.0.31 → 1.0.32 - packages/reset-css/package.json

Patch

  • Auto-update: depends on '@devup-ui/react' via a local workspace dependency

@devup-ui/rsbuild-plugin@1.0.67 → 1.0.68 - packages/rsbuild-plugin/package.json

Patch

  • Make atomHoist class names deterministic and match generated references to emitted CSS, freeze hoisting from predeclared route reach, and preserve dynamic !important, keyframes, and first-value responsive-token identities. No new build errors.
  • Webpack and Rsbuild builds hold every style in their stylesheets: a stylesheet module is built on its first import, so styles extracted later (the global styles of files webpack or Rsbuild reached late, often outside src) were missing from the output. The files the entries reach under src are now extracted before the build, the shared base on disk is kept current, and when a stylesheet still changed during the build it is compiled once more, writing only the complete result. Rsbuild serves each stylesheet from the current sheet instead of a module-wide string kept only when it grew, which left edits that shortened the CSS and later builds in the same process stale. plugin-utils adds computeReachableFiles
  • Class names and file numbers no longer depend on the order files are processed in. Every plugin walks the files it can extract (the project's source and the included packages) before the first transform and numbers them in path order (a file collapsed into a bucket is numbered as the bucket, and only files that mention the package, StyleX or an aliased package take numbers) through the new seedFileMap, so identical builds give identical class prefixes, CSS file names and output hashes; in development, files that appear later are numbered after the existing ones. Styles are given class names in a fixed order, not the order of a hash set. The exported class, file and canonical maps are canonical JSON (sorted keys). Stylesheet evaluation (vanilla-extract) refuses Math.random(), Date.now(), new Date() and Date(), which differ between builds, with a build error; fixed dates such as new Date(0) are unchanged. resetBuildState starts a build from its own options: the prefix, atom hoisting, routes, buckets, names, numbers and styles an earlier build in the process left are cleared, and the prefix is set on every setup even when it is absent. Engine snapshots from concurrent transforms are written one after another per file, so an older snapshot is never written last. File lists are ordered by code point rather than the locale
  • Stabilize class and runtime-variable names across build environments, bound unnumbered source identities with compact deterministic names, reset generated variables on their owning elements, and preserve authored evaluation order and lazy selection. Exact content-name and source-name collisions report both contents and their best real source locations; conflicting source-variable roles and unprotected naming caches now fail closed without rejecting literal CSS content strings.
  • Compile proven static responsive arrays directly to classes and isolate content-named atoms by their existing delivered sheet identity. Safe original sources keep independent D9 counter namespaces even when their CSS shares a collapsed bucket. Build adapters supply an independent names-only project root; resolver IDs, D9 numbering and stylesheet placement stay unchanged. Versioned self-contained naming snapshots ignore and rebuild obsolete or invalid cache data that reaches WASM; cache build errors are reserved for real exact name collisions with located diagnostics. Static Textarea font-size arrays retain their declarations and DOM while compiling directly to classes.

@devup-ui/vite-plugin@1.0.73 → 1.0.74 - packages/vite-plugin/package.json

Patch

  • Make atomHoist class names deterministic and match generated references to emitted CSS, freeze hoisting from predeclared route reach, and preserve dynamic !important, keyframes, and first-value responsive-token identities. No new build errors.
  • Class names and file numbers no longer depend on the order files are processed in. Every plugin walks the files it can extract (the project's source and the included packages) before the first transform and numbers them in path order (a file collapsed into a bucket is numbered as the bucket, and only files that mention the package, StyleX or an aliased package take numbers) through the new seedFileMap, so identical builds give identical class prefixes, CSS file names and output hashes; in development, files that appear later are numbered after the existing ones. Styles are given class names in a fixed order, not the order of a hash set. The exported class, file and canonical maps are canonical JSON (sorted keys). Stylesheet evaluation (vanilla-extract) refuses Math.random(), Date.now(), new Date() and Date(), which differ between builds, with a build error; fixed dates such as new Date(0) are unchanged. resetBuildState starts a build from its own options: the prefix, atom hoisting, routes, buckets, names, numbers and styles an earlier build in the process left are cleared, and the prefix is set on every setup even when it is absent. Engine snapshots from concurrent transforms are written one after another per file, so an older snapshot is never written last. File lists are ordered by code point rather than the locale
  • Stabilize class and runtime-variable names across build environments, bound unnumbered source identities with compact deterministic names, reset generated variables on their owning elements, and preserve authored evaluation order and lazy selection. Exact content-name and source-name collisions report both contents and their best real source locations; conflicting source-variable roles and unprotected naming caches now fail closed without rejecting literal CSS content strings.
  • Compile proven static responsive arrays directly to classes and isolate content-named atoms by their existing delivered sheet identity. Safe original sources keep independent D9 counter namespaces even when their CSS shares a collapsed bucket. Build adapters supply an independent names-only project root; resolver IDs, D9 numbering and stylesheet placement stay unchanged. Versioned self-contained naming snapshots ignore and rebuild obsolete or invalid cache data that reaches WASM; cache build errors are reserved for real exact name collisions with located diagnostics. Static Textarea font-size arrays retain their declarations and DOM while compiling directly to classes.

@devup-ui/webpack-plugin@1.0.71 → 1.0.72 - packages/webpack-plugin/package.json

Patch

  • Webpack and Rsbuild builds hold every style in their stylesheets: a stylesheet module is built on its first import, so styles extracted later (the global styles of files webpack or Rsbuild reached late, often outside src) were missing from the output. The files the entries reach under src are now extracted before the build, the shared base on disk is kept current, and when a stylesheet still changed during the build it is compiled once more, writing only the complete result. Rsbuild serves each stylesheet from the current sheet instead of a module-wide string kept only when it grew, which left edits that shortened the CSS and later builds in the same process stale. plugin-utils adds computeReachableFiles
  • Class names and file numbers no longer depend on the order files are processed in. Every plugin walks the files it can extract (the project's source and the included packages) before the first transform and numbers them in path order (a file collapsed into a bucket is numbered as the bucket, and only files that mention the package, StyleX or an aliased package take numbers) through the new seedFileMap, so identical builds give identical class prefixes, CSS file names and output hashes; in development, files that appear later are numbered after the existing ones. Styles are given class names in a fixed order, not the order of a hash set. The exported class, file and canonical maps are canonical JSON (sorted keys). Stylesheet evaluation (vanilla-extract) refuses Math.random(), Date.now(), new Date() and Date(), which differ between builds, with a build error; fixed dates such as new Date(0) are unchanged. resetBuildState starts a build from its own options: the prefix, atom hoisting, routes, buckets, names, numbers and styles an earlier build in the process left are cleared, and the prefix is set on every setup even when it is absent. Engine snapshots from concurrent transforms are written one after another per file, so an older snapshot is never written last. File lists are ordered by code point rather than the locale
  • Compile proven static responsive arrays directly to classes and isolate content-named atoms by their existing delivered sheet identity. Safe original sources keep independent D9 counter namespaces even when their CSS shares a collapsed bucket. Build adapters supply an independent names-only project root; resolver IDs, D9 numbering and stylesheet placement stay unchanged. Versioned self-contained naming snapshots ignore and rebuild obsolete or invalid cache data that reaches WASM; cache build errors are reserved for real exact name collisions with located diagnostics. Static Textarea font-size arrays retain their declarations and DOM while compiling directly to classes.

@codecov

codecov Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
bindings/devup-ui-wasm/src/administration.rs 100.00% <100.00%> (ø)
...ndings/devup-ui-wasm/src/atom_hoist_measurement.rs 100.00% <100.00%> (ø)
bindings/devup-ui-wasm/src/atom_tests.rs 100.00% <100.00%> (ø)
bindings/devup-ui-wasm/src/cache6_restore.rs 100.00% <100.00%> (ø)
bindings/devup-ui-wasm/src/cache6_session.rs 100.00% <100.00%> (ø)
...dings/devup-ui-wasm/src/cache6_transition_tests.rs 100.00% <100.00%> (ø)
...indings/devup-ui-wasm/src/cache_admission_tests.rs 100.00% <100.00%> (ø)
...indings/devup-ui-wasm/src/cache_allocator_proof.rs 100.00% <100.00%> (ø)
bindings/devup-ui-wasm/src/cache_atom_proof.rs 100.00% <100.00%> (ø)
bindings/devup-ui-wasm/src/cache_descriptor.rs 100.00% <100.00%> (ø)
... and 100 more

... and 107 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

owjs3901 and others added 7 commits October 10, 2026 09:52
Merge exactly c021e2b from #764, keeping the canonical counter kernel dormant. Resolve the sheet dynamic insertion conflict by preserving W42 dy.effective_value for var/calc conversion and one important suffix, while retaining the incoming raw insert_property owned fields, placement and reset bookkeeping. Preserve all existing assertions and snapshots.

Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Merge exactly #764 U2 7cdd0b3 with dormant strict cache 6 export and admission. Retain W42 dynamic effective_value conversion, conditional declaration classes and source-faithful evaluation. Preserve all existing assertions and snapshots.

Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #694

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Merge exactly #764 U3 4ef37bc with dormant binding companion and session restore plus coverage repair. Retain W42 dynamic effective_value conversion, conditional declaration classes and source-faithful evaluation. Preserve all existing assertions and snapshots.

Refs #694, #695, #685

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
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