Commit Graph
475 Commits
Author SHA1 Message Date
sergioandClaude Opus 4.8 ef86e4f986 arranque-grafo: current/default siempre presentes — interop con el lector de mirada
Verificado contra el parser REAL del otro agente (mirada-boot-core::BootGraph,
recién commiteado en tawasuyu): su struct declara `current: String` y
`default: String` OBLIGATORIOS (sin Option, sin default). Mi emisor los omitía
(`skip_serializing_if`) cuando no hay generación viva ⇒ en un sistema recién
instalado (cero upgrades) el JSON era `{"version":1,"nodes":[]}` y mirada
fallaba al parsear con "missing field `current`".

Fix del lado productor (adaptar la salida a la forma publicada del contrato):
BootGraph.current/default pasan a String, presentes siempre, cadena vacía = "sin
generación viva" (degrada limpio: default_index() de mirada cae al primer
bootable). Probado e2e pasando el JSON real de `hammer boot graph` (vacío +
poblado) por mirada-boot-core::BootGraph::from_path → ambos OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 22:34:49 -04:00
sergioandClaude Opus 4.8 3c343bee9a arranque-grafo: paso 3 del ADR 0010 — grafo de estados + hammer boot
El menú de arranque como navegación del grafo content-addressed de estados
(no una lista de kernels). Sube el modelo de generaciones in-place a un grafo
navegable y define el contrato de datos con mirada.

- hammer_upgrade::boot_graph: BootGraph/BootNode (formato exacto del contrato),
  build() arma el DAG desde las generaciones (id = of_tree sin b3:, parents =
  of_tree del padre, Base para la raíz del linaje), nodo Recovery sintético
  colgando de la viva, emit() atómico a /run/hammer/boot-graph.json.
- activate(): resuelve el id content-addressed a una generación y deja el
  sistema en ese nodo — no-op si ya viva, rollback paso a paso a un ancestro
  (reusa el rollback E4), recovery = un rollback, error honesto ante un "redo"
  hacia una generación huérfana (pide re-aplicar el árbol).
- CLI `hammer boot graph [--out|--stdout]` y `hammer boot activate <id>
  [--from-select]` (lee el id que mirada deja en /run/hammer/boot-select).
- Tests: DAG + activate a ancestro + recovery + redo-falla; rfc3339 sin deps.
  Validado e2e por el binario (3 generaciones → grafo → activar → recovery).

Cierra el lado `proceso` de SDD 15 §H4 (arrancar = activar un nodo del DAG).
mirada ya puede maquetar contra el grafo real (HANDOFF-arranque-grafo.md).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 20:36:04 -04:00
sergioandClaude Opus 4.8 7e21b0184b docs: ADR 0010 — arranque por grafo (menú de boot = navegación del grafo de estados, mirada+hammer)
El menú de arranque soberano (sin systemd-boot, sin GRUB) no es un port de GRUB: es la
navegación del grafo content-addressed de estados del sistema, renderizado por mirada
sobre KMS y respaldado por las generaciones/DAG de hammer. Cierra el lado 'proceso' de
SDD 15 §H4 (arrancar = activar un nodo). Fija la división de labores, el contrato de
datos (/run/hammer/boot-graph.json + hammer boot activate), el invariante cero-parpadeo
(simpledrm→i915 seamless) y la vía del loader (squashfs+overlay → initrd chico → EFI-stub
directo viable). Espejo en tawasuyu/HANDOFF-arranque-grafo.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 20:23:25 -04:00
sergioandClaude Opus 4.8 d9d891a64a granja: tanda VPS efímero 2026-07-06 — 7 promovidos al catálogo firmado (714)
dalfox/templ/errcheck/ineffassign/unconvert (Go) + dprint (Rust) + kyverno (Go),
construidos en un worker efímero hcloud, cosechados y firmados. Binarios musl-static
verificados: dalfox 3.1.2, templ v0.3.1020, dprint 0.55.1, ineffassign, y los
analizadores Go corren. feroxbuster/jless/mdcat/mise quedan staged (frontera *-sys:
openssl-sys/xcb desde fuente).

