NOASSERTIONupdated 1mo ago
Let be the absolute plugin directory two levels above this SKILL.md. Resolve that path before running commands or opening shared references. When these instructions say swiftui-ctx, invoke /scripts/swiftui-ctx; do not assume the command is on PATH.
What can you do with Audit Swiftui Availability Gating?
name: audit-swiftui-availability-gating description: Audit macOS SwiftUI availability gating for correctness, current APIs, and production conventions. Use for that domain or as part of a full audit.
Bundled resource root
Let <swiftui-plugin-root> be the absolute plugin directory two levels above this SKILL.md. Resolve that path before running commands or opening shared references. When these instructions say swiftui-ctx, invoke <swiftui-plugin-root>/scripts/swiftui-ctx; do not assume the command is on PATH.
Audit SwiftUI Availability Gating
AUDIT-ONLY Β· macOS-only Β· SwiftUI-only. Run this on a finished or in-progress macOS SwiftUI
project as the toolkit's blanket availability net: every API floored above the project's deployment
target must be gated on the macOS arm at the correct floor with a real fallback β or the build breaks on
the older macOS it claims to support. This skill catches the ungated symbol, the wrong-arm gate (the
* wildcard that always fires), the floor mismatch, the missing else, the missing *, and the
macOS-ABSENT symbol wrapped in a Mac gate. Findings are written to disk in the toolkit's unified schema;
the two purely-mechanical defects are fixed under the fix-safety protocol. This is never a from-scratch
gated-UI generator.
The deployment target is load-bearing β read it first (ORIENT). Every gating defect is conditional on it: a symbol floored at macOS 14 is only a finding when the target is below 14.
Boundary / seam note (stay in lane)
- Deprecation flagging belongs to
audit-swiftui-api-currency. A symbol that is both deprecated and ungated is a deprecation finding there (it owns the flag); do not double-report it here β emit across_refto api-currency and let it carry the primary. We own "is it gated"; currency owns "is it current." - Deep glass gating belongs to
audit-swiftui-liquid-glass. Percross-ref-graph.md, glass symbols (glassEffect,GlassEffectContainer,.buttonStyle(.glass),scrollEdgeEffectβ¦) are gated in depth by liquid-glass (it owns the pre-26 fallback table and the morph wiring). When this net catches an ungated/wrong-arm glass symbol, file it withcross_ref: audit-swiftui-liquid-glassand let glass keep the primary. - Each domain owns its own gating in depth (state-observation, navigation-toolbars, scenes-windows,
swiftdata, previews). This skill is the catch-all net for the gates those domains missed β file
with a
cross_refto the owning domain when the symbol is clearly theirs.
The cross-cutting gating rule (point in, never restate)
The macOS-arm rule, the required * wildcard, the wrong-arm failure, and how to read a multi-platform
availability string live in <swiftui-plugin-root>/references/_shared/macos-arm-gating.md β read it,
do not restate it. Floor values are the reconciled truth in
<swiftui-plugin-root>/references/_shared/floors-master.md. The floors-master table IS this skill's
floor map (symbol β macOS floor); the LOCATE lint only finds candidate symbols, and you look each one
up there. Never restate the floor table in this package.
Defect index (gate-01 β¦ gate-08)
id Β· tell Β· severity Β· fix Β· open reference. Severities: hard-fail (build break on the target's
floor / never-correct), warning (compiles but wrong/fragile), advisory (verify-by-hand).
auto = mechanical single-answer fix; flag = show the β
, dev applies.
| id | One-line tell | Sev | Fix | Reference |
|---|---|---|---|---|
| gate-01 | an above-floor symbol used with no availability gate under a deployment target below its floor | hard-fail | flag | gating-defects.md |
| gate-02 | #available(iOS NN, *) gating a macOS-floored API in a Mac target (wrong arm β the * always fires) |
hard-fail | auto | gating-defects.md |
| gate-03 | #available(macOS NN, *) whose NN β the symbol's floor in floors-master.md (floor mismatch) |
warning | flag | gating-defects.md |
| gate-04 | an availability gate with no else where the gated view needs a pre-floor fallback |
warning | flag | gating-defects.md |
| gate-05 | an @available type/decl gate whose use site is unguarded, or a use site with no decl gate |
warning | flag | gating-defects.md |
| gate-06 | a macOS-ABSENT symbol wrapped in #available(macOS β¦) β replace, don't gate |
hard-fail | flag | absent-and-quirks.md |
| gate-07 | #available((macOS|iOS) NN) missing the trailing , * wildcard (compile error) |
hard-fail | auto | gating-defects.md |
| gate-08 | a type-property whose floor differs from its type (the DocC inheritance quirk) β verify via Sosumi | advisory | flag | absent-and-quirks.md |
gate-04 has no flat lint tell (a missing else is structural absence ast-grep cannot positively
match) β the LOCATE lint surfaces every #available(macOS β¦) gate (gate-03 tell) and you decide in the
READ step whether a fallback is required. gate-08 is surfaced during the floor cross-check in VERIFY,
not by a flat string. Never assert a floor or absence from memory β confirm it (VERIFY).
The real API, at a glance
This is the blanket sweep, so the "real API" is the floor map itself, not one symbol family:
read each located symbol's macOS floor from
<swiftui-plugin-root>/references/_shared/floors-master.md and gate it on the macOS arm at exactly that
floor. Common above-floor symbols the lint locates (each has a floor in floors-master): @Observable /
@Bindable (14.0), glassEffect & glass family (26.0), scrollEdgeEffectStyle (26.0),
backgroundExtensionEffect (26.0), symbolEffect (14.0), MeshGradient (15.0), TextRenderer (14.0),
@Model class inheritance (26.0), Tab(...)/TabSection (15.0). macOS-ABSENT (never gate, replace):
.glassBackgroundEffect() (visionOS), WheelPickerStyle, ToolbarItemPlacement.topBarLeading/.topBarTrailing,
WindowStyle.volumetric, navigationBarTitleDisplayMode, .bottomBar β the canonical list is
<swiftui-plugin-root>/references/_shared/hallucination-blacklist.md. Read, never restate.
The 8-step audit workflow (execute verbatim)
- ORIENT.
tree/findthe SwiftUI sources. Read the deployment target (project.pbxprojMACOSX_DEPLOYMENT_TARGET, orPackage.swiftplatforms:) β it is the pivot for every gate-01/03 finding. Record it. If the project ships a dual target (macOS 15 and 26), every β₯26 symbol needs a gate. - LOCATE. Run the shared hybrid lint runner:
bash <swiftui-plugin-root>/scripts/swiftui-lint.sh --skill audit-swiftui-availability-gating --dir <sources> --json /tmp/gating.json --sarif /tmp/gating.sarif. It runs this skill's tier-1 grep tells (lint/grep-tells.tsv) + tier-2 structural ast-grep rules (lint/ast-grep/*.ymlβ the wrong-arm and absent-symbol-in-gate gate-scope rules grep can't express), plus a per-file parse probe, and emits unified JSON + SARIF. Read itsparse_warningsβ a flagged file did not fully parse, so a gate hidden in an unparsed block can't masquerade as clean; READ those by hand. The runner only LOCATES. Engine + rule-file format + degradation:<swiftui-plugin-root>/references/_shared/lint-architecture.md. - READ. Open every located file in full β gate scope, container nesting, and the presence of an
elseare invisible to a flat grep. For each located symbol build an inventory: symbol Β· its floor (from floors-master) Β· the deployment target Β· is it inside a gate Β· is the gate's armmacOSΒ· is the floor right Β· is there anelse. - DETECT. Apply the index against the recorded deployment target. Assign each candidate a
confidence; report a finding only at 100% certainty (e.g. an
iOSarm wrapping a Mac symbol, amacOS 26symbol ungated under a 15.0 target, aWheelPickerStylein a Mac gate). A floored symbol whose floor is β€ the deployment target is not a finding β suppress it. - VERIFY. For anything β€ ~70% confidence (a floor you can't place, a symbol you're unsure exists, a
type-property quirk) run both evidence sources. (a) Practice β
bash <swiftui-plugin-root>/scripts/swiftui-ctx lookup <api> --json: read itsintroduced_macos(the real floor),deprecated+replacement(if set, this is a currency seam β cross_ref, don't double- report),consensus(the canonical gated shape), andrecommended/diversepermalink withmin_macos; alookupexit 3 corroborates a hallucinated/absent name. For a currency/deprecation question also runswiftui-ctx deprecated <api>. Deeper corpus evidence (deprecated-AND-above-floor): when a finding sits on a deprecated symbol, runbash <swiftui-plugin-root>/scripts/swiftui-ctx deprecated <api> --jsonfor itsreplacement, thenlookup <replacement> --introduced_macosβ a renamed API can migrate to an above-floor replacement that itself needs a gate (real corpus:tabItemβTab, andlookup Tab=introduced_macos: 15.0, so the migration creates a new macOS-15 gate; cross_ref currency, but gate the replacement here). (b) Spec β confirm the floor via Sosumi:curl -sSL https://sosumi.ai/<apple-path>usingreferences/source-directory.mdfor the path and<swiftui-plugin-root>/references/_shared/sosumi-reference.mdfor the protocol (neverWebFetchdeveloper.apple.com). Cross-checkswiftui-ctx introduced_macosagainst thefloors-master.mdvalue and the Sosumidoc:floor β they must agree. The DocC type-property quirk (gate-08): a type-property page can render the type's floor, not the property's β always re-confirm a type-property floor against Sosumi, and note.task-family doc paths can return an SPA shell (retry / use the JSON endpoint per sosumi-reference). The CLI contract is<swiftui-plugin-root>/references/_shared/swiftui-ctx-reference.md. Promote with the citation or discard. Carry any unconfirmable floor asadvisorywithsource: verify against Xcode 26 SDK. - REPORT. Write each confirmed finding (output contract below). One finding per file, zero-padded,
ordered. Emit
cross_refon a seam finding (glass β liquid-glass; deprecated-and-ungated β api-currency; a domain's own symbol β that domain). Write the run's_index.md. - FIX. Apply corrections under the fix-safety protocol
(
<swiftui-plugin-root>/references/_shared/fix-safety-protocol.md): clean-tree gate, findings-first, onlyfix_mode: auto(gate-02 arm swapiOSβmacOS; gate-07 append, *), one conventional commit per finding citing itsrule_id, never weaken a check. The β "Correct" is not a hand- written snippet β it is the swiftui-ctx consensus shape put in## Correct, backed by a real macOS-26 example fetched withbash <swiftui-plugin-root>/scripts/swiftui-ctx file <recommended.id> --smartwhose GitHub permalink (plus the Sosumidoc:) goes in## Source. The canonical gated example this skill ships (verifiedswiftui-ctx lookup glassEffectβdiverse[0],f/textream/ContentView.swift#L73,min_macos: 26) is theif #available(macOS 26.0, *) { β¦ } else { .background(.ultraThinMaterial β¦) }shape. Leaveflag-onlyfindingsopenwith that β . - DOUBLE-CHECK. Re-grep each fixed file to confirm the tell no longer matches; record it in
## Fix applied?. Re-confirm every cited floor still resolves and still says the samemacOS NN. If a fix introduced a new tell (an arm-swap that now needs anelsefallback), loop that file to DETECT.
Confidence gating (load-bearing)
Report a finding only at 100% certainty, and always relative to the recorded deployment target.
Anything β€ ~70% (a floor, an existence, a type-property quirk) goes to VERIFY (step 5) first β never emit
a speculative gate finding. Auto-fix only the two mechanical defects (gate-02 arm swap, gate-07 wildcard);
everything else is fix_mode: flag-only (the right else fallback and the right floor are judgment).
Output contract
Inherits the toolkit's unified contract (full schema + body sections + frontmatter keys:
<swiftui-plugin-root>/references/_shared/finding-schema.md β do not restate it). Specialized for this
domain:
- Findings:
swiftui-audits/availability-gating/<context>/NN-slug.md(one finding per file, zero-padded, ordered). Per-run index:swiftui-audits/availability-gating/_index.md. domain: availability-gating.fix_modeisautofor gate-02/gate-07, elseflag-only.availabilityreads fromfloors-master.md.sourceis an Apple URL + access date (fetched via Sosumi) orverify against Xcode 26 SDK.cross_refper the seam note.
Starter <context> folders (file here whenβ¦):
<context> |
File a finding here when⦠|
|---|---|
ungated-symbol/ |
an above-floor symbol ships with no gate under a sub-floor target (gate-01) |
wrong-arm/ |
a Mac-floored API is gated on the iOS arm (gate-02) |
floor-mismatch/ |
a #available(macOS NN) floor disagrees with floors-master, incl. the type-property quirk (gate-03, gate-08) |
missing-fallback/ |
a gate has no else where the view needs a pre-floor fallback (gate-04) |
decl-vs-use/ |
an @available decl gate and its #available use site disagree (gate-05) |
platform-wrong/ |
a macOS-ABSENT symbol is wrapped in a Mac gate instead of replaced (gate-06) |
missing-wildcard/ |
an #available/@available omits the trailing , * (gate-07) |
New-folder rule: if a finding does not fit any existing context folder, create a new one under
swiftui-audits/availability-gating/ with a lowercase-hyphen slug naming the sub-category, and note it
in the run's _index.md. Prefer an existing folder when the fit is reasonable; consistency across runs
is a hard requirement. Two runs over the same code produce structurally identical trees.
Reference routing
| File | Open when |
|---|---|
references/gating-defects.md |
the ungated / wrong-arm / floor-mismatch / no-else / decl-vs-use depth and βββ rewrites (gate-01/02/03/04/05/07) |
references/absent-and-quirks.md |
a macOS-ABSENT symbol (replace, don't gate) or the DocC type-property floor quirk + .task-family SPA-shell caution (gate-06/08) |
references/source-directory.md |
step VERIFY β the Apple/WWDC/practitioner source map fetched via Sosumi |
lint/grep-tells.tsv + lint/ast-grep/*.yml |
step LOCATE β this skill's declarative lint rule set (tier-1 grep tells + tier-2 structural wrong-arm/absent gate-scope rules); edit here to tune detection |
Shared toolkit references (point in, never restate):
| Shared file | For |
|---|---|
<swiftui-plugin-root>/references/_shared/floors-master.md |
every floor/availability value β this skill's floor map; the reconciled truth |
<swiftui-plugin-root>/references/_shared/macos-arm-gating.md |
the macOS-arm gating rule, the * wildcard, the wrong-arm failure, reading multi-platform strings |
<swiftui-plugin-root>/references/_shared/hallucination-blacklist.md |
the canonical macOS-ABSENT / invented-name list (gate-06) |
<swiftui-plugin-root>/references/_shared/finding-schema.md |
the unified finding schema + frontmatter keys |
<swiftui-plugin-root>/references/_shared/fix-safety-protocol.md |
the 8-point fix-safety protocol (step 7) |
<swiftui-plugin-root>/references/_shared/sosumi-reference.md |
the Apple-doc spec fetch protocol (step 5 VERIFY) |
<swiftui-plugin-root>/references/_shared/swiftui-ctx-reference.md |
the practice-corpus CLI contract β lookup/deprecated/file --smart for introduced_macos, the consensus shape + permalinked example (steps 5 VERIFY Β· 7 FIX) |
<swiftui-plugin-root>/references/_shared/cross-ref-graph.md |
seam ownership + cross_ref targets (glass β liquid-glass; deprecation β api-currency; each domain's own gating) |
Detection accelerator
bash <swiftui-plugin-root>/scripts/swiftui-lint.sh --skill audit-swiftui-availability-gating --dir <files-or-dir> [--json out.json] [--sarif out.sarif] β the toolkit's one shared hybrid lint engine, fed this
skill's declarative rules: tier-1 grep tells (lint/grep-tells.tsv,
gate-01/02/03/05/06/07) + tier-2 ast-grep structural rules (lint/ast-grep/*.yml β gate-02 wrong-arm
gate-scope, gate-06 macOS-ABSENT-symbol-in-a-macOS-gate) that grep cannot express. It runs a per-file
parse probe (surfaces "did not fully parse" so a hidden gate can't look clean), emits unified
JSON + SARIF, exits 2 on any hard-fail (gate-06/07) for a CI gate, and degrades to
grep-only with a notice if ast-grep is unreachable (npx --package @ast-grep/cli ast-grep; faster:
brew install ast-grep). It only LOCATES β always READ each hit in full before reporting (step 3), and
always judge it against the recorded deployment target. The thin scripts/gating-lint.sh is a pointer to
this runner. Engine + rule-file format + JSON/SARIF shape + safety rails:
<swiftui-plugin-root>/references/_shared/lint-architecture.md.
Install
Add Audit Swiftui Availability Gating to your client. Pick the one you use.
npx skills add yigitkonur/plugin-swiftuiInstalls every skill in the repository, then prompts for which to keep.
/plugin marketplace add yigitkonur/plugin-swiftuiAdds the repository as a plugin marketplace; install individual plugins with `/plugin install`.
git clone https://github.com/yigitkonur/plugin-swiftui
cp -r plugins/swiftui/skills/audit-swiftui-availability-gating ~/.claude/skills/A skill is a plain directory. Copy it into `.claude/skills/` in a project or in your home directory.
Score
68 / 100
Good