Files
msd-core/.changeset
Tom Boucher c72fb34e9a fix(#4658): give the ui plan gate's evidence check a native branch (#4807)
* test(#4658): add failing-first coverage for native frontend evidence

hasStaticFrontendEvidence recognised only JS-ecosystem evidence, so
computeUiPlanGate could never block for a SwiftUI/Compose/Flutter/XAML
project. Adds evidence-level fixtures for the four suggested markers
(import-matched for .swift/.kt/.dart, extension-alone for .xaml), the
reporter's non-UI Swift control case, marker-exactness and SKIP_DIRS and
I/O-degrade negatives, gate-level block assertions through makeProject's
new native frontendEvidence modes, and a pinned-seed fast-check property.
All new assertions are RED until src/ui-frontend-evidence.cts grows the
native branch.

* fix(#4658): give the ui plan gate's evidence check a native branch

hasStaticFrontendEvidence recognised only JS-ecosystem evidence (a root
package.json UI-framework dep, or a .tsx/.jsx/.vue/.svelte file), so
computeUiPlanGate could never block for a SwiftUI, Jetpack Compose, Flutter,
or .NET MAUI project — the #3312 gate was structurally unreachable for them.

Adds a native BFS over the same bounds and skip rules: .xaml is evidence by
extension alone (the .tsx analogue), while .swift/.kt/.dart count only when
their content carries the ecosystem's UI import marker (import SwiftUI /
import UIKit, androidx.compose, package:flutter) — matched on the import, not
the extension, so a non-UI Swift package stays silent exactly as the issue's
37-file control case requires. Marker reads are bounded to a 64 KiB prefix;
any I/O failure degrades to false per the module contract. The #3718
vocabulary filter, the JS evidence rules, and the weaker-extension exclusion
are untouched.

* chore(#4658): regenerate the macos conformance tier list

The native-evidence additions to tests/check-ui-plan-gate.test.cjs move the
file into the macOS conformance tier per the classifier; the committed
generated list is a derived artifact and must match the live tests/ tree
(the same sync the fragment-single-edit-propagation install test enforces).

* fix(#4658): accept both Dart quote styles and extract the shared bounded walk

The isolated reviews' remaining findings: the Dart marker carried only the
single-quote anchor, missing legal double-quoted imports (a spec-narrowing
deviation); the two evidence walks duplicated the subtle MAX_WALK_ENTRIES
cap semantics verbatim, so they are extracted into one walkProjectFiles BFS
with a visit callback; tests now use the createTempDir helper, shared
fixture literals that cannot drift from NATIVE_UI_CONTENT_MARKERS, a
double-quoted Flutter import case, and drop a vacuous assertion and a
mid-body re-require alias.

* docs(#4658): backfill changeset PR number

---------

Co-authored-by: sim <sim@local>
2026-09-16 15:29:19 -04:00
..

Changeset Fragments

This directory holds per-PR CHANGELOG fragments. Every PR with user-facing changes drops one (or more) <random-name>.md files here describing its CHANGELOG entry. Fragments are consolidated into the top-level CHANGELOG.md at release time.

Why

Two PRs that both edit the ### Fixed block of CHANGELOG.md always conflict on merge — git can't pick a serialization order without human input. Two PRs that each add a fresh .changeset/<unique-name>.md never conflict because they don't share lines.

See #2975 for the full rationale.

Adding a fragment

node scripts/changeset/new.cjs \
  --type Fixed \
  --pr 1234 \
  --body "fix the thing — explain the user-visible change in one sentence"

This writes .changeset/<adjective>-<noun>-<noun>.md with frontmatter and a body. Three random words → concurrent PRs don't collide.

Format

---
type: Fixed
pr: 1234
---
**`/gsd-foo` no longer drops trailing slashes** — explain the user-visible change.

Allowed type: values follow Keep a Changelog: Added, Changed, Deprecated, Removed, Fixed, Security.

Opting out

PRs that legitimately have no user-facing impact can add the no-changelog label. CI honors it. When unsure, add the fragment.

At release time

Promotion is automatic. The release workflow's finalize job runs:

node scripts/changeset/cli.cjs render --version vX.Y.Z --date YYYY-MM-DD --allow-empty

This reads every fragment, groups bullets by type:, replaces ## [Unreleased] with a new ## [vX.Y.Z] - YYYY-MM-DD block, opens a fresh ## [Unreleased] above, and deletes consumed fragments. The --allow-empty flag ensures a no-change release still gets a dated heading (with a _No notable changes._ placeholder). A subsequent verify step confirms the promotion landed correctly. Maintainers do not run this by hand.

Archived fragments

.changeset/archived/ holds fragments for already-shipped releases (≤ 1.3.1), retained for provenance. Their content was hand-curated into the dated ## [1.x.y] sections of CHANGELOG.md during the #690 backfill — they were never consumed by render. All changeset tooling enumerates .changeset/ non-recursively, so archived fragments are never picked up or rendered. Do not move them back to the top level.