Fix farm-down: el promote final ahora recorre TODAS las colas del worker
(incoming/incoming-go/incoming-clib), no sólo recipes/incoming — los artefactos de
las otras colas se cosechaban pero no se firmaban.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 07:31:05 -04:00
sergioandClaude Opus 4.8 e2e5bc6f04 granja: fix host-key en workers efímeros — known_hosts a /dev/null
Los workers efímeros reciclan IPs de Hetzner. accept-new RECHAZA una clave de host
cambiada ⇒ el 'until ssh true' de farm-up colgaba para siempre en una IP reusada.
Como el modelo es hub-and-spoke (worker sin secretos, compute descartable) no hay
superficie MITM: saltamos verificación de host y no ensuciamos known_hosts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 06:56:25 -04:00
sergioandClaude Opus 4.8 b90855dc30 granja: farm-run.sh — el ciclo efímero desatendido (up→esperar-ciclo→cosecha+destruye)
Encadena farm-up + farm-down con detección de fin-de-ciclo por el marcador 'ciclo
terminado' del worker-loop (cuenta ocurrencias en el journal, robusto a skew de reloj
y builds largos). 'Subí la cola, corré esto, se apaga solo al terminar.'

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 06:47:11 -04:00
sergioandClaude Opus 4.8 7891654810 granja: cola fresca para prueba VPS efímero — 11 recetas nuevas (dalfox/templ/errcheck/ineffassign/unconvert/kyverno Go + jless/dprint/mdcat/feroxbuster/mise Rust), purga cola stale ya-en-catálogo
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 06:46:39 -04:00
sergioandClaude Opus 4.8 3e520d4477 H4e: requires OBSERVADOS — dep de runtime divergida = incompatible (SDD 15 §H4)
Cierra la simetría de la vía observada: además de observar lo que un paquete escribe (H4c),
observa de qué depende A UNA VERSIÓN. Fuente observable sin declaración: el paquete se
construyó contra la versión de sus deps que hay en el repo (deps.runtime del .swm +
expected_hash de cada dep en el índice); si el usuario tiene esa dep instalada a OTRO hash,
la divergió -> rechazo duro. Es el caso wayland DERIVADO (el que H4b captura cuando el autor
declara requires, ahora leído del cierre).

- compat::observed_requires(swm, index) + version_conflicts(db, req) — reusan deps del .swm,
  expected_hash del índice e InstalledDb.hash (cero declaración nueva).
- Cableado en install (rechazo duro, no lo salva --force-slots) y en `hammer compat`.
- Verificado e2e real: `hammer compat` marca app INCOMPATIBLE por su dep wayland-protocol
  instalada a un hash divergido del repo (read-only, ve el source_patch sin construirlo).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 06:29:22 -04:00
sergioandClaude Opus 4.8 bbf4411af0 H4d: hammer compat <repo> — la búsqueda que particiona un repo contra lo instalado (SDD 15 §H4)
Responde la pregunta que arrancó §H4 ("cuando busco, ¿cuáles puedo adoptar?"): es el `filtrar`
del prototipo wawa-memo, ahora sobre el repo real y READ-ONLY (no construye ni toca nada).
Evalúa cada paquete contra el estado instalado y lo parte en {compatibles, requieren-elección,
incompatibles}, combinando la vía declarada (slots, H4b) con la observada (paths, H4c):
incompatible domina, colisión (de slot o fichero) -> elección, si no compatible.

Verificado e2e real (tests/compat_gate.rs): un repo de dos paquetes se parte correctamente
(uno choca de fichero con lo instalado -> elección; otro limpio -> compatible).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 20:23:19 -04:00
sergioandClaude Opus 4.8 9be7bdd707 H4c: superficies OBSERVADAS — colisión de fichero en install sin declarar slots (SDD 15 §H4)
La misma subida de H1 (prometer -> verificar), ahora sobre topología: la superficie más
común de un paquete es el conjunto de paths que escribe, y esos paths ya están declarados
en el .swm (target_bin + file_drop.path), conocidos ANTES de hidratar.

