fix(recetas): el panic de zbus-lockstep SÍ se dispara — y «error[E0432]» no era la causa
`pata-notify-triage` pasó el pkg-config con los deps nuevos y murió compilando `atspi-common`. El log mostraba seis clases de error de Rust, y la primera lectura —la mía— fue «incompatibilidad de versiones». Mirando los errores completos: ``` error: custom attribute panicked (×5) error[E0432]: unresolved imports `object_ref::ObjectRef`, `object_ref::ObjectRefOwned` ``` **Los `E0432` son CONSECUENCIA, no causa**: el `#[validate]` de `zbus-lockstep-macros` panica y los tipos nunca se generan, así que lo que se lee primero está lejos de lo que importa. Es el panic conocido: `accesskit` → `atspi` → `atspi-common`, cuyo macro recorre `xml/` llamando `.extension().expect()` en cada entrada y revienta con el subdirectorio `xml/schemas/`. ⚠ **Y esto desmiente lo que `cadcraft.toml` anotó HOY MISMO.** Esa receta dice: «el panic de `zbus-lockstep-macros` NO se dispara en estas versiones», generalizando desde que `vectorcraft` compiló sin el bloque. Con las **mismas versiones** —`atspi-common` 0.13.0 + `zbus-lockstep-macros` 0.5.2— acá sí se dispara. ⇒ La lección, que vale más que el arreglo: **que una receta compile sin el bloque no prueba que el bloque no haga falta — prueba que ESE binario no llegó a esa rama del grafo de features.** Lo mismo que esa receta ya había aprendido sobre los features de `eframe`, que son aditivos y los enciende otro miembro del workspace. Queda escrito en las seis. Entra la fase `compile` con `LOCKSTEP_XML_PATH` tal como la tienen `boveda` y `mirada-greeter`, con su comprobante a gritos: un `cp` mudo dejaría la variable apuntando a un dir vacío y el panic volvería sin su causa. Y se unifican los deps de `pata-notify-triage` con el set probado, en vez de dejar el mínimo que yo había deducido del primer fallo: adivinar la lista corta ya me costó una vuelta. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
6 archivos · +195 −1
- recipes/churay-metal.toml +32 −0
- recipes/pata-centro.toml +32 −0
- recipes/pata-llimphi.toml +32 −0
- recipes/pata-notify-panel.toml +32 −0
- recipes/pata-notify-triage.toml +35 −1
- recipes/pata-notify.toml +32 −0
diff --git a/recipes/churay-metal.toml b/recipes/churay-metal.toml
index a01021d2..7c6c63d3 100644
--- a/recipes/churay-metal.toml
+++ b/recipes/churay-metal.toml
@@ -23,6 +23,38 @@ link = "dynamic"
# motivo que \`llimphi-counter\`, que es la plantilla probada del stack llimphi.
flags = ["-p", "churay-metal", "--bin", "churay-metal"]
+[build.phases]
+# ⚠ LOCKSTEP_XML_PATH — y acá el panic SÍ SE DISPARA, contra lo que dice `cadcraft.toml`.
+# Esa receta anotó el 2026-10-13 que «el panic de `zbus-lockstep-macros` NO se dispara en estas
+# versiones», generalizando desde que `vectorcraft` compiló sin el bloque. Medido hoy con las MISMAS
+# versiones —`atspi-common` 0.13.0 + `zbus-lockstep-macros` 0.5.2— este binario muere así:
+#
+# error: custom attribute panicked (×5)
+# error[E0432]: unresolved imports `object_ref::ObjectRef`, …
+#
+# Los `E0432` son CONSECUENCIA, no causa: el `#[validate]` panica y los tipos nunca se generan, así
+# que el error que se lee está lejos del que importa. La cadena es `accesskit` → `atspi` →
+# `atspi-common`, cuyo `#[validate]` recorre `xml/` llamando `.extension().expect()` en cada entrada
+# y PANICA al toparse con el subdirectorio `xml/schemas/`. Apuntar la variable a un dir con sólo los
+# `.xml` lo evita.
+#
+# ⇒ Que una receta compile sin el bloque NO prueba que el bloque no haga falta: prueba que ESE
+# binario no llegó a esa rama del grafo de features. El comprobante del `ls` es a gritos a propósito
+# — un `cp` mudo dejaría la variable apuntando a un dir vacío y el panic volvería sin su causa.
+compile = '''
+set -e
+XMLDIR="$PWD/.atspi-lockstep-xml"
+mkdir -p "$XMLDIR"
+ls .hammer-cargo-vendor/atspi-common/xml/*.xml >/dev/null 2>&1 || { echo "no hay .hammer-cargo-vendor/atspi-common/xml/*.xml — ¿cambió el vendoreo o la versión de atspi? sin esto zbus-lockstep-macros panica en xml/schemas/" >&2; exit 1; }
+cp .hammer-cargo-vendor/atspi-common/xml/*.xml "$XMLDIR"/
+export LOCKSTEP_XML_PATH="$XMLDIR"
+printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec zig cc -mcpu=baseline "$@"' > "$PWD/.hammer-zig-cc"
+chmod +x "$PWD/.hammer-zig-cc"
+RF="-C linker=$PWD/.hammer-zig-cc"
+rustc -vV | grep -q 'host: .*-alpine-' || RF="$RF -C link-self-contained=no"
+CC="$PWD/.hammer-zig-cc" RUSTFLAGS="$RF" cargo rustc --release --locked --offline -p churay-metal --bin churay-metal -- -C target-feature=-crt-static
+'''
+
[deps]
# El set de deps sale de `recipes/churay.toml`, la receta de la cara *hybrid* que OTRO AGENTE ya
# tenía escrita (sin commitear) con esta lista probada. Adoptarla en vez de adivinarla es lo que
diff --git a/recipes/pata-centro.toml b/recipes/pata-centro.toml
index d28c5c15..768c6af4 100644
--- a/recipes/pata-centro.toml
+++ b/recipes/pata-centro.toml
@@ -25,6 +25,38 @@ link = "dynamic"
# motivo que \`llimphi-counter\`, que es la plantilla probada del stack llimphi.
flags = ["-p", "pata-centro-llimphi", "--bin", "pata-centro"]
+[build.phases]
+# ⚠ LOCKSTEP_XML_PATH — y acá el panic SÍ SE DISPARA, contra lo que dice `cadcraft.toml`.
+# Esa receta anotó el 2026-10-13 que «el panic de `zbus-lockstep-macros` NO se dispara en estas
+# versiones», generalizando desde que `vectorcraft` compiló sin el bloque. Medido hoy con las MISMAS
+# versiones —`atspi-common` 0.13.0 + `zbus-lockstep-macros` 0.5.2— este binario muere así:
+#
+# error: custom attribute panicked (×5)
+# error[E0432]: unresolved imports `object_ref::ObjectRef`, …
+#
+# Los `E0432` son CONSECUENCIA, no causa: el `#[validate]` panica y los tipos nunca se generan, así
+# que el error que se lee está lejos del que importa. La cadena es `accesskit` → `atspi` →
+# `atspi-common`, cuyo `#[validate]` recorre `xml/` llamando `.extension().expect()` en cada entrada
+# y PANICA al toparse con el subdirectorio `xml/schemas/`. Apuntar la variable a un dir con sólo los
+# `.xml` lo evita.
+#
+# ⇒ Que una receta compile sin el bloque NO prueba que el bloque no haga falta: prueba que ESE
+# binario no llegó a esa rama del grafo de features. El comprobante del `ls` es a gritos a propósito
+# — un `cp` mudo dejaría la variable apuntando a un dir vacío y el panic volvería sin su causa.
+compile = '''
+set -e
+XMLDIR="$PWD/.atspi-lockstep-xml"
+mkdir -p "$XMLDIR"
+ls .hammer-cargo-vendor/atspi-common/xml/*.xml >/dev/null 2>&1 || { echo "no hay .hammer-cargo-vendor/atspi-common/xml/*.xml — ¿cambió el vendoreo o la versión de atspi? sin esto zbus-lockstep-macros panica en xml/schemas/" >&2; exit 1; }
+cp .hammer-cargo-vendor/atspi-common/xml/*.xml "$XMLDIR"/
+export LOCKSTEP_XML_PATH="$XMLDIR"
+printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec zig cc -mcpu=baseline "$@"' > "$PWD/.hammer-zig-cc"
+chmod +x "$PWD/.hammer-zig-cc"
+RF="-C linker=$PWD/.hammer-zig-cc"
+rustc -vV | grep -q 'host: .*-alpine-' || RF="$RF -C link-self-contained=no"
+CC="$PWD/.hammer-zig-cc" RUSTFLAGS="$RF" cargo rustc --release --locked --offline -p pata-centro-llimphi --bin pata-centro -- -C target-feature=-crt-static
+'''
+
[deps]
# Mismo set que `churay-metal`: cliente Wayland con stack gráfico.
build = ["mesa", "wayland", "wayland-protocols", "libdrm", "libxkbcommon", "expat", "zlib", "zstd", "libffi", "pkgconf"]
diff --git a/recipes/pata-llimphi.toml b/recipes/pata-llimphi.toml
index d2c11e52..91b50316 100644
--- a/recipes/pata-llimphi.toml
+++ b/recipes/pata-llimphi.toml
@@ -23,6 +23,38 @@ link = "dynamic"
# motivo que \`llimphi-counter\`, que es la plantilla probada del stack llimphi.
flags = ["-p", "pata-llimphi", "--bin", "pata-llimphi"]
+[build.phases]
+# ⚠ LOCKSTEP_XML_PATH — y acá el panic SÍ SE DISPARA, contra lo que dice `cadcraft.toml`.
+# Esa receta anotó el 2026-10-13 que «el panic de `zbus-lockstep-macros` NO se dispara en estas
+# versiones», generalizando desde que `vectorcraft` compiló sin el bloque. Medido hoy con las MISMAS
+# versiones —`atspi-common` 0.13.0 + `zbus-lockstep-macros` 0.5.2— este binario muere así:
+#
+# error: custom attribute panicked (×5)
+# error[E0432]: unresolved imports `object_ref::ObjectRef`, …
+#
+# Los `E0432` son CONSECUENCIA, no causa: el `#[validate]` panica y los tipos nunca se generan, así
+# que el error que se lee está lejos del que importa. La cadena es `accesskit` → `atspi` →
+# `atspi-common`, cuyo `#[validate]` recorre `xml/` llamando `.extension().expect()` en cada entrada
+# y PANICA al toparse con el subdirectorio `xml/schemas/`. Apuntar la variable a un dir con sólo los
+# `.xml` lo evita.
+#
+# ⇒ Que una receta compile sin el bloque NO prueba que el bloque no haga falta: prueba que ESE
+# binario no llegó a esa rama del grafo de features. El comprobante del `ls` es a gritos a propósito
+# — un `cp` mudo dejaría la variable apuntando a un dir vacío y el panic volvería sin su causa.
+compile = '''
+set -e
+XMLDIR="$PWD/.atspi-lockstep-xml"
+mkdir -p "$XMLDIR"
+ls .hammer-cargo-vendor/atspi-common/xml/*.xml >/dev/null 2>&1 || { echo "no hay .hammer-cargo-vendor/atspi-common/xml/*.xml — ¿cambió el vendoreo o la versión de atspi? sin esto zbus-lockstep-macros panica en xml/schemas/" >&2; exit 1; }
+cp .hammer-cargo-vendor/atspi-common/xml/*.xml "$XMLDIR"/
+export LOCKSTEP_XML_PATH="$XMLDIR"
+printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec zig cc -mcpu=baseline "$@"' > "$PWD/.hammer-zig-cc"
+chmod +x "$PWD/.hammer-zig-cc"
+RF="-C linker=$PWD/.hammer-zig-cc"
+rustc -vV | grep -q 'host: .*-alpine-' || RF="$RF -C link-self-contained=no"
+CC="$PWD/.hammer-zig-cc" RUSTFLAGS="$RF" cargo rustc --release --locked --offline -p pata-llimphi --bin pata-llimphi -- -C target-feature=-crt-static
+'''
+
[deps]
# Mismo set que `churay-metal`: cliente Wayland con stack gráfico.
build = ["mesa", "wayland", "wayland-protocols", "libdrm", "libxkbcommon", "expat", "zlib", "zstd", "libffi", "pkgconf"]
diff --git a/recipes/pata-notify-panel.toml b/recipes/pata-notify-panel.toml
index a1df46e5..0970e0ee 100644
--- a/recipes/pata-notify-panel.toml
+++ b/recipes/pata-notify-panel.toml
@@ -23,6 +23,38 @@ link = "dynamic"
# motivo que \`llimphi-counter\`, que es la plantilla probada del stack llimphi.
flags = ["-p", "pata-notify-panel", "--bin", "pata-notify-panel"]
+[build.phases]
+# ⚠ LOCKSTEP_XML_PATH — y acá el panic SÍ SE DISPARA, contra lo que dice `cadcraft.toml`.
+# Esa receta anotó el 2026-10-13 que «el panic de `zbus-lockstep-macros` NO se dispara en estas
+# versiones», generalizando desde que `vectorcraft` compiló sin el bloque. Medido hoy con las MISMAS
+# versiones —`atspi-common` 0.13.0 + `zbus-lockstep-macros` 0.5.2— este binario muere así:
+#
+# error: custom attribute panicked (×5)
+# error[E0432]: unresolved imports `object_ref::ObjectRef`, …
+#
+# Los `E0432` son CONSECUENCIA, no causa: el `#[validate]` panica y los tipos nunca se generan, así
+# que el error que se lee está lejos del que importa. La cadena es `accesskit` → `atspi` →
+# `atspi-common`, cuyo `#[validate]` recorre `xml/` llamando `.extension().expect()` en cada entrada
+# y PANICA al toparse con el subdirectorio `xml/schemas/`. Apuntar la variable a un dir con sólo los
+# `.xml` lo evita.
+#
+# ⇒ Que una receta compile sin el bloque NO prueba que el bloque no haga falta: prueba que ESE
+# binario no llegó a esa rama del grafo de features. El comprobante del `ls` es a gritos a propósito
+# — un `cp` mudo dejaría la variable apuntando a un dir vacío y el panic volvería sin su causa.
+compile = '''
+set -e
+XMLDIR="$PWD/.atspi-lockstep-xml"
+mkdir -p "$XMLDIR"
+ls .hammer-cargo-vendor/atspi-common/xml/*.xml >/dev/null 2>&1 || { echo "no hay .hammer-cargo-vendor/atspi-common/xml/*.xml — ¿cambió el vendoreo o la versión de atspi? sin esto zbus-lockstep-macros panica en xml/schemas/" >&2; exit 1; }
+cp .hammer-cargo-vendor/atspi-common/xml/*.xml "$XMLDIR"/
+export LOCKSTEP_XML_PATH="$XMLDIR"
+printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec zig cc -mcpu=baseline "$@"' > "$PWD/.hammer-zig-cc"
+chmod +x "$PWD/.hammer-zig-cc"
+RF="-C linker=$PWD/.hammer-zig-cc"
+rustc -vV | grep -q 'host: .*-alpine-' || RF="$RF -C link-self-contained=no"
+CC="$PWD/.hammer-zig-cc" RUSTFLAGS="$RF" cargo rustc --release --locked --offline -p pata-notify-panel --bin pata-notify-panel -- -C target-feature=-crt-static
+'''
+
[deps]
# Mismo set que `churay-metal`. Mi primera versión salió sin `[deps]` y murió en
# `smithay-client-toolkit/build.rs` pidiendo `xkbcommon.pc` por pkg-config.
diff --git a/recipes/pata-notify-triage.toml b/recipes/pata-notify-triage.toml
index 47d660b1..a3942b00 100644
--- a/recipes/pata-notify-triage.toml
+++ b/recipes/pata-notify-triage.toml
@@ -30,7 +30,41 @@ target = "x86_64-linux-musl"
link = "dynamic"
flags = ["-p", "pata-notify-triage", "--bin", "pata-notify-triage"]
+[build.phases]
+# ⚠ LOCKSTEP_XML_PATH — y acá el panic SÍ SE DISPARA, contra lo que dice `cadcraft.toml`.
+# Esa receta anotó el 2026-10-13 que «el panic de `zbus-lockstep-macros` NO se dispara en estas
+# versiones», generalizando desde que `vectorcraft` compiló sin el bloque. Medido hoy con las MISMAS
+# versiones —`atspi-common` 0.13.0 + `zbus-lockstep-macros` 0.5.2— este binario muere así:
+#
+# error: custom attribute panicked (×5)
+# error[E0432]: unresolved imports `object_ref::ObjectRef`, …
+#
+# Los `E0432` son CONSECUENCIA, no causa: el `#[validate]` panica y los tipos nunca se generan, así
+# que el error que se lee está lejos del que importa. La cadena es `accesskit` → `atspi` →
+# `atspi-common`, cuyo `#[validate]` recorre `xml/` llamando `.extension().expect()` en cada entrada
+# y PANICA al toparse con el subdirectorio `xml/schemas/`. Apuntar la variable a un dir con sólo los
+# `.xml` lo evita.
+#
+# ⇒ Que una receta compile sin el bloque NO prueba que el bloque no haga falta: prueba que ESE
+# binario no llegó a esa rama del grafo de features. El comprobante del `ls` es a gritos a propósito
+# — un `cp` mudo dejaría la variable apuntando a un dir vacío y el panic volvería sin su causa.
+compile = '''
+set -e
+XMLDIR="$PWD/.atspi-lockstep-xml"
+mkdir -p "$XMLDIR"
+ls .hammer-cargo-vendor/atspi-common/xml/*.xml >/dev/null 2>&1 || { echo "no hay .hammer-cargo-vendor/atspi-common/xml/*.xml — ¿cambió el vendoreo o la versión de atspi? sin esto zbus-lockstep-macros panica en xml/schemas/" >&2; exit 1; }
+cp .hammer-cargo-vendor/atspi-common/xml/*.xml "$XMLDIR"/
+export LOCKSTEP_XML_PATH="$XMLDIR"
+printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec zig cc -mcpu=baseline "$@"' > "$PWD/.hammer-zig-cc"
+chmod +x "$PWD/.hammer-zig-cc"
+RF="-C linker=$PWD/.hammer-zig-cc"
+rustc -vV | grep -q 'host: .*-alpine-' || RF="$RF -C link-self-contained=no"
+CC="$PWD/.hammer-zig-cc" RUSTFLAGS="$RF" cargo rustc --release --locked --offline -p pata-notify-triage --bin pata-notify-triage -- -C target-feature=-crt-static
+'''
+
[deps]
# El set mínimo de un cliente Wayland, igual que `mirada-compositor`: `pkgconf` para que el
# `build.rs` encuentre los `.pc`, y `libxkbcommon` porque es el que nombró el fallo.
-build = ["wayland", "libxkbcommon", "libffi", "expat", "pkgconf"]
+# Unificado con el set de `churay-metal` —el que otro agente tenía probado— en vez de dejar el
+# mínimo que yo había deducido del primer fallo: adivinar la lista corta ya me costó una vuelta.
+build = ["mesa", "wayland", "wayland-protocols", "libdrm", "libxkbcommon", "expat", "zlib", "zstd", "libffi", "pkgconf"]
diff --git a/recipes/pata-notify.toml b/recipes/pata-notify.toml
index 8f8dd866..a64072cf 100644
--- a/recipes/pata-notify.toml
+++ b/recipes/pata-notify.toml
@@ -23,6 +23,38 @@ link = "dynamic"
# motivo que \`llimphi-counter\`, que es la plantilla probada del stack llimphi.
flags = ["-p", "pata-notify", "--bin", "pata-notify"]
+[build.phases]
+# ⚠ LOCKSTEP_XML_PATH — y acá el panic SÍ SE DISPARA, contra lo que dice `cadcraft.toml`.
+# Esa receta anotó el 2026-10-13 que «el panic de `zbus-lockstep-macros` NO se dispara en estas
+# versiones», generalizando desde que `vectorcraft` compiló sin el bloque. Medido hoy con las MISMAS
+# versiones —`atspi-common` 0.13.0 + `zbus-lockstep-macros` 0.5.2— este binario muere así:
+#
+# error: custom attribute panicked (×5)
+# error[E0432]: unresolved imports `object_ref::ObjectRef`, …
+#
+# Los `E0432` son CONSECUENCIA, no causa: el `#[validate]` panica y los tipos nunca se generan, así
+# que el error que se lee está lejos del que importa. La cadena es `accesskit` → `atspi` →
+# `atspi-common`, cuyo `#[validate]` recorre `xml/` llamando `.extension().expect()` en cada entrada
+# y PANICA al toparse con el subdirectorio `xml/schemas/`. Apuntar la variable a un dir con sólo los
+# `.xml` lo evita.
+#
+# ⇒ Que una receta compile sin el bloque NO prueba que el bloque no haga falta: prueba que ESE
+# binario no llegó a esa rama del grafo de features. El comprobante del `ls` es a gritos a propósito
+# — un `cp` mudo dejaría la variable apuntando a un dir vacío y el panic volvería sin su causa.
+compile = '''
+set -e
+XMLDIR="$PWD/.atspi-lockstep-xml"
+mkdir -p "$XMLDIR"
+ls .hammer-cargo-vendor/atspi-common/xml/*.xml >/dev/null 2>&1 || { echo "no hay .hammer-cargo-vendor/atspi-common/xml/*.xml — ¿cambió el vendoreo o la versión de atspi? sin esto zbus-lockstep-macros panica en xml/schemas/" >&2; exit 1; }
+cp .hammer-cargo-vendor/atspi-common/xml/*.xml "$XMLDIR"/
+export LOCKSTEP_XML_PATH="$XMLDIR"
+printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec zig cc -mcpu=baseline "$@"' > "$PWD/.hammer-zig-cc"
+chmod +x "$PWD/.hammer-zig-cc"
+RF="-C linker=$PWD/.hammer-zig-cc"
+rustc -vV | grep -q 'host: .*-alpine-' || RF="$RF -C link-self-contained=no"
+CC="$PWD/.hammer-zig-cc" RUSTFLAGS="$RF" cargo rustc --release --locked --offline -p pata-notify --bin pata-notify -- -C target-feature=-crt-static
+'''
+
[deps]
# Mismo set que `churay-metal`: arrastra el toolkit de cliente Wayland.
build = ["mesa", "wayland", "wayland-protocols", "libdrm", "libxkbcommon", "expat", "zlib", "zstd", "libffi", "pkgconf"]