Skip to content

Commit 435824b

Browse files
Merge pull request #10 from pavelevgrafov/fix-d41-tailwind-optional
Fix D.41 over-reach: the Tailwind bridge is optional, the CSS is not
2 parents cb75497 + 31859d0 commit 435824b

3 files changed

Lines changed: 52 additions & 7 deletions

File tree

.agents/skills/visual-director/scripts/compile-tokens.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,28 @@ def first_difference(have, want):
149149
def main():
150150
ap = argparse.ArgumentParser()
151151
ap.add_argument("tokens", nargs="?", default="tokens.json")
152-
ap.add_argument("--out-css", default="tokens.css")
153-
ap.add_argument("--out-tailwind", default="tokens.theme.css")
152+
ap.add_argument("--out-css", default=None)
153+
ap.add_argument("--out-tailwind", default=None)
154154
ap.add_argument("--check-only", action="store_true")
155155
ap.add_argument("--verify", action="store_true",
156156
help="D.41: fail if the files on disk differ from what "
157157
"this run would write")
158158
args = ap.parse_args()
159159

160+
# --verify against the DEFAULT paths compares the tokens with whatever
161+
# happens to sit in the working directory, and reports "missing" when
162+
# nothing does. That reads exactly like real staleness and is not — it cost
163+
# a reviewer a diff hunt on the day D.41 shipped. The floor always passes
164+
# explicit paths, so requiring them costs nothing and removes the false
165+
# alarm entirely.
166+
if args.verify and not (args.out_css and args.out_tailwind):
167+
print("FAIL: --verify needs explicit --out-css and --out-tailwind. "
168+
"Comparing against the defaults would measure the working "
169+
"directory, not the theme that belongs to these tokens.")
170+
return 2
171+
args.out_css = args.out_css or "tokens.css"
172+
args.out_tailwind = args.out_tailwind or "tokens.theme.css"
173+
160174
problems = []
161175
try:
162176
with open(args.tokens, encoding="utf-8") as f:
@@ -235,23 +249,37 @@ def main():
235249
return 1
236250

237251
if args.verify:
238-
stale = []
239-
for path, want in ((args.out_css, css), (args.out_tailwind, tw)):
252+
# The CSS is what the floor reads and what the browser renders, so its
253+
# absence IS staleness. The Tailwind bridge is optional: a project that
254+
# does not use Tailwind never emits one, and demanding it would fail
255+
# every such project for a file it has no use for. Absent is reported,
256+
# never silently treated as fresh [A.6]; present is always compared.
257+
stale, notes = [], []
258+
checked = 0
259+
for path, want, required in ((args.out_css, css, True),
260+
(args.out_tailwind, tw, False)):
240261
try:
241262
with open(path, encoding="utf-8") as f:
242263
have = f.read()
243264
except FileNotFoundError:
244-
stale.append(f"{path}: missing — the theme was never compiled")
265+
if required:
266+
stale.append(f"{path}: missing — the theme was never compiled")
267+
else:
268+
notes.append(f"{path}: absent — no Tailwind bridge in this "
269+
f"project, nothing to go stale")
245270
continue
271+
checked += 1
246272
if have != want:
247273
stale.append(f"{path}: {first_difference(have, want)}")
274+
for n in notes:
275+
print(f"note: {n}")
248276
for s in stale:
249277
print(f"FAIL: {s}")
250278
if stale:
251279
print(f"\n{len(stale)} compiled file(s) no longer match {args.tokens} "
252280
f"[D.41]. Re-run compile-tokens.py; never hand-edit the output.")
253281
return 1
254-
print(f"OK: compiled theme matches {args.tokens} [D.41]")
282+
print(f"OK: {checked} compiled file(s) match {args.tokens} [D.41]")
255283
return 0
256284

257285
if args.check_only:

.github/workflows/design-ops.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ jobs:
8585
--out /tmp/e2e/site --ux-out /tmp/e2e/artifacts/ux \
8686
--contract /tmp/e2e/artifacts/design-contract.yaml
8787
grep -q "origin: inherited" /tmp/e2e/artifacts/design-contract.yaml
88-
cp skins/base-site/tokens.json skins/base-site/tokens.css /tmp/e2e/artifacts/visual/
88+
# all three files a real K2A leaves behind, not two of them:
89+
# a materialisation thinner than the real thing makes the floor
90+
# measure a project that never exists (D.41 caught this)
91+
cp skins/base-site/tokens.json skins/base-site/tokens.css \
92+
skins/base-site/tokens.theme.css /tmp/e2e/artifacts/visual/
8993
cp skins/base-site/tokens.css /tmp/e2e/site/tokens.css
9094
sed -i 's|\.\./\.\./\.\./skins/base-site/tokens.css|tokens.css|' /tmp/e2e/site/index.html
9195
- name: Self-service panel on the real build

eval/selftest/run-self-test.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,19 @@ for SKIN in base-site base-app; do
442442
done
443443
[ "$D41BAD" -eq 0 ] && ok "D.41: both skins ship a fresh theme, and one edited line fails the build"
444444

445+
# The Tailwind bridge is optional; the CSS is not. A project that never emits
446+
# a bridge must pass, and a project missing the CSS itself must not — the
447+
# post-merge run on main failed on exactly this over-reach, because the CI
448+
# materialisation copied two of the three files a real K2A leaves behind.
449+
D41OPT=$(mktemp -d 2>/dev/null || mktemp -d -t d41o)
450+
cp "$ROOT/skins/base-site/tokens.json" "$ROOT/skins/base-site/tokens.css" "$D41OPT/"
451+
python3 "$VD/compile-tokens.py" "$D41OPT/tokens.json" --out-css "$D41OPT/tokens.css" --out-tailwind "$D41OPT/tokens.theme.css" --verify >/dev/null 2>&1 && rm -f "$D41OPT/tokens.css" && ! python3 "$VD/compile-tokens.py" "$D41OPT/tokens.json" --out-css "$D41OPT/tokens.css" --out-tailwind "$D41OPT/tokens.theme.css" --verify >/dev/null 2>&1 && ok "D.41: a project with no Tailwind bridge passes, a project with no CSS does not" || bad "D.41 treats the optional bridge and the required CSS alike"
452+
453+
# ...and --verify refuses to guess its own paths, which is how a reviewer got a
454+
# false 'missing' on the day D.41 shipped.
455+
python3 "$VD/compile-tokens.py" "$ROOT/skins/base-site/tokens.json" --verify >/dev/null 2>&1
456+
[ "$?" -eq 2 ] && ok "D.41: --verify against default paths is refused, not answered" || bad "D.41 --verify still compares against whatever is in the working directory"
457+
445458
# --- [Т-1] the declared dark ramp ----------------------------------------
446459
# The dark theme used to live in a comment ("87/60/38% over #121212") next to
447460
# sixteen literals nobody could check against it. Now the sentence is

0 commit comments

Comments
 (0)