- compat::output_paths(swm) lee esos paths; compat::path_collisions(db, name, paths) detecta
  cuáles ya posee OTRO paquete instalado (reusa InstalledDb.files + owner_of, cero declaración
  nueva). Reinstalar el mismo paquete sobre sus propios paths NO colisiona (upgrade).
- Gate en `install` corre el chequeo observado JUNTO al declarado (H4b): pisar el fichero de
  otro paquete = caso logo a nivel de fichero (elección) -> aborta salvo --force-slots.
- Verificado e2e REAL (tests/compat_gate.rs, shell-ea al binario hammer): dos paquetes
  escriben /share/logo.png; el 2do aborta con "COLISIÓN de fichero" sin escribir nada; con
  --force-slots la elección se respeta y el fichero se escribe.

Un paquete SIN declarar slots ya participa del gate por lo que de verdad toca.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 20:17:17 -04:00
sergioandClaude Opus 4.8 27066776b3 H4b: gate de compatibilidad de configs en la receta real + hammer install (SDD 15 §H4)
Sube el modelo de slots de wawa-memo (prototipo host) a hammer:
- Recipe + source_patch del .swm llevan bloque `slots` {claims, requires} (slot->b3:…),
  FUERA de hash_inputs (topología ≠ identidad, no mueve el artifact_hash). Viaja intacto
  por los dos sentidos del puente (Recipe->.swm->Recipe): test de round-trip.
- InstalledDb registra claims por paquete + system_state() -> slot->hash (el Estado del gate).
- hammer-core::compat::evaluar(estado, slots) -> Veredicto {Compatible, Colision, Incompatible}
  (el álgebra probada en wawa-memo, sobre tipos de hammer).
- Gate en `hammer install`: antes de tocar nada evalúa el paquete contra el estado instalado.
  Incompatible (requisito sin resolver, caso wayland) -> aborta; Colisión (caso logo) ->
  aborta pidiendo elección salvo --force-slots; Compatible -> procede y registra los claims.

Plumbing propagado por los 5 sitios de Mutation::SourcePatch (from_recipe, swm_bridge,
export, bus, orchestrator). Tests: compat (4) + slots-no-en-hash/round-trip (2) +
system_state (1) + puente receta<->swm (1). Workspace compila y verde.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 20:10:02 -04:00
sergioandClaude Opus 4.8 66241c31a4 docs: SDD 15 §H4 — configs compartidas (compatible/completa/segura) + la ambición hasta config=paquete=función=proceso
Aterriza H2/H3 sobre el caso de uso real del usuario: compartir configuraciones
por la malla y, al buscar, saber que son compatibles/completas/seguras.
- H4a  (prototipo en wawa-memo): el modelo de slots reclama/requiere; compatible
  = colisión sobre la misma superficie (logo=elección, wayland=rechazo); completa y
  segura reusan H3c/H2c.
- H4b: subir slots a la receta/.swm real (InstalledDb como slot->Id).
- Sección "la ambición hasta el final": config y programa son el mismo objeto (hash);
  el último lado abierto es el proceso (replay del MonotonicLog, plan OS-CRDT).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 17:57:12 -04:00
sergioandClaude Fable 5 e72a630d31 docs: SDD 15 §H3c — formato de viaje canónico del Paquete + wawa-verifica (el puente concreto paquete↔función)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 10:31:28 -04:00
sergioandClaude Opus 4.8 5658e9337c granja: ciclo de vida EFÍMERO por hcloud API (farm-up/farm-down) + baseline €0
Migración del worker pet-24/7 a workers efímeros on-demand. farm1 (ccx23 persistente que
idleaba quemando plata) → snapshot golden 'hammer-golden-2026-07-05' (img 405120842: toolchain
+ store sellado horneados) → destruido. Baseline ahora 0 cajas / €0.

- farm-up.sh [N]: crea N workers desde el snapshot (cache-hit instantáneo del catálogo baked),
  los alinea con la cola actual del laptop, registra la flota en scripts/farm/.fleet (gitignored).
- farm-down.sh [name...]: cosecha el store (CAS, merge seguro) al laptop y DESTRUYE; promueve+firma.
  Orden seguro: sólo destruye si el pull de store salió bien.
