769 lines
60 KiB
Markdown
769 lines
60 KiB
Markdown
|
|
el tema con cargo xtask
|
|||
|
|
tal y como lo tenemos @.coder/2026-05-26-deps-sync.info.md
|
|||
|
|
es ¿ cómo actualizamos los crated a nuevas versiones sin romper el sync de dependencias ?
|
|||
|
|
⎿ Read .coder/2026-05-26-deps-sync.info.md (232 lines)
|
|||
|
|
|
|||
|
|
⏺ Voy a verificar el estado actual del sistema xtask y la registry antes de responder.
|
|||
|
|
|
|||
|
|
Searched for 1 pattern, listed 1 directory (ctrl+o to expand)
|
|||
|
|
|
|||
|
|
⏺ ★ Insight ─────────────────────────────────────
|
|||
|
|
- El sistema invierte el flujo habitual de Cargo: en vez de cargo update actualizando Cargo.lock, aquí los bumps de versión son
|
|||
|
|
cambios source-controlled sobre registry/dependencies.toml, y el xtask los propaga determinísticamente a cada Cargo.toml.
|
|||
|
|
- El overlay (rustelo-deps-overlay.toml) rechaza por diseño los overrides de versión — esto convierte cada bump en una decisión
|
|||
|
|
global y atómica, no en una negociación per-impl.
|
|||
|
|
- El --check reporta drift por conteo de líneas, no diff semántico: es un gate de "estado convergido", no un explicador del cambio.
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
El flujo para actualizar versiones
|
|||
|
|
|
|||
|
|
El sistema no impide actualizar — al contrario, lo canaliza por un único punto. La pregunta correcta no es "cómo actualizo sin
|
|||
|
|
romper el sync", sino "el sync convierte el bump en una decisión global; ¿estoy listo a propagar?".
|
|||
|
|
|
|||
|
|
Workflow concreto
|
|||
|
|
|
|||
|
|
1. Editar registry/dependencies.toml ← única fuente de verdad
|
|||
|
|
[deps.NAME]
|
|||
|
|
version = "X.Y.Z"
|
|||
|
|
|
|||
|
|
2. cargo xtask sync-deps ← propaga a rustelo/Cargo.toml
|
|||
|
|
3. cargo xtask sync-deps --target ../jpl-website
|
|||
|
|
(y a cada impl conocida)
|
|||
|
|
|
|||
|
|
4. cargo build / cargo test ← validar en CADA workspace
|
|||
|
|
(rustelo + cada impl)
|
|||
|
|
|
|||
|
|
5. Si rompe en impl:
|
|||
|
|
a) FORWARD → adaptar código del impl al nuevo API
|
|||
|
|
b) REGRESS → bajar la versión en registry/dependencies.toml
|
|||
|
|
y volver a sincronizar
|
|||
|
|
|
|||
|
|
Lo que no se puede hacer (y es intencional)
|
|||
|
|
|
|||
|
|
┌─────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Intento │ Por qué falla │
|
|||
|
|
├─────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ [overlay.sqlx] version = "..." en impl │ El validador rechaza override de versión (línea 90-93 del │
|
|||
|
|
│ │ .info) │
|
|||
|
|
├─────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Editar a mano dentro del bloque # >>> │ El siguiente --check lo detecta como drift y sync-deps lo │
|
|||
|
|
│ rustelo-sync:workspace-deps │ sobreescribe │
|
|||
|
|
├─────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Per-impl version pin │ "Per-impl version overrides are intentionally NOT supported" │
|
|||
|
|
│ │ (línea 189) │
|
|||
|
|
└─────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────┘
|
|||
|
|
|
|||
|
|
Esto es el corazón del invariante de unificación cross-workspace: si dos workspaces pueden tener versiones distintas, no hay
|
|||
|
|
garantía de unificación; el sistema entero pierde su razón de existir.
|
|||
|
|
|
|||
|
|
Qué hacer con bumps que rompen impl
|
|||
|
|
|
|||
|
|
El caso ya documentado: sqlx 0.8 → 0.9 en jpl-website tras un sync.
|
|||
|
|
|
|||
|
|
★ Insight ─────────────────────────────────────
|
|||
|
|
- La "convergencia forzada" no es un bug sino el contrato. El xtask te empuja a tomar la decisión arquitectónica: el registry
|
|||
|
|
refleja lo que el framework dice que es canónico, y los impls deben alinearse o el registry retrocede.
|
|||
|
|
- La opción "Regress registry" es legítima pero costosa: significa que el framework no puede avanzar hasta que el impl bloqueante
|
|||
|
|
se adapte. Útil como freno cuando hay deadline en impl.
|
|||
|
|
- No existe punto medio. Si necesitas el punto medio, el sistema te está diciendo que el registry está mal-versionado:
|
|||
|
|
probablemente la nueva versión no debió subir al registry todavía.
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
Patrón recomendado para bumps frágiles (leptos, axum, sqlx)
|
|||
|
|
|
|||
|
|
1. Crear branch en rustelo: bump/leptos-0.X
|
|||
|
|
2. Editar registry/dependencies.toml
|
|||
|
|
3. cargo xtask sync-deps # rustelo
|
|||
|
|
4. cargo build --workspace # ¿compila rustelo?
|
|||
|
|
5. cargo xtask sync-deps --target ../jpl-website
|
|||
|
|
6. cd ../jpl-website && cargo build # ¿compila impl?
|
|||
|
|
7. Si 4 o 6 falla:
|
|||
|
|
- Fix forward → commit a rustelo (si es framework code)
|
|||
|
|
→ commit a impl (si es código de impl)
|
|||
|
|
- O regress registry y volver al paso 2
|
|||
|
|
8. Commit registry + Cargo.toml sincronizados JUNTOS (atomicidad de bump)
|
|||
|
|
|
|||
|
|
El paso 8 es importante: el pre-commit hook (rustelo-deps-sync con --check) bloquea cualquier commit donde
|
|||
|
|
registry/dependencies.toml esté desincronizado de Cargo.toml. Esto fuerza que el bump y su propagación sean un solo commit, no dos.
|
|||
|
|
|
|||
|
|
Gap actual del sistema (línea 217 del .info)
|
|||
|
|
|
|||
|
|
▎ Auto-discovery of impls via rustelo.manifest.toml [sync] section (currently impls are reached via explicit --target).
|
|||
|
|
|
|||
|
|
Hoy debes recordar a mano qué impls existen y pasarles --target uno a uno. Esto es un riesgo operacional real: si añades un impl
|
|||
|
|
nuevo y olvidas sincronizarlo, drifta silenciosamente hasta que alguien corra el hook en ese repo. Si quieres, esto sería el
|
|||
|
|
siguiente xtask útil de implementar (sync-deps --all leyendo de un manifiesto).
|
|||
|
|
|
|||
|
|
¿Quieres que profundice en alguno de los flujos — por ejemplo el patrón forward vs regress para un bump concreto que tengas
|
|||
|
|
pendiente — o que mire el código del xtask para confirmar el comportamiento de algún caso edge?
|
|||
|
|
|
|||
|
|
✻ Churned for 55s
|
|||
|
|
|
|||
|
|
❯ zed nos muestra versiones actualizables sobre Cargo.toml pero es sobreescrito por xtask
|
|||
|
|
|
|||
|
|
⏺ ★ Insight ─────────────────────────────────────
|
|||
|
|
- Zed (vía rust-analyzer + crates lsp) detecta updates leyendo tablas [dependencies] o [workspace.dependencies] en archivos
|
|||
|
|
Cargo.toml. No reconoce registry/dependencies.toml porque no es un manifiesto Cargo válido — es un schema ad-hoc del xtask.
|
|||
|
|
- El conflicto es estructural: el sistema xtask deliberadamente coloca la fuente de verdad fuera del sitio donde las herramientas
|
|||
|
|
Cargo-native esperan encontrarla. Esto es bueno para el invariante cross-workspace pero rompe el flujo editor-driven que ofrecen
|
|||
|
|
Zed/rust-analyzer/crates-tooling.
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
Esto es una fricción real, no un mal uso. Tienes tres caminos. Te los presento con los tradeoffs.
|
|||
|
|
|
|||
|
|
Opción A — Reverse-sync (ingest)
|
|||
|
|
|
|||
|
|
Añadir un modo al xtask que lee Cargo.toml y actualiza registry/dependencies.toml (dirección inversa):
|
|||
|
|
|
|||
|
|
1. En Zed, click en el upgrade inline sobre Cargo.toml
|
|||
|
|
2. cargo xtask sync-deps --ingest ← lee Cargo.toml → escribe registry
|
|||
|
|
3. cargo xtask sync-deps --target ../jpl-website
|
|||
|
|
4. Commit los tres archivos juntos
|
|||
|
|
|
|||
|
|
Pros: mínimo cambio estructural, conserva el schema actual del registry (con rebase, etc).
|
|||
|
|
Contras: dos comandos por bump, fácil olvidar el --ingest y commitear Cargo.toml drifteado → el pre-commit hook lo detecta pero
|
|||
|
|
solo si está activo.
|
|||
|
|
|
|||
|
|
Opción B — Convertir el registry en Cargo.toml ficticio (recomendada)
|
|||
|
|
|
|||
|
|
Reemplazar registry/dependencies.toml por registry/Cargo.toml:
|
|||
|
|
|
|||
|
|
# registry/Cargo.toml
|
|||
|
|
[workspace]
|
|||
|
|
members = []
|
|||
|
|
exclude = []
|
|||
|
|
|
|||
|
|
[workspace.dependencies]
|
|||
|
|
leptos = { version = "0.8" }
|
|||
|
|
axum = { version = "0.8" }
|
|||
|
|
sqlx = { version = "0.9", features = ["postgres"], default-features = false }
|
|||
|
|
rustelo_utils = { path = "../crates/foundation/crates/rustelo_utils" }
|
|||
|
|
# ...
|
|||
|
|
|
|||
|
|
Y en rustelo/Cargo.toml:
|
|||
|
|
exclude = ["xtask", "registry"]
|
|||
|
|
|
|||
|
|
Workflow:
|
|||
|
|
1. Abrir registry/Cargo.toml en Zed
|
|||
|
|
2. Click inline-upgrade — Zed actualiza directamente la fuente de verdad
|
|||
|
|
3. cargo xtask sync-deps ← propaga a rustelo/Cargo.toml
|
|||
|
|
4. cargo xtask sync-deps --target ../jpl-website
|
|||
|
|
|
|||
|
|
★ Insight ─────────────────────────────────────
|
|||
|
|
- Truco clave: registry/Cargo.toml con members = [] es un workspace válido pero vacío — Cargo no compila nada ahí, pero
|
|||
|
|
rust-analyzer sí parsea sus deps y Zed muestra los upgrades disponibles.
|
|||
|
|
- Las paths necesitan re-prefix con ../ (porque la base cambia), pero el xtask ya tiene la lógica de pathdiff para rebase, así que
|
|||
|
|
solo invierte el cálculo en una dirección.
|
|||
|
|
- La metadata rebase = false no cabe en el formato Cargo nativo. Solución: moverla a un sidecar registry/sync.toml o inferirla
|
|||
|
|
(cualquier path que sale del workspace = no-rebase por defecto).
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
Pros: Zed funciona nativamente, sin pasos extra. Bump y sync siguen siendo dos operaciones explícitas pero la primera ya no
|
|||
|
|
requiere herramienta especial.
|
|||
|
|
Contras: migración del schema, hay que decidir dónde vive rebase (sidecar o convención). Cargo carga un workspace extra en cada
|
|||
|
|
operación (impacto mínimo).
|
|||
|
|
|
|||
|
|
Opción C — Aceptar la fricción
|
|||
|
|
|
|||
|
|
Documentar que Zed no debe usarse para upgrades en Cargo.toml, solo para descubrir versiones disponibles. El bump real se hace a
|
|||
|
|
mano en registry/dependencies.toml. Cero código nuevo, máxima fricción humana.
|
|||
|
|
|
|||
|
|
Recomendación
|
|||
|
|
|
|||
|
|
Opción B. Es la única que elimina la fricción en lugar de añadirle un workaround. El xtask sigue siendo necesario (para el splice
|
|||
|
|
cross-workspace), pero deja de ser el único punto de entrada — Zed se convierte en una interfaz válida porque la fuente de verdad
|
|||
|
|
ahora habla el dialecto que Zed entiende.
|
|||
|
|
|
|||
|
|
La migración es mecánica:
|
|||
|
|
1. Renombrar registry/dependencies.toml → registry/Cargo.toml con schema [workspace.dependencies]
|
|||
|
|
2. Re-prefix de paths con ../
|
|||
|
|
3. Mover rebase a registry/sync.toml (o inferirlo)
|
|||
|
|
4. Adaptar xtask/src/registry.rs para leer el nuevo formato
|
|||
|
|
5. Añadir exclude = ["registry"] a rustelo/Cargo.toml
|
|||
|
|
6. Validar cargo xtask sync-deps --check con la nueva fuente
|
|||
|
|
|
|||
|
|
¿Quieres que lo implemente, o prefieres ver primero el código actual de xtask/src/registry.rs para evaluar el alcance del cambio?
|
|||
|
|
|
|||
|
|
✻ Baked for 1m 1s
|
|||
|
|
|
|||
|
|
※ recap: Goal: resolve friction where Zed shows Cargo.toml upgrades but xtask overwrites them. Current task: choose between
|
|||
|
|
reverse-sync (ingest), converting registry to a fake Cargo.toml (recommended), or accepting the friction. Next: decide which option
|
|||
|
|
to implement. (disable recaps in /config)
|
|||
|
|
por qué implementar la opción B es más recomentable que A ?
|
|||
|
|
|
|||
|
|
⏺ ★ Insight ─────────────────────────────────────
|
|||
|
|
- La pregunta no es trivial: A es menos invasiva (no migra schema, no toca paths) y resuelve el síntoma. B requiere migración. Si
|
|||
|
|
solo miráramos esfuerzo, A gana. La elección depende de qué propiedad valoramos más: minimizar el cambio (A) o minimizar la
|
|||
|
|
complejidad sistémica resultante (B).
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
Te lo desgloso en ejes concretos. Voy del más decisivo al menos.
|
|||
|
|
|
|||
|
|
1. Direccionalidad del flujo
|
|||
|
|
|
|||
|
|
A introduce bidirección. El sync deja de ser una operación push (registry → Cargo.toml) y pasa a tener dos modos: push y pull.
|
|||
|
|
Bidirectional syncs son históricamente fuente de bugs sutiles — son el problema clásico de réplica master-master.
|
|||
|
|
|
|||
|
|
B preserva la unidireccionalidad. Siempre registry/Cargo.toml → todos los demás. El xtask no necesita resolver conflictos porque no
|
|||
|
|
puede haberlos: solo hay un origen.
|
|||
|
|
|
|||
|
|
2. Idempotencia y orden de operaciones
|
|||
|
|
|
|||
|
|
A pierde idempotencia parcial. El resultado de cargo xtask sync-deps depende del estado relativo de dos archivos: si Cargo.toml
|
|||
|
|
tiene un upgrade que registry no, el sync lo borra. Esto significa que el orden importa: primero --ingest, después sync-deps.
|
|||
|
|
Olvidar el orden = trabajo perdido silenciosamente.
|
|||
|
|
|
|||
|
|
B es idempotente. Corre sync-deps N veces sobre el mismo registry: resultado idéntico. El estado en disco de Cargo.toml es
|
|||
|
|
irrelevante para el resultado, porque siempre es destino, nunca origen.
|
|||
|
|
|
|||
|
|
3. Coherencia con el modelo de "fuente de verdad"
|
|||
|
|
|
|||
|
|
★ Insight ─────────────────────────────────────
|
|||
|
|
- El diseño actual ya tiene "DO NOT EDIT" en los marcadores del bloque managed. Es una declaración explícita: este texto es
|
|||
|
|
derivado, no lo toques. La opción A contradice esa declaración: pide al usuario que edite el bloque managed (vía Zed) como si fuera
|
|||
|
|
fuente, y luego ingiera el cambio. Confunde el contrato.
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
A rompe el invariante semántico del marker # >>> rustelo-sync:workspace-deps (managed by xtask — DO NOT EDIT). Con --ingest, el
|
|||
|
|
bloque managed pasa a ser editable bajo ciertas condiciones. El marker miente.
|
|||
|
|
|
|||
|
|
B preserva el invariante. El bloque managed sigue siendo solo-escritura-por-xtask. La edición humana ocurre en otro archivo,
|
|||
|
|
claramente identificado como fuente.
|
|||
|
|
|
|||
|
|
4. Composabilidad con ecosistema Cargo
|
|||
|
|
|
|||
|
|
Esto es el argumento más fuerte a medio plazo.
|
|||
|
|
|
|||
|
|
A solo resuelve Zed. ¿Y cargo upgrade de cargo-edit? ¿Y Dependabot, que mira Cargo.toml? ¿Y cargo outdated? Cada herramienta que en
|
|||
|
|
el futuro quieras integrar requerirá su propio adaptador --ingest-from-X, o un paso manual.
|
|||
|
|
|
|||
|
|
B resuelve toda la familia de una sola vez. Cualquier herramienta que sepa leer [workspace.dependencies] (es decir, todas las
|
|||
|
|
herramientas Cargo-native) opera sobre la fuente sin saber que existe el sync.
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
A B
|
|||
|
|
│ │
|
|||
|
|
┌────────┼────────┐ ┌────────┼────────┐
|
|||
|
|
│ │ │ │ │ │
|
|||
|
|
Zed cargo-up Depbot Zed cargo-up Depbot
|
|||
|
|
│ │ │ │ │ │
|
|||
|
|
▼ ▼ ▼ ▼ ▼ ▼
|
|||
|
|
Cargo (custom) (custom) registry/Cargo.toml
|
|||
|
|
│ │ │ │
|
|||
|
|
└───────┼────────┘ ▼
|
|||
|
|
▼ xtask sync
|
|||
|
|
xtask --ingest
|
|||
|
|
▼
|
|||
|
|
registry
|
|||
|
|
▼
|
|||
|
|
xtask sync
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
En A cada herramienta nueva requiere un adaptador o un paso manual. En B la herramienta apunta directamente a la fuente.
|
|||
|
|
|
|||
|
|
5. Superficie de código en el xtask
|
|||
|
|
|
|||
|
|
A añade código: parser inverso (Cargo.toml → dep map), detección de conflicto (¿qué pasa si registry y Cargo.toml difieren en N
|
|||
|
|
deps a la vez?), validación de overlay contra ingest, lógica de "qué dirección priorizar".
|
|||
|
|
|
|||
|
|
B reduce código: desaparece el parser custom de dependencies.toml, se reemplaza por el parser de Cargo.toml que el xtask ya tiene
|
|||
|
|
(o toml_edit directo). El schema custom se va.
|
|||
|
|
|
|||
|
|
6. Modo de fallo y recuperación
|
|||
|
|
|
|||
|
|
┌───────────────────────────┬───────────────────────────────────────────────────────┬──────────────────────────────────────────┐
|
|||
|
|
│ Escenario │ A │ B │
|
|||
|
|
├───────────────────────────┼───────────────────────────────────────────────────────┼──────────────────────────────────────────┤
|
|||
|
|
│ Editor con upgrade inline │ flujo natural pero peligroso (olvido de --ingest) │ flujo natural y seguro │
|
|||
|
|
├───────────────────────────┼───────────────────────────────────────────────────────┼──────────────────────────────────────────┤
|
|||
|
|
│ Edit manual en archivo │ difícil distinguir error de uso correcto (Cargo.toml │ error claro: editaste un bloque marcado │
|
|||
|
|
│ equivocado │ es editable a veces) │ "DO NOT EDIT" │
|
|||
|
|
├───────────────────────────┼───────────────────────────────────────────────────────┼──────────────────────────────────────────┤
|
|||
|
|
│ Dos personas suben bumps │ merge complejo: ambos editaron Cargo.toml + ambos │ merge normal en registry/Cargo.toml, │
|
|||
|
|
│ distintos en paralelo │ --ingest-aron, registry tiene un orden ganador │ conflicto de Git visible │
|
|||
|
|
│ │ silencioso │ │
|
|||
|
|
├───────────────────────────┼───────────────────────────────────────────────────────┼──────────────────────────────────────────┤
|
|||
|
|
│ Pre-commit detecta drift │ sí, pero el mensaje confunde (¿debía hacer --ingest?) │ sí, mensaje claro: "registry y │
|
|||
|
|
│ │ │ Cargo.toml difieren, corre sync-deps" │
|
|||
|
|
└───────────────────────────┴───────────────────────────────────────────────────────┴──────────────────────────────────────────┘
|
|||
|
|
|
|||
|
|
7. Curva de aprendizaje para nuevos contribuidores
|
|||
|
|
|
|||
|
|
A: dos archivos parecidos (Cargo.toml y dependencies.toml con schema custom), una operación que depende de la dirección. Necesita
|
|||
|
|
documentación y disciplina humana.
|
|||
|
|
|
|||
|
|
B: un archivo (registry/Cargo.toml) que cualquier rustáceo entiende a primera vista, un comando para propagar (sync-deps). La
|
|||
|
|
documentación se reduce a "el registry es un workspace Cargo vacío cuya única función es declarar dependencies".
|
|||
|
|
|
|||
|
|
El caso donde A gana
|
|||
|
|
|
|||
|
|
Hay uno: si los rebase/features/metadata custom del schema actual son suficientemente ricos para que migrarlos a formato Cargo
|
|||
|
|
nativo pierda información, A preserva la flexibilidad. Mirando el schema actual:
|
|||
|
|
|
|||
|
|
[deps.NAME]
|
|||
|
|
version = "..."
|
|||
|
|
path = "..."
|
|||
|
|
features = ["..."]
|
|||
|
|
default_features = false
|
|||
|
|
rebase = false
|
|||
|
|
|
|||
|
|
Solo rebase no tiene correspondencia directa en formato Cargo. El resto (version, path, features, default-features) es exactamente
|
|||
|
|
la sintaxis de Cargo workspace.dependencies. Así que la "pérdida" se limita a un campo, que se resuelve con un sidecar
|
|||
|
|
registry/sync.toml muy pequeño:
|
|||
|
|
|
|||
|
|
[paths]
|
|||
|
|
"platform-nats" = { rebase = false }
|
|||
|
|
|
|||
|
|
★ Insight ─────────────────────────────────────
|
|||
|
|
- En el fondo, A trata el síntoma ("Zed no ve el registry"); B trata la causa ("la fuente de verdad usa un dialecto que el
|
|||
|
|
ecosistema no entiende"). La cura siempre es preferible al alivio cuando el coste de la cura es proporcional al problema — y aquí
|
|||
|
|
lo es: una migración mecánica de un archivo a otro formato.
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
Resumen ejecutivo
|
|||
|
|
|
|||
|
|
A resuelve Zed con un comando nuevo, manteniendo un schema custom y añadiendo bidireccionalidad. B resuelve Zed (y cualquier futura
|
|||
|
|
herramienta Cargo-native) eliminando el schema custom y manteniendo la unidireccionalidad del sync. El coste es una migración
|
|||
|
|
única; el beneficio es un sistema más simple y más componible para siempre.
|
|||
|
|
|
|||
|
|
A es la respuesta correcta si la migración es prohibitiva o si hay restricciones que aún no me has contado (p.ej. impls que ya usan
|
|||
|
|
el formato dependencies.toml directamente). B es la respuesta correcta en cualquier otro escenario.
|
|||
|
|
|
|||
|
|
¿Hay alguna restricción del lado de jpl-website u otros impls que me esté perdiendo y que pudiera hacer la migración más costosa de
|
|||
|
|
lo que asumo?
|
|||
|
|
|
|||
|
|
✻ Brewed for 1m 12s
|
|||
|
|
|
|||
|
|
❯ implementa la opción B
|
|||
|
|
|
|||
|
|
★ Insight ─────────────────────────────────────
|
|||
|
|
- El sync reproduce bit-a-bit la región managed previa — confirma que el cambio de schema preserva la semántica. Para platform-nats
|
|||
|
|
(no-rebase) el path se canonicaliza a ../stratumiops/crates/platform-nats igual que antes, pero ahora viene de
|
|||
|
|
../../stratumiops/... en registry/Cargo.toml (registry-relative).
|
|||
|
|
- pathdiff opera textualmente sobre componentes, así que canonicalize antes del diff evita que .. segmentos contaminen el output.
|
|||
|
|
Sin canonicalize, el path emitido sería registry/../crates/... — válido pero feo. Con canonicalize, es limpio.
|
|||
|
|
- [workspace.dependencies] con members = [] es un workspace Cargo legítimo: cargo metadata retorna packages: [] sin error. Cargo
|
|||
|
|
solo valida sintaxis del manifest, no intenta resolver paths (no hay miembros que las usen). Esto es justo lo que necesitamos:
|
|||
|
|
Zed/rust-analyzer escanean la tabla, Cargo no compila nada.
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
GUIDELINE: rust.md (no unwrap, idiomatic, ?, expect, clippy -D warnings clean)
|
|||
|
|
IMPLEMENTING: opción B — registry como workspace Cargo vacío editable nativamente por Zed
|
|||
|
|
EXCLUDED: documentación nueva, commits, actualización de .coder/2026-05-26-deps-sync.info.md
|
|||
|
|
(queda stale; pendiente de tu confirmación para refrescarlo)
|
|||
|
|
|
|||
|
|
Cambios aplicados
|
|||
|
|
|
|||
|
|
┌────────────────────────────┬───────────────┬─────────────────────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Archivo │ Acción │ Por qué │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ registry/Cargo.toml │ nuevo │ Workspace Cargo vacío con [workspace.dependencies] — fuente de verdad │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ registry/sync.toml │ nuevo │ Sidecar: no_rebase = ["platform-nats"] (única metadata sin equivalente Cargo) │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ registry/dependencies.toml │ borrado │ Schema custom reemplazado │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ xtask/src/registry.rs │ reescrito │ Parsea Cargo.toml (untagged enum string-or-table) + lee sidecar; Dep con │
|
|||
|
|
│ │ │ Deserialize manual │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ xtask/src/render.rs │ reescrito │ Rebase con origen en registry/, canonicalize antes de diff_paths, propaga Result │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ xtask/src/sync.rs │ edición │ Propaga ? desde render_region; fix clippy pendiente │
|
|||
|
|
│ │ mínima │ (manual_pattern_char_comparison) │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ xtask/src/overlay.rs │ edición │ Mensaje de error apunta a registry/Cargo.toml │
|
|||
|
|
│ │ mínima │ │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ xtask/src/main.rs │ edición │ Comentarios docs actualizados │
|
|||
|
|
│ │ mínima │ │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Cargo.toml (raíz) │ edición │ exclude = ["xtask", "registry"] para que la sub-workspace no contamine │
|
|||
|
|
├────────────────────────────┼──────────────┼──────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ .pre-commit-config.yaml │ edición │ Regex ^(Cargo\.toml|registry/(Cargo|sync)\.toml)$ │
|
|||
|
|
└────────────────────────────┴──────────────┴──────────────────────────────────────────────────────────────────────────────────┘
|
|||
|
|
|
|||
|
|
Verificación ejecutada
|
|||
|
|
|
|||
|
|
$ cargo build --manifest-path xtask/Cargo.toml → OK
|
|||
|
|
$ cargo clippy --manifest-path xtask/Cargo.toml -D warnings → OK
|
|||
|
|
$ cargo xtask sync-deps --check → "up to date" (exit 0)
|
|||
|
|
$ cargo metadata --no-deps --manifest-path Cargo.toml → OK
|
|||
|
|
$ cargo metadata --no-deps --manifest-path registry/Cargo.toml → OK (packages=[])
|
|||
|
|
|
|||
|
|
La región managed en rustelo/Cargo.toml quedó idéntica al estado previo a la migración — convergencia bit-a-bit valida que la
|
|||
|
|
traducción del schema preserva semántica.
|
|||
|
|
|
|||
|
|
Flujo nuevo para Zed
|
|||
|
|
|
|||
|
|
1. Abrir registry/Cargo.toml en Zed → rust-analyzer detecta [workspace.dependencies] y muestra upgrades inline.
|
|||
|
|
2. Click en el upgrade → Zed escribe directamente en la fuente de verdad.
|
|||
|
|
3. cargo xtask sync-deps → propaga a rustelo/Cargo.toml.
|
|||
|
|
4. cargo xtask sync-deps --target ../jpl-website → propaga a cada impl.
|
|||
|
|
5. Pre-commit hook bloquea commits desincronizados (fires en cambios a Cargo.toml, registry/Cargo.toml o registry/sync.toml).
|
|||
|
|
|
|||
|
|
Pendientes (no implementados, por si los quieres)
|
|||
|
|
|
|||
|
|
- Actualizar .coder/2026-05-26-deps-sync.info.md: el doc describe el formato viejo (dependencies.toml, schema custom). Su modelo
|
|||
|
|
conceptual sigue siendo correcto pero los detalles concretos están stale.
|
|||
|
|
- Sincronizar jpl-website u otros impls: no he tocado nada fuera de rustelo. Cuando ejecutes cargo xtask sync-deps --target
|
|||
|
|
../jpl-website la primera vez producirá output equivalente al anterior (la región managed allí seguirá la misma forma).
|
|||
|
|
- Auto-discovery de impls: sigue pendiente del .info original; no es regresión sino limitación heredada.
|
|||
|
|
|
|||
|
|
STATUS: Complete
|
|||
|
|
|
|||
|
|
⏺ ★ Insight ─────────────────────────────────────
|
|||
|
|
- En rustelo las recetas viven en el top-level (justfiles/build.just importado con import), así que se invocan planas (just
|
|||
|
|
deps-sync). En jpl-website el justfile usa mod build "just/build.just", así que se invocan con namespace (just build deps-sync).
|
|||
|
|
Misma funcionalidad, dos convenciones distintas según el patrón del proyecto.
|
|||
|
|
- Para el impl, la receta encapsula tres detalles operacionales molestos: la ruta al xtask (../rustelo/xtask/Cargo.toml), las flags
|
|||
|
|
--rustelo-root ../rustelo --target ., y el override de CARGO_TARGET_DIR para no contaminar el target volume-pinned del framework.
|
|||
|
|
El humano nunca tiene que recordarlos.
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
Resumen de cambios
|
|||
|
|
|
|||
|
|
Documentación
|
|||
|
|
- .coder/2026-05-26-deps-sync.info.md — actualizado: schema nuevo (registry/Cargo.toml + sync.toml), workflow editor-driven con
|
|||
|
|
Zed, rationale de la migración, verificación de bit-identical reproduction.
|
|||
|
|
- rustelo/reflection/qa.ncl — deps-sync-workflow reescrito: bump editor-driven como flujo recomendado, schema Cargo-native, sidecar
|
|||
|
|
no_rebase, sección "why a fake Cargo.toml".
|
|||
|
|
- jpl-website/reflection/qa.ncl — deps-sync-impl-workflow actualizado: referencia a ../rustelo/registry/Cargo.toml, mención de Zed
|
|||
|
|
inline upgrades para descubrir versiones disponibles.
|
|||
|
|
|
|||
|
|
Recetas just
|
|||
|
|
│ rustelo │ just deps-sync │ propagar registry → rustelo/Cargo.toml │
|
|||
|
|
├─────────────┼──────────────────────────────────────────┼──────────────────────────────────────────────┤
|
|||
|
|
│ rustelo │ just deps-sync-check │ verificar drift sin escribir │
|
|||
|
|
├─────────────┼──────────────────────────────────────────┼──────────────────────────────────────────────┤
|
|||
|
|
│ rustelo │ just deps-sync-impl ../jpl-website │ propagar a impl arbitrario │
|
|||
|
|
├─────────────┼──────────────────────────────────────────┼──────────────────────────────────────────────┤
|
|||
|
|
│ rustelo │ just deps-sync-check-impl ../jpl-website │ verificar drift en impl │
|
|||
|
|
├─────────────┼──────────────────────────────────────────┼──────────────────────────────────────────────┤
|
|||
|
|
│ rustelo │ just deps-sync-all │ rustelo + impls conocidos en un solo comando │
|
|||
|
|
├─────────────┼──────────────────────────────────────────┼──────────────────────────────────────────────┤
|
|||
|
|
│ jpl-website │ just build deps-sync │ pull desde ../rustelo/registry/Cargo.toml │
|
|||
|
|
├─────────────┼──────────────────────────────────────────┼──────────────────────────────────────────────┤
|
|||
|
|
│ jpl-website │ just build deps-sync-check │ verificar drift contra rustelo │
|
|||
|
|
└─────────────┴──────────────────────────────────────────┴──────────────────────────────────────────────┘
|
|||
|
|
|
|||
|
|
Verificado
|
|||
|
|
$ just deps-sync-check → ./Cargo.toml is up to date (exit 0)
|
|||
|
|
$ just --list (rustelo) → 5 recipes deps-sync* visibles
|
|||
|
|
$ just --list build (jpl) → deps-sync, deps-sync-check visibles bajo build::
|
|||
|
|
|
|||
|
|
STATUS: Complete
|
|||
|
|
|
|||
|
|
escribe un doc en .coder
|
|||
|
|
para pedir en una sesión claude code
|
|||
|
|
que se implemente este mismo mecanismo tal cual (opción B e incluir las recetas just) de sync de crates en un proyecto nuevo
|
|||
|
|
|
|||
|
|
|
|||
|
|
⏺ ★ Insight ─────────────────────────────────────
|
|||
|
|
- El doc está estructurado como prompt para una sesión Claude Code, no como referencia general. Cada task usa el formato
|
|||
|
|
obligatorio del proyecto (COMPLEXITY/DEPENDENCIES/RISKS/SUCCESS_CRITERIA) sin estimaciones temporales, lo que evita que la sesión
|
|||
|
|
receptora "improvise" pasos.
|
|||
|
|
- Las tasks marcan dependencias explícitas (1→3→4→5→6→[7,8,9]→10), así que si la sesión receptora se interrumpe a la mitad, puede
|
|||
|
|
retomar desde un estado parcial seguro sin reconstruir contexto.
|
|||
|
|
- El doc separa lo que se debe copiar tal cual (xtask source, markers # >>> rustelo-sync) de lo que hay que adaptar (paths
|
|||
|
|
registry-relativos, lista de deps, hook id). Esa separación es lo que distingue una replicación correcta de una "reescritura
|
|||
|
|
libre".
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
Resumen del doc
|
|||
|
|
|
|||
|
|
Ruta: .coder/2026-05-26-deps-sync-replication.plan.md
|
|||
|
|
|
|||
|
|
Es un brief auto-contenido para entregar a otra sesión Claude Code. Estructura:
|
|||
|
|
|
|||
|
|
1. Why / Reference implementation — contexto mínimo + apuntadores a la doc canónica de rustelo
|
|||
|
|
2. Preconditions — qué debe tener el proyecto destino
|
|||
|
|
3. Open questions — 5 preguntas que la sesión receptora debe hacer al usuario antes de empezar (project root, project name,
|
|||
|
|
framework-vs-impl, no-rebase deps, downstream impls)
|
|||
|
|
4. 10 tasks ordenadas con COMPLEXITY/DEPENDENCIES/RISKS/SUCCESS_CRITERIA cada una:
|
|||
|
|
- 1: crear registry/Cargo.toml
|
|||
|
|
- 2: crear registry/sync.toml
|
|||
|
|
- 3: copiar xtask
|
|||
|
|
- 4: editar root Cargo.toml (exclude)
|
|||
|
|
- 5: añadir alias .cargo/config.toml
|
|||
|
|
- 6: primer sync + commit
|
|||
|
|
- 7: pre-commit hook
|
|||
|
|
- 8: recetas just (framework)
|
|||
|
|
- 9: recetas just (impl) — opcional
|
|||
|
|
- 10: validación end-to-end
|
|||
|
|
5. Adaptations checklist — qué cambiar vs rustelo (paths, nombre, lista de deps, etc.)
|
|||
|
|
6. Things to leave untouched — marker text, standalone-workspace de xtask, deserialización dual de Dep
|
|||
|
|
7. Order of independence — qué subconjuntos de tasks son estados estables si se quiere parar a mitad
|
|||
|
|
8. See also — los tres docs/QA de referencia en el repo rustelo
|
|||
|
|
|
|||
|
|
El doc asume que rustelo está accesible para cp -r ../rustelo/xtask .; si no lo está, la sesión receptora debe preguntar dónde vive
|
|||
|
|
(mencionado explícitamente en la Open question #1 y Task 3 NOTES).
|
|||
|
|
|
|||
|
|
STATUS: Complete
|
|||
|
|
|
|||
|
|
exlica lo de Auto-discovery de impls: sigue pendiente del .info original; no es regresión sino limitación heredada.
|
|||
|
|
|
|||
|
|
⏺ ★ Insight ─────────────────────────────────────
|
|||
|
|
- "Limitación heredada" significa que existía en el diseño original con dependencies.toml y la migración a opción B no la introdujo
|
|||
|
|
ni la resolvió. Decir "no es regresión" es importante: si el usuario migrara con la expectativa de que B arreglase TODO lo del
|
|||
|
|
.info original, este punto le decepcionaría sin esta aclaración.
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
Qué significa "auto-discovery de impls"
|
|||
|
|
|
|||
|
|
Hoy, cuando ejecutas cargo xtask sync-deps, el xtask sincroniza un solo target — el que recibe por CLI. Hay tres modos posibles:
|
|||
|
|
|
|||
|
|
cargo xtask sync-deps → rustelo/Cargo.toml
|
|||
|
|
cargo xtask sync-deps --target ../jpl-website → jpl-website/Cargo.toml
|
|||
|
|
cargo xtask sync-deps --target ../otra-impl → otra-impl/Cargo.toml
|
|||
|
|
|
|||
|
|
El xtask no sabe qué impls existen en el ecosistema. Si añades ../proyecto-z mañana como consumidor del registry, el xtask no se
|
|||
|
|
entera hasta que alguien le pase --target ../proyecto-z explícitamente.
|
|||
|
|
|
|||
|
|
Auto-discovery sería el mecanismo opuesto: el xtask conoce la lista completa de impls y puede iterar sobre ellos sin que un humano
|
|||
|
|
se la recuerde:
|
|||
|
|
|
|||
|
|
cargo xtask sync-deps --all
|
|||
|
|
→ sincroniza rustelo + cada impl declarada en algún lugar
|
|||
|
|
|
|||
|
|
Por qué importa operacionalmente
|
|||
|
|
|
|||
|
|
Hoy hay tres puntos de fricción:
|
|||
|
|
|
|||
|
|
1. Memoria humana: para mantener el ecosistema en sync, alguien debe recordar la lista de impls. En mi receta deps-sync-all añadí
|
|||
|
|
../jpl-website hardcoded — si mañana aparece ../jpl-blog, hay que editar la receta. Y nadie lo recordará hasta que rompa algo.
|
|||
|
|
2. Drift silencioso: si una impl nueva no se añade a la lista, los pre-commit hooks de cada repo seguirán fallando
|
|||
|
|
independientemente (eso protege la integridad de cada repo aisladamente), pero no hay un sitio donde rustelo te diga "atención, hay
|
|||
|
|
3 impls drifteadas". Cada repo es una isla hasta que alguien hace commit allí.
|
|||
|
|
3. Onboarding: un colaborador nuevo en rustelo no sabe automáticamente qué impls hay que sincronizar tras un bump de versión. Tiene
|
|||
|
|
que preguntar o leer el README/justfile.
|
|||
|
|
|
|||
|
|
Por qué no es regresión de la migración a opción B
|
|||
|
|
|
|||
|
|
El diseño original (registry/dependencies.toml schema custom) tampoco tenía auto-discovery. El .info original lo lista en su
|
|||
|
|
sección Open items:
|
|||
|
|
|
|||
|
|
- Auto-discovery of impls via `rustelo.manifest.toml` `[sync]` section
|
|||
|
|
(currently impls are reached via explicit `--target`).
|
|||
|
|
|
|||
|
|
La migración a opción B preservó todo el comportamiento del CLI: --target sigue funcionando idéntico, los markers son los mismos,
|
|||
|
|
el splice es el mismo. Solo cambió el formato de la fuente de verdad, no la topología del sync. Por eso uso "limitación heredada" —
|
|||
|
|
viaja con el sistema desde el diseño original.
|
|||
|
|
|
|||
|
|
★ Insight ─────────────────────────────────────
|
|||
|
|
- En realidad la migración a opción B hace este open item más fácil de resolver, no más difícil. Antes había que extender el schema
|
|||
|
|
custom de dependencies.toml ([meta], [deps.X], y ahora añadir [sync.impls]). Con opción B, ese tipo de metadata no-Cargo ya tiene
|
|||
|
|
un sitio natural: registry/sync.toml. Solo hay que añadir un campo y una iteración en sync.rs.
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
Cómo se resolvería (boceto, no implementado)
|
|||
|
|
|
|||
|
|
Extender registry/sync.toml:
|
|||
|
|
|
|||
|
|
no_rebase = ["platform-nats"]
|
|||
|
|
|
|||
|
|
[impls]
|
|||
|
|
known = [
|
|||
|
|
"../jpl-website",
|
|||
|
|
"../jpl-blog", # ejemplo futuro
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
En el xtask, añadir un flag --all:
|
|||
|
|
|
|||
|
|
// sync.rs (boceto)
|
|||
|
|
if args.all {
|
|||
|
|
let sidecar = registry::load_sidecar(&args.rustelo_root)?;
|
|||
|
|
// sync rustelo
|
|||
|
|
sync_target(&args.rustelo_root, /*target=*/ &args.rustelo_root, …)?;
|
|||
|
|
for impl_path in sidecar.impls.known {
|
|||
|
|
let target = args.rustelo_root.join(&impl_path);
|
|||
|
|
sync_target(&args.rustelo_root, &target, …)?;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Y la receta just simplificaría:
|
|||
|
|
|
|||
|
|
# antes
|
|||
|
|
deps-sync-all:
|
|||
|
|
@just deps-sync
|
|||
|
|
@just deps-sync-impl ../jpl-website # hardcoded
|
|||
|
|
|
|||
|
|
# después
|
|||
|
|
deps-sync-all:
|
|||
|
|
cargo xtask sync-deps --all # lista vive en sync.toml
|
|||
|
|
|
|||
|
|
Por qué sigue pendiente
|
|||
|
|
|
|||
|
|
Es un trade-off consciente, no un olvido:
|
|||
|
|
|
|||
|
|
┌───────────────────────────────────────┬──────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Argumento a favor de implementarlo │ Argumento a favor de aplazarlo │
|
|||
|
|
├───────────────────────────────────────┼──────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Elimina memoria humana del flujo │ Hoy solo hay 1 impl (jpl-website); sobre-ingeniería para N=1 │
|
|||
|
|
├───────────────────────────────────────┼──────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Drift detection centralizado │ Cada impl ya tiene su pre-commit hook independiente │
|
|||
|
|
├───────────────────────────────────────┼──────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Onboarding más simple │ El README/justfile ya documenta el comando manual │
|
|||
|
|
├───────────────────────────────────────┼──────────────────────────────────────────────────────────────┤
|
|||
|
|
│ sync.toml ya tiene sitio para meterlo │ Es código nuevo en xtask, validación, tests │
|
|||
|
|
└───────────────────────────────────────┴──────────────────────────────────────────────────────────────┘
|
|||
|
|
|
|||
|
|
El veredicto del .info original fue "no urgente, pero está identificado". Coincido. Si alguna vez aparece la segunda impl, vale la
|
|||
|
|
pena cerrarlo; con una sola impl, el --target manual es perfectamente operativo.
|
|||
|
|
|
|||
|
|
Resumen en una línea
|
|||
|
|
|
|||
|
|
▎ Auto-discovery = el xtask conoce la lista de impls que consumen el registry y puede sincronizarlas en bloque sin que un humano se
|
|||
|
|
▎ las recuerde. Sigue pendiente porque con una sola impl no compensa el código adicional, pero la opción B (sidecar sync.toml)
|
|||
|
|
▎ deja el camino más despejado para resolverlo el día que haga falta.
|
|||
|
|
|
|||
|
|
✻ Churned for 59s
|
|||
|
|
|
|||
|
|
❯ implementalo, en cuanto verifiquemos jpl-website vamos a crear más sites
|
|||
|
|
|
|||
|
|
Plan en orden de dependencias:
|
|||
|
|
|
|||
|
|
TASK 1: Extender sidecar con [impls.known] en registry.rs
|
|||
|
|
COMPLEXITY: simple
|
|||
|
|
DEPENDENCIES: none
|
|||
|
|
RISKS: typos en sync.toml apuntan a paths que no existen → mitigación: validar existencia al cargar
|
|||
|
|
SUCCESS_CRITERIA: load_sidecar() retorna no_rebase + impls
|
|||
|
|
|
|||
|
|
TASK 2: Refactorizar sync.rs para extraer sync_one() y añadir driver --all
|
|||
|
|
COMPLEXITY: simple
|
|||
|
|
DEPENDENCIES: TASK 1
|
|||
|
|
RISKS: en --check --all, error en target N no debe abortar el chequeo de N+1
|
|||
|
|
SUCCESS_CRITERIA: sync_one por target, drift de cualquier target → exit 1 al final
|
|||
|
|
|
|||
|
|
TASK 3: Añadir flag --all en CLI (conflicts_with --target y --overlay)
|
|||
|
|
COMPLEXITY: trivial
|
|||
|
|
DEPENDENCIES: TASK 2
|
|||
|
|
SUCCESS_CRITERIA: --all sin --target ni --overlay funciona; combinarlos error
|
|||
|
|
|
|||
|
|
TASK 4: Declarar ../jpl-website en registry/sync.toml [impls.known]
|
|||
|
|
COMPLEXITY: trivial
|
|||
|
|
DEPENDENCIES: TASK 3
|
|||
|
|
SUCCESS_CRITERIA: cargo xtask sync-deps --all itera 2 targets
|
|||
|
|
|
|||
|
|
TASK 5: Sustituir deps-sync-all en justfile + añadir deps-sync-check-all
|
|||
|
|
COMPLEXITY: trivial
|
|||
|
|
DEPENDENCIES: TASK 4
|
|||
|
|
SUCCESS_CRITERIA: just deps-sync-check-all exit 0
|
|||
|
|
|
|||
|
|
TASK 6: Documentación (info, QA, replication plan)
|
|||
|
|
COMPLEXITY: simple
|
|||
|
|
DEPENDENCIES: TASK 5
|
|||
|
|
SUCCESS_CRITERIA: auto-discovery sale de Open Items y aparece en Architecture
|
|||
|
|
|
|||
|
|
Empiezo.
|
|||
|
|
|
|||
|
|
|
|||
|
|
⏺ ★ Insight ─────────────────────────────────────
|
|||
|
|
|
|||
|
|
- El refactor importante fue normalizar paths registry-relative →
|
|||
|
|
rustelo-root-relative en el loader, en lugar de cambiar la lógica del render.
|
|||
|
|
Eso preservó el contrato de Rebase::translate_path y evitó romper el
|
|||
|
|
rustelo-root-relativos, no registry-relativos). Una capa de traducción
|
|||
|
|
centralizada en un solo punto = un solo sitio que mantener.
|
|||
|
|
- sync_one retorna un enum SyncOutcome en vez de un ExitCode. Eso permite al
|
|||
|
|
driver de --all agregar drift de N targets sin perder información: cada target
|
|||
|
|
imprime su outcome, y solo al final el run agregado decide el código de
|
|||
|
|
salida. Si hubiera usado ExitCode, habrías tenido que return-early en el
|
|||
|
|
primer drift.
|
|||
|
|
- Adding una impl ahora es exactamente una línea en registry/sync.toml. No
|
|||
|
|
xtask, no recetas. Esa es la propiedad clave para tu plan de crear más sites:
|
|||
|
|
la fricción operacional al escalar de N=1 a N=K se mantiene constante (O(1)
|
|||
|
|
por impl).
|
|||
|
|
─────────────────────────────────────────────────
|
|||
|
|
|
|||
|
|
GUIDELINE: rust.md (no unwrap, idiomatic, ?, expect, clippy -D warnings clean)
|
|||
|
|
IMPLEMENTING: auto-discovery de impls vía [impls.known] en sync.toml + --all
|
|||
|
|
en xtask
|
|||
|
|
EXCLUDED: ondaod evaluation (sin solicitud de adr?), commits
|
|||
|
|
|
|||
|
|
Cambios
|
|||
|
|
|
|||
|
|
┌───────────────────────┬──────────────────────────────────────────────────┐
|
|||
|
|
│ Archivo │ Acción │
|
|||
|
|
├───────────────────────┼──────────────────────────────────────────────────┤
|
|||
|
|
│ xtask/src/registry.rs │ Sidecar struct, load_sidecar() público, │
|
|||
|
|
│ │ normalize_registry_path() (strip ..) │
|
|||
|
|
├───────────────────────┼──────────────────────────────────────────────────┤
|
|||
|
|
│ xtask/src/sync.rs │ refactor en sync_one() + driver de --all; agrega │
|
|||
|
|
│ xtask/src/sync.rs │ refactor en sync_one() + driver de │
|
|||
|
|
│ │ --all; agrega drift sin fail-fast │
|
|||
|
|
├─────────────────────────────────────┼────────────────────────────────────┤
|
|||
|
|
│ │ revert al contrato original │
|
|||
|
|
│ xtask/src/render.rs │ (Dep.path rustelo-root-relative, │
|
|||
|
|
│ │ sin canonicalize) │
|
|||
|
|
├─────────────────────────────────────┼────────────────────────────────────┤
|
|||
|
|
│ xtask/src/main.rs │ flag --all, --target ahora │
|
|||
|
|
│ │ Option<PathBuf> │
|
|||
|
|
├─────────────────────────────────────┼────────────────────────────────────┤
|
|||
|
|
│ registry/sync.toml │ añadido [impls] known = │
|
|||
|
|
│ │ ["../jpl-website"] │
|
|||
|
|
├─────────────────────────────────────┼────────────────────────────────────┤
|
|||
|
|
────────────────────────────────────────
|
|||
|
|
Archivo: .coder/2026-05-26-deps-sync.info.md
|
|||
|
|
Acción: [impls] documentado, --all documentado, auto-discovery movida de Open
|
|||
|
|
→
|
|||
|
|
Closed
|
|||
|
|
────────────────────────────────────────
|
|||
|
|
Archivo: reflection/qa.ncl (rustelo)
|
|||
|
|
Acción: sección PROPAGATE TO IMPLEMENTATIONS actualizada con --all
|
|||
|
|
────────────────────────────────────────
|
|||
|
|
Archivo: .coder/2026-05-26-deps-sync-replication.plan.md
|
|||
|
|
Acción: Task 2 y Task 8 actualizadas con [impls.known] y --all
|
|||
|
|
|
|||
|
|
Verificación
|
|||
|
|
|
|||
|
|
$ cargo xtask sync-deps --check → exit 0
|
|||
|
|
$ cargo xtask sync-deps --all --check → 2 targets, exit 0
|
|||
|
|
$ cargo xtask sync-deps --all --target X → rejected (exit 2)
|
|||
|
|
$ cargo xtask sync-deps --all --overlay Y → rejected (exit 2)
|
|||
|
|
$ cargo clippy --manifest-path xtask/Cargo.toml -- -D warnings → exit 0
|
|||
|
|
$ just deps-sync-check-all → 2 targets, exit 0
|
|||
|
|
|
|||
|
|
Para los próximos sites
|
|||
|
|
|
|||
|
|
Cuando crees ../site-nueva, el workflow es:
|
|||
|
|
|
|||
|
|
1. Crear el workspace ../site-nueva con [workspace.dependencies] (vacío o
|
|||
|
|
pobladio).
|
|||
|
|
|
|||
|
|
Para los próximos sites
|
|||
|
|
|
|||
|
|
Cuando crees ../site-nueva, el workflow es:
|
|||
|
|
|
|||
|
|
1. Crear el workspace ../site-nueva con [workspace.dependencies] (vacío o pobladio).
|
|||
|
|
2. Opcional: crear ../site-nueva/rustelo-deps-overlay.toml con [overlay.*] y [extra.*].
|
|||
|
|
3. Editar registry/sync.toml: añadir "../site-nueva" al array [impls.known].
|
|||
|
|
4. cargo xtask sync-deps --all — itera rustelo + jpl-website + site-nueva.
|
|||
|
|
5. (Opcional) Replicar el hook pre-commit en ../site-nueva/.pre-commit-config.yaml apuntando al xtask de rustelo.
|
|||
|
|
|
|||
|
|
No hay cambios al xtask ni a las recetas just. La operación es O(1) por impl añadida.
|
|||
|
|
|
|||
|
|
STATUS: Complete
|
|||
|
|
|
|||
|
|
|
|||
|
|
⏺ Confirmado. El doc ahora refleja el modelo [impls.known] + --all en cuatro puntos:
|
|||
|
|
|
|||
|
|
┌──────────────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Sección │ Contenido │
|
|||
|
|
├──────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Open questions (línea 67) │ Pregunta sobre impls indica que se encodean en registry/sync.toml [impls.known], no │
|
|||
|
|
│ │ en la receta │
|
|||
|
|
├──────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Task 2 RISKS (línea 104) │ Añade riesgo de impl path sin Cargo.toml │
|
|||
|
|
├──────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Task 2 SUCCESS_CRITERIA (líneas │ Schema de sync.toml incluye [impls] known = [...] │
|
|||
|
|
│ 113–114) │ │
|
|||
|
|
├──────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Task 2 NOTES (línea 121) │ Documenta que [impls.known] habilita --all y que añadir impls es one-line edit │
|
|||
|
|
├──────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Task 8 recipes (líneas 269–278) │ deps-sync-all y deps-sync-check-all usan cargo xtask sync-deps --all │
|
|||
|
|
├──────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Adaptations checklist (línea 354) │ Señala que la lista de impls va en sync.toml, no en la receta │
|
|||
|
|
└──────────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────┘
|
|||
|
|
|
|||
|
|
STATUS: Complete
|