You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The ask (Josh): Does the cascade model — pin / filter / override / extend — hold
up against a real iOS platform well enough to commit to broader adoption work? I ran it
against Spectrum iOS's actual 742-row override log and built a real Swift consumer that
renders resolved tokens as pixels, and I'd like your async read on two things before the
Aug 28 director review: (1) is this sufficient proof to green-light the Nov 20 adoption
work, and (2) how should the remaining open gaps below be prioritized — specifically, is
schema validation of extensions.tokens (9osr) and the iOS vocabulary crosswalk
(h890.15/16/17) blocking for adoption, or follow-up? The two gaps I'd flagged as most
load-bearing for this decision — legacy-slug override targeting and alias type-safety —
turned out to be narrow sdk/core implementation bugs and are already fixed, so the
question is really whether the model is proven, not the engine.
Background
This POC is the concrete commitment from the July 31 director review (bd spectrum-design-data-7mt / task -7mt.3, due Aug 28). The decision there was: web
declared success on the cascade KR, but cascade is proven on iOS first, not web — so
before the real Nov 20 adoption work we build a non-production POC that tests the
manifest/cascade model against a real platform, with your review as part of the
acceptance criteria. This is that review. Initiative DNA-1522 (adaptive support per
platform).
What was built
Two halves, both against real iOS data (Spectrum iOS's actual spectrum-tokens-ios
package and its ios-tokens/override-log.csv — 742 real overrides, not fabricated):
Data side — a real iOS Layer-2 manifest.json cascading over a remotely-fetched
foundation. .design-data.toml pins the foundation via the github source (release
tarball over pure HTTPS — no Node, no git binary) at @adobe/spectrum-tokens@15.1.0,
with a top-level, source-independent manifest key that cascades on top: foundationVersion pin, include/exclude query filters, typed overrides targeted
by UUID, and extensions.tokens (net-new + increased-contrast tokens).
Real consumer — a minimal Swift executable (consumer/, swift run spectrum-demo)
that reads resolved cascade output and renders it as truecolor terminal swatches: one
foundation color, one override (teal, visibly distinct from the foundation blue it sits
on), one contrast=high extension token. The cascade now reaches a rendered pixel, not
just a JSON diff. → PR Adding Semantic Release #2 (feat/swift-consumer-poc): Add Swift consumer rendering resolved cascade tokens GarthDB/spectrum-ios-design-data#2
Why the data shape matters: classifying the 742 real iOS overrides, the dominant
pattern (399, ~54%) is adding increased-contrast color variants, not changing
existing values — and foundation ships zero tokens with a high contrast value, so there
is no existing record to override. The POC's central finding is that these belong in extensions, not overrides. The model handled that cleanly.
What was verified
Commands run against the real fetched/local dataset (CLI built from sdk/):
Remote pin + manifest cascade compose end-to-end.github-pinned foundation +
top-level manifest key: the CLI fetches/caches the tagged release tarball (pure
HTTPS), then applies the manifest on top. resolve color reports File: manifest.json
for extension tokens; filters/overrides/extensions all materialize against the fetched
source.
Filtering works.query --filter "property=color" returns 1587 with no
manifest; with this manifest's exclude: ["colorScheme=wireframe"], it drops to 1136 — the wireframe-scheme color tokens are correctly removed.
Extensions materialize and are queryable. With the manifest configured, property=color,state=pressed returns exactly the 2 net-new accent-background-color-pressed records, and property=color,contrast=high returns
exactly the 2contrast=high records — none of which exist in foundation.
Overrides land as new Platform-layer records. The two UUID-targeted disabled
overrides moved property=color,state=disabled from 7 → 9: the original alias
records are untouched, plus 2 new synthetic records carrying the override's literal
value. (query shows all layers; only resolve applies Foundation < Platform <
Product precedence — a distinction worth documenting so nobody counts query output as
"what a platform ships.")
Gaps found
Organized by whether they block Nov 20 adoption.
Load-bearing for this decision — found in the POC, now FIXED (narrow sdk/core bugs, not spec problems):
Legacy-slug override targeting silently no-oped (bd spectrum-design-data-8bkb, closed). Targeting an override by its human-readable legacy name (what an override
log like iOS's actually speaks) hit the graph's internal-key lookup, not the legacy_name_index — so it dropped with no error and no effect; only a UUID worked.
This was the single biggest usability risk for anyone hand-authoring a manifest, and
it's fixed.
Type-safety guard skipped alias-only targets (bd spectrum-design-data-c3qw, closed). The "overrides MUST NOT change resolved type" check only ran when the
matched foundation record carried a literal value; both real override targets are pure $ref aliases, so the guard was skipped and an override could change a color to a
number with no error. Alias-typed tokens are the majority of the color corpus, so this
covered most real overrides — now fixed.
That both turned out to be small, well-understood implementation fixes (rather than model
flaws) is the core of why I think the model itself is sound.
Independently reviewed: both fixes (#1356, #1365) were traced end-to-end against sdk/core/src/graph.rs — all cross-file callers checked, the full 23-test graph:: suite
green, no regressions. Each is a strict superset of prior behavior, not a narrowing.
Also fixed along the way:
query/resolve positional PATH ignored the configured tokens root (bd spectrum-design-data-jl7t, closed) — passing . loaded whatever *.json sat in
cwd instead of the configured dataset. Fixed to consult resolved.tokens_root.
Open — for your prioritization call (blocking vs. follow-up):
extensions.tokens isn't schema-validated (bd spectrum-design-data-9osr, in progress, started Aug 25). manifest.schema.json only declares formatting under extensions;
everything else passes via additionalProperties: true, so a malformed extension token
fails silently/downstream, not at validation time. Is this a prerequisite for adoption,
or a hardening follow-up?
iOS vocabulary crosswalk (bd spectrum-design-data-h890.15 typography/size row
import, -h890.16elevated colorScheme foundation gap, -h890.17 registry ergonomics
for increased↔high / pressed/down, all open). The importer skipped 10 elevated rows and 14 unresolved rows; increased→high is modeled here but not
registered anywhere else. Which of these must land before adoption vs. alongside it?
Foundation version pin. iOS's real current pin (@adobe/spectrum-tokens@13.0.0)
predates the cascade format entirely — a real adoption manifest can't target it; iOS
would need to move its pin to a cascade-format release (15.0.0+) as a prerequisite,
independent of the manifest work.
Android
Not built this pass, deliberately. The manifest/cascade engine
(TokenGraph::apply_platform_manifest, sdk/core/src/graph.rs) is platform-agnostic — it
consumes the same manifest.json and emits the same resolve/query --format json
regardless of consumer. An Android consumer would read that identical JSON; the only new
work is the rendering side (Kotlin instead of Swift), i.e. a codegen-target swap, not a
model change. Question for you: do you want an Android pass before sign-off, or is the
iOS proof sufficient that we treat Android as a downstream codegen target?
Out of scope
Proof of concept only. No production hardening, no Kotlin/Xcode app, no published starter
repo — this is a personal POC sandbox to prove the model before Nov 20, nothing more.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The ask (Josh): Does the cascade model — pin / filter / override / extend — hold
up against a real iOS platform well enough to commit to broader adoption work? I ran it
against Spectrum iOS's actual 742-row override log and built a real Swift consumer that
renders resolved tokens as pixels, and I'd like your async read on two things before the
Aug 28 director review: (1) is this sufficient proof to green-light the Nov 20 adoption
work, and (2) how should the remaining open gaps below be prioritized — specifically, is
schema validation of
extensions.tokens(9osr) and the iOS vocabulary crosswalk(
h890.15/16/17) blocking for adoption, or follow-up? The two gaps I'd flagged as mostload-bearing for this decision — legacy-slug override targeting and alias type-safety —
turned out to be narrow
sdk/coreimplementation bugs and are already fixed, so thequestion is really whether the model is proven, not the engine.
Background
This POC is the concrete commitment from the July 31 director review (bd
spectrum-design-data-7mt/ task-7mt.3, due Aug 28). The decision there was: webdeclared success on the cascade KR, but cascade is proven on iOS first, not web — so
before the real Nov 20 adoption work we build a non-production POC that tests the
manifest/cascade model against a real platform, with your review as part of the
acceptance criteria. This is that review. Initiative
DNA-1522(adaptive support perplatform).
What was built
Two halves, both against real iOS data (Spectrum iOS's actual
spectrum-tokens-iospackage and its
ios-tokens/override-log.csv— 742 real overrides, not fabricated):manifest.jsoncascading over a remotely-fetchedfoundation.
.design-data.tomlpins the foundation via thegithubsource (releasetarball over pure HTTPS — no Node, no git binary) at
@adobe/spectrum-tokens@15.1.0,with a top-level, source-independent
manifestkey that cascades on top:foundationVersionpin,include/excludequery filters, typedoverridestargetedby UUID, and
extensions.tokens(net-new + increased-contrast tokens).consumer/,swift run spectrum-demo)that reads resolved cascade output and renders it as truecolor terminal swatches: one
foundation color, one override (teal, visibly distinct from the foundation blue it sits
on), one
contrast=highextension token. The cascade now reaches a rendered pixel, notjust a JSON diff. → PR Adding Semantic Release #2 (
feat/swift-consumer-poc):Add Swift consumer rendering resolved cascade tokens GarthDB/spectrum-ios-design-data#2
Why the data shape matters: classifying the 742 real iOS overrides, the dominant
pattern (399, ~54%) is adding increased-contrast color variants, not changing
existing values — and foundation ships zero tokens with a
highcontrast value, so thereis no existing record to override. The POC's central finding is that these belong in
extensions, notoverrides. The model handled that cleanly.What was verified
Commands run against the real fetched/local dataset (CLI built from
sdk/):github-pinned foundation +top-level
manifestkey: the CLI fetches/caches the tagged release tarball (pureHTTPS), then applies the manifest on top.
resolve colorreportsFile: manifest.jsonfor extension tokens; filters/overrides/extensions all materialize against the fetched
source.
query --filter "property=color"returns 1587 with nomanifest; with this manifest's
exclude: ["colorScheme=wireframe"], it drops to1136 — the wireframe-scheme color tokens are correctly removed.
property=color,state=pressedreturns exactly the 2 net-newaccent-background-color-pressedrecords, andproperty=color,contrast=highreturnsexactly the 2
contrast=highrecords — none of which exist in foundation.overrides moved
property=color,state=disabledfrom 7 → 9: the original aliasrecords are untouched, plus 2 new synthetic records carrying the override's literal
value. (
queryshows all layers; onlyresolveapplies Foundation < Platform <Product precedence — a distinction worth documenting so nobody counts
queryoutput as"what a platform ships.")
Gaps found
Organized by whether they block Nov 20 adoption.
Load-bearing for this decision — found in the POC, now FIXED (narrow
sdk/corebugs, not spec problems):spectrum-design-data-8bkb,closed). Targeting an override by its human-readable legacy name (what an override
log like iOS's actually speaks) hit the graph's internal-key lookup, not the
legacy_name_index— so it dropped with no error and no effect; only a UUID worked.This was the single biggest usability risk for anyone hand-authoring a manifest, and
it's fixed.
spectrum-design-data-c3qw,closed). The "overrides MUST NOT change resolved type" check only ran when the
matched foundation record carried a literal
value; both real override targets are pure$refaliases, so the guard was skipped and an override could change a color to anumber with no error. Alias-typed tokens are the majority of the color corpus, so this
covered most real overrides — now fixed.
That both turned out to be small, well-understood implementation fixes (rather than model
flaws) is the core of why I think the model itself is sound.
Independently reviewed: both fixes (#1356, #1365) were traced end-to-end against
sdk/core/src/graph.rs— all cross-file callers checked, the full 23-testgraph::suitegreen, no regressions. Each is a strict superset of prior behavior, not a narrowing.
Also fixed along the way:
query/resolvepositional PATH ignored the configured tokens root (bdspectrum-design-data-jl7t, closed) — passing.loaded whatever*.jsonsat incwd instead of the configured dataset. Fixed to consult
resolved.tokens_root.Open — for your prioritization call (blocking vs. follow-up):
extensions.tokensisn't schema-validated (bdspectrum-design-data-9osr,in progress, started Aug 25).
manifest.schema.jsononly declaresformattingunderextensions;everything else passes via
additionalProperties: true, so a malformed extension tokenfails silently/downstream, not at validation time. Is this a prerequisite for adoption,
or a hardening follow-up?
spectrum-design-data-h890.15typography/size rowimport,
-h890.16elevatedcolorScheme foundation gap,-h890.17registry ergonomicsfor
increased↔high/pressed/down, all open). The importer skipped 10elevatedrows and 14 unresolved rows;increased→highis modeled here but notregistered anywhere else. Which of these must land before adoption vs. alongside it?
@adobe/spectrum-tokens@13.0.0)predates the cascade format entirely — a real adoption manifest can't target it; iOS
would need to move its pin to a cascade-format release (
15.0.0+) as a prerequisite,independent of the manifest work.
Android
Not built this pass, deliberately. The manifest/cascade engine
(
TokenGraph::apply_platform_manifest,sdk/core/src/graph.rs) is platform-agnostic — itconsumes the same
manifest.jsonand emits the sameresolve/query --format jsonregardless of consumer. An Android consumer would read that identical JSON; the only new
work is the rendering side (Kotlin instead of Swift), i.e. a codegen-target swap, not a
model change. Question for you: do you want an Android pass before sign-off, or is the
iOS proof sufficient that we treat Android as a downstream codegen target?
Out of scope
Proof of concept only. No production hardening, no Kotlin/Xcode app, no published starter
repo — this is a personal POC sandbox to prove the model before Nov 20, nothing more.
Links
spectrum-design-data-7mt.3(task),-7mt(epic), initiativeDNA-1522All reactions