- Validado punta a punta: up 1 → boot+cache+toolchain OK → down (cosecha+destruye) OK.
- Cron laptop harvest-go contra farm1 removido (la cosecha ahora la hace farm-down).

El worker sigue sin secretos (hub-and-spoke): compute puro y descartable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 08:23:06 -04:00
sergioandClaude Opus 4.8 c516f9a5ea Etapa G (go): promovida tanda go-2026-07-05b al catálogo firmado (anew/chartmuseum/fortio/goldilocks/kluctl/nancy/pint/sake/timetrace) + gotools nuevo
Cosecha del ciclo que sacó al VPS del idle. Build-yield 20/22 en incoming-go (fallan
dolt/migrate, quedan staged). El resto de las 'frescas' del refeed resultaron duplicados
ya catalogados (hugo/delve/glow/sops/dnsx/kubeseal/dbmate/jsonnet-bundler/opa/scaleway-cli
promovidos en tandas previas).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 08:16:19 -04:00
sergioandClaude Opus 4.8 a917149116 Etapa G (go): re-alimento incoming-go — 13 recetas frescas al VPS idle (hugo/delve/glow/opa/scaleway-cli/kubeseal/dolt/dbmate/migrate/sops/gotools/dnsx/jsonnet-bundler)
El worker VPS estaba idle (load 0.01): las 3 colas eran 100% cache-hit (tanda go-2026-07-05b
sellada, incoming/ del otro agente, incoming-clib 21/21). Cosecho 13 attrs Go nuevos verificados
por nix eval (los alias de las listas de refeed daban 'ninguna fuente' por no ser attrs reales).
Import 13/13 nix + pin tag→SHA + rsync dirigido a la cola aislada incoming-go/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 07:54:09 -04:00
sergioandClaude Fable 5 6e602707fd Etapa G (go): puredns diferido (go.mod 1.16 vs unsafe.Slice, clase gotop) — tanda 2026-07-05b queda 9/10 sellada
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 06:21:34 -04:00
sergioandClaude Fable 5 3ff1823e38 docs: SDD 15 §H3c hecho — el linker de contenido (grano intra-función por hash, Merkle-DAG de código)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 06:20:07 -04:00
sergioandClaude Fable 5 6c655642b6 Etapa G (go): re-cola kluctl (go build -o: main en ./cmd sellaba binario 'cmd') + tanda 2026-07-05b a mano (fortio/nancy/chartmuseum/sake/timetrace/anew/puredns/pint/goldilocks, tags por ls-remote) + werf diferido (gpgme como skopeo)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 05:57:09 -04:00
sergio b615adeaae Etapa G: cosecha-go finde (auto) — promovidos: bom crossplane-cli fabric-ai kn kubectl-neat oh-my-posh prometheus-blackbox-exporter prometheus-node-exporter timoni | review: kluctl(bin=cmd) 2026-07-05 05:55:34 -04:00
sergioandClaude Fable 5 3eda286806 Etapa G (go): +4 a la cola (kluctl/timoni/kubectl-neat/kn) — el corpus ya cubre 803 nombres, la cola larga adelgaza
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 05:43:27 -04:00
sergioandClaude Fable 5 f922450c62 Etapa G (go): bom flags=./cmd/bom (raíz = magefiles con build-tags que excluyen todo) + aws-vault/minikube diferidos (CGO: onepassword-sdk / libvirt)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 05:39:57 -04:00
sergioandClaude Fable 5 e4ef80b76e Etapa G (go): cosecha 20 + syft/traefik promovidos a mano (pack fallaba: patches no viajaban a recipes/ — fix en harvest-go) + pre-check por name interno del TOML (exporters) + re-cola crossplane-cli/fabric-ai/oh-my-posh con fixes (alias crossplane, ./cmd/fabric, -o oh-my-posh) + logs por-cola en build-farm
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 05:31:58 -04:00
sergio ec8bb17fd8 Etapa G: cosecha-go finde (auto) — promovidos: apko atlas crane flyctl go-migrate gomi grype jsonnet-bundler krew kubescape melange rekor-cli revive scorecard seaweedfs staticcheck step-ca tea trivy xq | review: crossplane-cli(bin=crossplane) fabric-ai(bin=code2context) oh-my-posh(bin=src) syft(pack) traefik(pack) 2026-07-05 05:27:49 -04:00
sergioandClaude Fable 5 5c4c2cd153 Etapa G (go): grype/traefik a vía Go auto (les faltaba deps.build=go, fases abuild llamaban go a ciegas) + dolt diferido (cgo→ICU externa, necesita receta icu4c)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 00:51:58 -04:00
sergioandClaude Fable 5 46a2d777d3 Etapa G (go): re-alimenta la granja — tanda 2026-07-05 (15 recetas: flyctl/kubescape/seaweedfs/melange/step-ca/scorecard/krew/…, 11 a mano por fetchgit-NAR + 4 import nix), aliases de gate (weed/migrate/jb/fabric/crank) y descarte flux=misimport DirectFB
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 00:47:09 -04:00
sergioandClaude Fable 5 3171dd59f9 Etapa G (go): triage cola envenenada del VPS — purga 25 (misimports/CGO/embed) + 10 fixes (subdir dolt-atlas-omp, crane ./cmd/crane, trivy GOEXPERIMENT=jsonv2, xq/tea/staticcheck/syft/apko a vía Go auto)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 00:35:40 -04:00
sergio ba1b91b225 Etapa G: cosecha-go finde (auto) — promovidos: ssh-vault talosctl | review: 2026-07-04 20:05:19 -04:00
sergio 83e41a2174 Etapa G: cosecha-go finde (auto) — promovidos: kubie skaffold | review: terrascan(smoke) 2026-07-04 08:05:32 -04:00
sergio 460a4bb7e3 Etapa G: cosecha-go finde (auto) — promovidos: gocron lego | review: flux(bin=fluxcomp) kics(bin=builder) 2026-07-04 07:35:16 -04:00
sergioandClaude Opus 4.8 d94544b34d Etapa G (go): re-alimenta la granja — tanda go-refeed (51 recetas) a incoming-go
Prioridad: el worker VPS nunca idle. Import de 108 candidatos Go nuevos (listas
fuel-go menos el corpus); 2 olas → 51 recetas importadas (yield ~47%), pusheadas
a la cola incoming-go del VPS. El worker las está moliendo (load ~17). Incluye
proyectos Go grandes (dolt/etcd/dagger/crane/gitlab-runner/forgejo) que vendorean
cientos de deps ⇒ builds largos. Crudas de nixpkgs (tag sin pin, algún misimport
Python que falla inocuo); la cosecha promueve sólo las que sellan + pasan smoke.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 07:33:19 -04:00
sergio 83219e17aa Etapa G: cosecha-go finde (auto) — promovidos: temporal-cli | review: 2026-07-04 07:12:09 -04:00
sergioandClaude Opus 4.8 0b04c90d5b Etapa G (go): re-encola temporal-cli con el main correcto + alias de cosecha
El repo temporalio/cli tiene 3 mains bajo cmd/ (gen-commands, gen-docs,
temporal); detect_go_main elegía gen-commands ⇒ binario equivocado, quedó
en needs-review. Fix: flags=["./cmd/temporal"] apunta al CLI real (verificado
vía API de GitHub en el commit fijado). El binario se llama `temporal`, así
que agrego el alias temporal-cli→temporal al gate de harvest-go.sh (mismo
patrón que opentofu→tofu). Vuelve a recipes/incoming-go para que el worker
lo selle y la cosecha lo promueva.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 06:53:25 -04:00
sergioandClaude Opus 4.8 aad80ca519 docs: SDD 15 §H3b — puente H3b↔H2c (compartir programas por la malla, seguros por construcción)
Cierra la tesis de §H3: un programa entero viaja como Paquete verificable
en dos capas — integridad del código por el hash (tamper-evident sin firmar)
+ verdad del resultado por reproducción (H2c). Implementación en tawasuyu
wawa-memo/src/programa.rs (8 tests, total wawa-memo 30).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 06:45:48 -04:00
sergioandClaude Opus 4.8 fdfaab5151 docs: SDD 15 §H3b hecho — código por contenido estilo Unison sobre el grano wasm de H2
El núcleo del modelo Unison (definir por hash, nombres como metadata,
actualizar sin romper, componer por hash) se sostiene sobre el runtime
de wawa. Implementación en tawasuyu wawa-memo/src/base.rs (8 tests verdes).
Frontera: es el subconjunto que wasm+BLAKE3+H2 sostienen, no el colapso
total paquete=función=proceso (sigue ambición, no promesa).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 06:31:57 -04:00
sergioandClaude Opus 4.8 efe1dfcc46 docs: SDD 15 §H2c — núcleo de confianza hecho (sellado + verificar-reproduciendo)
En wawa-memo: sellado de portabilidad (Portable/SoloLocal, sella el vector
NaN cross-arch) + modelo de confianza (ingerir_ajeno verifica reproduciendo,
rechaza envenenamiento). Transporte de malla diferido al otro agente
(PLAN-OS-CRDT E3). Tests h2c.rs verdes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 20:17:29 -04:00
sergioandClaude Opus 4.8 ea2dface82 docs: SDD 15 §H2b hecho — memoización de ejecución wasm (cómputo como dato)
El prototipo vive en tawasuyu/03_ukupacha/wawa/wawa-memo (crate host/std):
reproduce la vía pura del kernel y monta la clave del contrato §4 sobre un
LwwMap. Test §5 verde (72 casos byte-idénticos, Hit/Miss, fallas cacheadas,
E-invalidación, merge de malla). Desbloquea H2c.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 20:07:33 -04:00
sergioandClaude Opus 4.8 b173630e81 query: exports:<elf> — procedencia por-símbolo (puente barato de ADR 0009)
Extiende el parser ELF (parse_elf_needed→parse_elf_info): además de DT_NEEDED,
recorre .dynsym (DT_SYMTAB) y extrae los símbolos EXPORTADOS (defined +
global/weak). Nuevo término `exports:<path>` en el mini-lenguaje de queries;
fluye por el bus (query expr) sin cambios. Metadata descriptiva, fuera de
hash_inputs (misma disciplina que la evidencia de H1). Refactor: helper
vaddr_to_file_off compartido por strtab/symtab + cstr_at.

