Nuevo crate hammer-mirror + CLI `hammer mirror push|pull|status <remote>`. El /store es un CAS (dir `<hash>-<name>`, el hash ES la dirección); un mirror = ese CAS replicado entre máquinas + resolución por hash. La integridad se ancla en of_tree (content-hash BLAKE3 del árbol): el receptor RECOMPUTA of_tree sobre lo copiado y exige que case el del índice ANTES de sellar (Store::seal, atómico + read-only en un staging del mismo FS) ⇒ una transferencia corrupta/manipulada se RECHAZA, no se instala. - index(store): enumera dirs `<64hex>-<name>` (filtra bootstrap.json/.bootstrap-tmp), of_tree cada uno. diff(src,dst): faltantes en cada lado + conflictos (mismo dir, otro contenido). - sync(src,dst): copia los que faltan (verificados), idempotente, no sobrescribe conflictos. push = sync(local,remoto); pull = sync(remoto,local). - Transporte = filesystem (el remoto es una ruta a otro store, p.ej. sshfs); SSH/red queda como envoltorio ortogonal posterior. Endurecimiento: anclar of_tree a una raíz firmada (bootstrap.json / atestación D) vs un origen plenamente malicioso. 5 tests unitarios (forma de dir, índice, sync idempotente, rechazo de transferencia corrupta, conflicto-no-sobrescribe) + validado E2E con el CLI sobre artefactos reales (push/pull/status, idempotencia, bytes idénticos, tamper→conflicto, conflicto no sobrescrito exit≠0). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
62 lines
1.8 KiB
TOML
62 lines
1.8 KiB
TOML
[workspace]
|
|
resolver = "2"
|
|
members = [
|
|
"crates/hammer-core",
|
|
"crates/hammer-build",
|
|
"crates/hammer-bootstrap",
|
|
"crates/hammer-overlay",
|
|
"crates/hammer-journal",
|
|
"crates/hammer-mirror",
|
|
"crates/hammer-agent",
|
|
"crates/hammer-cli",
|
|
"crates/hammerd",
|
|
"crates/netup",
|
|
]
|
|
|
|
[workspace.package]
|
|
version = "0.0.1"
|
|
edition = "2021"
|
|
license = "MIT"
|
|
authors = ["sergio <gerencia@jlsoltech.com>"]
|
|
repository = "https://gitea.gioser.net/sergio/hammer"
|
|
|
|
[workspace.dependencies]
|
|
hammer-core = { path = "crates/hammer-core" }
|
|
hammer-build = { path = "crates/hammer-build" }
|
|
hammer-bootstrap = { path = "crates/hammer-bootstrap" }
|
|
hammer-overlay = { path = "crates/hammer-overlay" }
|
|
hammer-journal = { path = "crates/hammer-journal" }
|
|
hammer-mirror = { path = "crates/hammer-mirror" }
|
|
hammer-agent = { path = "crates/hammer-agent" }
|
|
|
|
# shared third-party deps, pinned at the workspace level
|
|
anyhow = "1"
|
|
thiserror = "2"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
serde_yaml = "0.9"
|
|
toml = "0.8"
|
|
# postcard + ulid: SÓLO para releer el frame del bus de arje (hammerd::arje_link). Versiones
|
|
# alineadas con las que usa arje-bus (postcard 1.1.x, ulid 1.2.x) para garantizar el mismo wire.
|
|
postcard = { version = "1", features = ["use-std"] }
|
|
ulid = { version = "1", features = ["serde"] }
|
|
blake3 = "1"
|
|
sha2 = "0.10"
|
|
hex = "0.4"
|
|
base64 = "0.22"
|
|
ed25519-dalek = "2"
|
|
getrandom = "0.2"
|
|
nix = { version = "0.30", default-features = false, features = ["fanotify", "fs", "user"] }
|
|
tempfile = "3"
|
|
clap = { version = "4", features = ["derive"] }
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
|
|
[profile.release]
|
|
# small, static-friendly binaries for the userland
|
|
opt-level = "z"
|
|
lto = true
|
|
codegen-units = 1
|
|
strip = true
|
|
panic = "abort"
|