nsyms vía layout convencional (strtab sigue a symtab); best-effort → [] si no
se puede acotar con seguridad. Validado end-to-end: 2873 símbolos reales de
/lib/libc.so.6 (aguanta glibc y musl). Tests: term-parse + missing-file +
host-gated real-.so. Workspace verde (33 suites).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 06:10:59 -04:00
sergioandClaude Opus 4.8 236aac7c7f docs: ADR 0009 código direccionado por contenido (H3a) — registrar visión Unison
Design-doc de la idea 3 (SDD 15 §H3): decide NO reescribir la unidad de
compilación. Puente barato = procedencia por-símbolo como metadata (extender
el parser ELF parse_elf_needed para emitir exports de .dynsym), fuera de
hash_inputs — misma disciplina que la evidencia de H1. El grano fino real
(función-por-hash) se difiere a H3b sobre wasm, gateado por el determinismo H2.
Marca §H3a  en la frontera.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 06:03:48 -04:00
sergioandClaude Opus 4.8 7a708aa282 docs: SDD 15 §H2a hecho — auditoría de determinismo wasm de wawa
El subconjunto puro ya existe (ejecutar_dinamico/_v2, linker vacío); H2a lo
sella con un contrato de clave de caché + hash-de-entorno. Deliverable en
tawasuyu/03_ukupacha/wawa/SDD-determinismo.md. Desbloquea H2b (prototipo de
memoización local blake3(módulo)⊕blake3(entrada)→salida).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 01:11:21 -04:00
sergioandClaude Opus 4.8 6ac6438c00 H1c (proof-carrying recipes): cablea la evidencia al Orchestrator VERIFY
La evidencia corre del lado del BUILD (hammer-agent no depende de hammer-build:
separación PROPONE/CONSTRUYE). Piezas:

- proto: RecipeInline lleva `evidence`; Event::BuildReady lleva
  `verdict: Option<EvidenceVerdict>` (+ EvidenceCheckVerdict). Ambos con
  skip_serializing_if ⇒ wire compatible con clientes pre-H1c.
- hammerd/bus: run_compile ejecuta la evidencia declarada tras sellar el
  artefacto (run_evidence vía swm_bridge::recipe_from_source_patch) y adjunta
  el veredicto en BuildReady. Si ni se pudo ejecutar ⇒ veredicto fallido
  sintético (no pasa en silencio). El lab reporta; el gate vive en el agente.
- client: compile() devuelve CompileOutcome { artifact, verdict }.
- orchestrator: VERIFY lee el veredicto; si all_passed=false empuja
  VerifyCheck::fail y ABORTA antes de hidratar (artefacto sellado, no toca el
  sistema). Nuevo constructor VerifyCheck::fail.

Tests: roundtrip del veredicto en proto; stub-bus refleja evidencia→verdict;
nueva prueba de integración orchestrator_evidence_gate (veredicto fallido ⇒
run() aborta con "no se propone" y no hidrata). Suite completa verde (33 suites).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 13:33:25 -04:00
sergioandClaude Opus 4.8 497d0d00e7 H1b (proof-carrying recipes): checker swm-verify --evidence que ejecuta la evidencia
El verificador que corre cada check en el sandbox reproducible y falla ⇒ no proponer
(SDD 15 §H1). Piezas: (1) hammer-core: EvidenceCheck::evaluate(exit, stdout) -> CheckOutcome
(pura, testeada: exige expected_exit y, si hay, blake3(stdout)==expected_output) +
ArtifactHash::of_bytes. (2) hammer-build: Sandbox::run_capture -> CmdOutcome (captura stdout
completo + exit, tee de stderr) + run_evidence(recipe,cfg,store) -> EvidenceReport que
reproduce el artefacto (cache-hit), levanta un sandbox con fuente+build-deps+el artefacto
instalado como capa overlay (binarios en PATH) y corre cada check. (3) CLI: swm-verify
--evidence reconstruye cada source_patch y corre run_evidence; imprime veredicto por check +
estrato máximo alcanzado; exit != 0 si algún check falla. Es un runner de comandos con hash
del output, no un framework — la confianza vive en el checker.

Verificado e2e: tree con [[evidence.checks]] cmd-exit 'tree --version' → pack cache-hitea
(evidencia no cambia el hash) → swm-verify --evidence corre el check en el sandbox: pasa (exit
0) y falla con expected_exit=7 (exit 1, 'NO proponer'). Núcleo puro con tests unitarios.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 13:03:34 -04:00
sergioandClaude Opus 4.8 39f0f26e7b H1a: fix construcción SourcePatch en test del orchestrator (campo evidence faltante)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 12:42:56 -04:00
sergioandClaude Opus 4.8 3116ccfc93 H1a (proof-carrying recipes): bloque evidence en receta y .swm
Frontera AI-nativa SDD 15 §H1. Agrega `Evidence { checks: Vec<EvidenceCheck> }` a Recipe
(TOML) y a Mutation::SourcePatch (.swm YAML): cada check es {kind, cmd, expected_exit,
expected_output?} con kind ∈ {cmd-exit, proptest, contract, kani} (estratos de confianza
crecientes, EvidenceKind: Ord). DECISIÓN CLAVE: la evidencia NO entra en hash_inputs —
certifica comportamiento, no identidad ⇒ no mueve el artifact_hash (baseline de
reproducibilidad intacto). Round-trip completo: from_recipe (forward) + swm_bridge
synthesize_recipe (reverse) + camino de pack (cli). verify_schema valida forma (cmd no
vacío, expected_output con prefijo b3:). El checker que EJECUTA la evidencia es H1b; el
cableado al Orchestrator VERIFY es H1c (marcado con evidence: _). Tests: recipe + swm,
incl. que la evidencia no cambia el hash. Sin warnings clippy nuevos.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 12:41:23 -04:00
sergioandClaude Opus 4.8 49106ed4ca Etapa G (GUI): appstream — agrega openssl a build-deps (dep transitiva de libcurl.pc)
appstream (dep compartida de libadwaita + demos GTK) usa libcurl en su meson (meson.build:171)
y declaraba curl+zlib sin openssl; libcurl.pc trae Requires: zlib,openssl ⇒ sin openssl.pc en
el sandbox, appstream falla y bloquea toda la cadena aguas arriba. Raíz real del muro que se
veía como 'libadwaita openssl not found' (el que fallaba era appstream, dep de libadwaita).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:49:50 -04:00
sergioandClaude Opus 4.8 d283630ecf Etapa G (GUI): libadwaita/demos — agrega openssl a build-deps (dep transitiva de libcurl.pc)
Las 4 recetas que dependen de curl (libadwaita + adwaita-hello/hammer-edit/sourceview-hello)
declaraban curl+zlib pero no openssl; libcurl.pc trae Requires.private: openssl (y libcurl.pc
sin openssl.pc en el sandbox ⇒ meson falla 'Dependency lookup for libcurl failed: openssl not
found'). Mismo patrón que harfbuzz/fontconfig. openssl ya está en el catálogo (recipes/openssl.toml).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:38:19 -04:00
sergioandClaude Opus 4.8 eae22122f5 Etapa G (GUI): cairo — preserva cairo-script-interpreter.pc (fix de regresión)
El patch anterior desactivaba el subdir cairo-script ENTERO para esquivar el link de pixman de
los ejecutables csi-*, pero eso quitaba libcairoscript + cairo-script-interpreter.pc, que los
demos GTK (gtk4-hello/adwaita-hello/sourceview-hello/hammer-edit) piden por pkg-config. Ahora el
subdir se construye (librería estática + .pc) y solo los EJECUTABLES csi-* se envuelven en
if false. cairo-trace queda saltado (nada pide su .pc). Verificado: cairo-script-interpreter.pc
presente en el artefacto sellado.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:35:54 -04:00
sergioandClaude Opus 4.8 823c7e1171 Etapa G (granja): concilia la colisión de concurrencia — reintento serial de fallos por dep compartida
build-farm.sh asumía 'sin colisión entre recetas distintas', falso para deps transitivas
compartidas no selladas: dos consumidores (p.ej. libadwaita/gtksourceview) construyen gtk4 a
la vez en el mismo sources/gtk4-<sha>/output ⇒ 'Some other Meson process is already using this
build directory'. Fase 1b: tras el pool paralelo, reintenta EN SERIE los fallos con firma de
colisión — la dep ya la selló el ganador ⇒ cache-hit y compila. Un pase basta (cada build
arrastra sus deps). Sólo reintenta colisiones, no MSRV/dep-faltante reales.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:25:19 -04:00
sergioandClaude Opus 4.8 a3732fc964 Etapa G (GUI): harfbuzz — agrega libpng a build-deps (dep transitiva de freetype2.pc)
freetype se compila --with-png ⇒ freetype2.pc trae Requires: zlib, libpng. harfbuzz tenía
zlib pero no libpng ⇒ pkg-config no resolvía freetype2 y meson setup abortaba
('freetype2 required but not found'). Mismo patrón que fontconfig (80a9cac). Con cairo ya
construyendo (patch ctime_r), esto destraba harfbuzz→pango (ambos sellan).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:09:17 -04:00
sergioandClaude Opus 4.8 f6b31ea3dd Etapa G (GUI): cairo construye bajo zig — patch fuerza HAVE_CTIME_R + salta utils
El probe has_function('ctime_r') de meson corre sin prefix de header ⇒ prototipo desnudo
que bajo zig-cc/gcc+musl choca con el builtin y FALLA ⇒ cairo-ps-surface.c:105 define un
fallback static que colisiona con <time.h> (error duro, tanto zig como gcc; _GNU_SOURCE en
c_args no alcanza). El patch fuerza HAVE_CTIME_R=1 tras el loop. Segundo hunk: salta los
ejecutables util csi-*/cairo-trace, que no linkean libpixman-1.a bajo la estrategia
no_fallback de zig — son dev-tools, no la librería que pango/gtk4 consumen. Resultado:
cairo 1.18.4 sella desde fuente (store c7b8703f), destraba el rebuild de la cadena GUI que
el drift de fontconfig/freetype había forzado. Cierra la Opción A (inviable) con la B real.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 10:53:23 -04:00