Versión: 1.1 Fecha: 2026-08-14 Estado: resultados medidos. La recomendación 1 fue RATIFICADA por el operador el 2026-08-14 («ratifica B más el rol de tooling y vuelve a correr el panel») — ver la sección S1b al final para la repetición; ddd-hexagonal-v2 (B + tooling) es el vocabulario candidato ratificado. La entrada en el léxico y cualquier renombrado siguen siendo pasos aparte y posteriores. Diseño: study-programme-handoff.md S1 (con S2 plegado dentro como brazo de confirmación, ratificado el 2026-08-14).
Método (lo que de verdad corrió)
- Muestra: 30 de 392 piezas del taller, muestra estratificada determinista
(directorios de capa + estratos por prefijo de nombre, cada k-ésima), sin selección a mano. La muestra completa y los hechos por pieza están en s1-vocabulary-agreement-votes-2026-08-14.tsv (360 votos, bajo control de versiones).
- Hechos por pieza: nombre, ruta, descripción del Cargo.toml (o la línea de
documentación de lib.rs), dependencias principales. Los panelistas vieron SOLO estos hechos — sin acceso al repositorio (una sola lectura del archivo de carga cada uno; anti-alucinación por construcción).
- Panel: 3 agentes sonnet independientes por celda, la misma instrucción dentro de
una celda, contexto nuevo cada vez; ningún agente clasificó bajo los dos vocabularios (entrega h8:85-93).
- Celdas 2×2: vocabulario A (
draft-v1, 8 roles) / B (ddd-hexagonal-v1, 11
roles, registrado en architectural-role-vocabulary.tsv en esta corrida) × presentación en párrafo de prosa / en campos tipados. Desviación respecto al diseño h8, declarada: el formato de RESPUESTA del brazo de prosa se acotó a líneas nombre: rol analizables (no texto del todo libre) para poder tabular los votos; el contraste de presentación vive en la entrada (párrafo contra campos tipados) y en el tipado de la respuesta (líneas contra JSON acotado por enumeración).
- Almacenamiento: consenso del brazo tipado →
crate_classification(30 renglones
por vocabulario, provenance_class='model', confianza = fracción modal); 8 métricas de acuerdo → run_measurement, run_id s1-2026-08-14; base corpus_sourcecode en 127.0.0.1:5432. La copia en git de cada voto es la fuente de verdad (ADR 0041).
Tasas de acuerdo (la métrica de H8)
| Celda | Tasa de acuerdo total | Acuerdo modal medio | κ de Fleiss |
|---|---|---|---|
| A · prosa | 0.867 | 0.956 | 0.889 |
| A · tipado | 0.767 | 0.911 | 0.787 |
| B · prosa | 0.733 | 0.911 | 0.774 |
| B · tipado | 0.833 | 0.944 | 0.857 |
Agrupado: A κ̄ = 0.838, B κ̄ = 0.816. Nota: si acaso, κ favorece a B (11 categorías contra 8 baja el acuerdo por azar), así que la lectura cruda es A empata o va ligeramente adelante; la diferencia (~0.02) está dentro del ruido para n=30 y 3 evaluadores.
La división del arquetipo — confirmada, por unanimidad
La división que predecía la entrega h8 se cumplió exactamente:
operations-approval-workflow— A:archetype6/6 en las dos celdas de A;
B: aggregate 6/6 en las dos celdas de B.
infrastructure-acquire— A:archetype(prosa 3/3; modal tipadoprimitive
2/3); B: pipeline 5/6.
Un término de A absorbía dos referentes que B distingue con acuerdo casi unánime: la máquina de estados con invariante se fue a aggregate, la escalera de adquisición por etapas se fue a pipeline. Este es el resultado más claro de la corrida: gane el vocabulario que gane, archetype debe retirarse en dos roles.
El brazo de estructura (confirmación S2) — una interacción, no un efecto principal
La presentación tipada NO subió el acuerdo de forma uniforme: subió a B (+0.083 κ) y bajó a A (−0.102 κ). La ratificación del WorkerPacket basada en precedente se mantiene (este brazo no bloquea nada), pero la afirmación «la presentación tipada siempre aumenta la consistencia» NO queda confirmada por esta muestra — se reporta tal como se encontró.
Dónde falló cada vocabulario (casos de desacuerdo, todos en el TSV de votos)
- B no tiene casa para las herramientas de desarrollo:
tools-advisory-reach,
tools-confinement-scan, tools-dev y tools-merge-resolve se repartieron entre infrastructure/application/pipeline en B-prosa (0.67 cada uno), mientras que el support de A fue unánime en los cuatro y en los dos brazos. B necesita un rol tooling/support o una convención declarada sobre infrastructure.
- B partió `domain-geo` donde el
domain_typede A fue unánime
(bounded_context contra value_object, 0.67 en los dos brazos) — la clase de tipo más gruesa de A esconde una ambigüedad real que B expone.
- Los dos vocabularios partieron `identity-auth` (A:
domain_module/domain_type/primitive, 0.33 en tipado — la peor celda de la corrida; B: bounded_context/capability 0.67) — la autenticación es genuinamente ambigua en su frontera e iría a unclassified bajo la regla de nunca adivinar; ningún panelista usó unclassified en ninguna parte, lo cual es en sí mismo un hallazgo sobre el comportamiento del panel.
- B fue unánime donde A se tambaleó en las piezas envoltorio forge-*:
adapter 30/30 votos en las dos celdas de B, contra la división component/domain_module de A en A-tipado (tres piezas en 0.67).
Recomendación (el operador ratifica; esta corrida no decide nada)
1. Tratar el titular como un empate estadístico. La regla vigente (harness-design-notes-2026-08-12.md:44-47: en un empate gana el término establecido) apunta entonces a B — pero B, tal como se corrió, tiene un hueco medido (sin rol para herramientas). Candidato: adoptar B más un rol tooling añadido, y volver a correr el panel sobre la B enmendada antes de cualquier entrada en el léxico. 2. Retirar archetype en aggregate + pipeline sin importar qué vocabulario gane — el único resultado casi unánime que cruza los dos vocabularios. 3. La ambigüedad de la clase identity-auth: el panel nunca usó unclassified; las corridas futuras deben forzar un campo de confianza por elemento para que «nunca adivines más allá de la evidencia» sea comprobable y no aspiracional.
Libro de la regla 14 (instrucción del operador en esta sesión: documenta cada paso improvisado)
Cada uno de estos corrió de forma improvisada en esta sesión y es repetible, por tanto se le debe a una herramienta Rust registrada (destino: subcomandos de tools-org-knowledge corpus que escriban en run_measurement):
1. Extracción de hechos de las piezas + muestreo estratificado — scratchpad/s1_extract.py (392 piezas → muestra de 30 + dos presentaciones de carga). 2. Cálculo del acuerdo (acuerdo total, modal, κ de Fleiss) — scratchpad/s1_agreement.py sobre el TSV de votos. 3. Emisión del SQL de consenso y métricas — scratchpad/s1_to_sql.py → INSERT en crate_classification + run_measurement. 4. Antes en esta misma sesión, la misma clase de deuda: los conteos de frecuencia de adverbios y adjetivos y la cuenta de archivos de documentos de sprint con sufijo (WORD-CHOICE.md §5) — pertenecen a corpus audit como métricas con nombre (harness-design-notes-2026-08-12.md:203-206 ya enuncia esta meta-regla).
La invocación del panel en sí (12 subagentes, con las instrucciones en la transcripción de la sesión) es trabajo del ejecutor de pasos cuando exista (dependencia S6 del programa de estudio).
---
S1b — repetición sobre la ddd-hexagonal-v2 ratificada (B + tooling), corrida s1b-2026-08-14
El operador ratificó la recomendación 1 el mismo día; 6 panelistas sonnet nuevos (3 por brazo), las mismas cargas, el mismo método. Votos: s1b-vocabulary-v2-votes-2026-08-14.tsv (180 votos). Almacenamiento: 30 renglones de consenso del brazo tipado (ddd-hexagonal-v2) + 4 métricas, run_id s1b-2026-08-14.
| Celda | Tasa de acuerdo total | Acuerdo modal medio | κ de Fleiss |
|---|---|---|---|
| v2 · prosa | 0.833 (antes B 0.733) | 0.944 | 0.854 (+0.080) |
| v2 · tipado | 0.900 (antes B 0.833) | 0.967 | 0.914 (+0.057) |
- v2-tipado es la mejor celda de todo el estudio (κ 0.914 > A-prosa 0.889). La
B enmendada ahora gana de frente, no por desempate.
- `tooling` cerró el hueco medido por completo: 30/30 votos en los dos brazos
pusieron las cinco piezas de herramientas en tooling; en la v1 esas cinco piezas producían la mayoría de los desacuerdos de B.
- Casos de desacuerdo que quedan (8, todos en el TSV de votos):
domain-geo
(bounded_context contra value_object, en los dos brazos — el único residuo estable), platform-api (application contra infrastructure — una raíz de composición que además es sustrato; candidata a unclassified o a un renglón del operador), operations-approval-workflow (en prosa se parte entre aggregate y capability; en el brazo tipado aggregate 3/3 — la línea entre identidad y ocurrente necesita los campos tipados para sostenerse), infrastructure-acquire (capability contra pipeline, en tipado), identity-auth e infrastructure-dom-reduce (un disidente cada uno, solo en prosa).
- Repetición del comportamiento del panel:
unclassifiedno se usó ni una vez en
540 votos entre las dos corridas. La recomendación 3 (un campo de confianza obligatorio por elemento) se mantiene.
Estado después de S1b: ddd-hexagonal-v2 es el vocabulario ratificado, medido como el mejor en los dos brazos. La entrada en el léxico aterrizó el mismo día (ratificación del operador; ver la sección de vocabulario ratificado de docs/reference/lexicon-policy.tsv — los términos acuñados perdedores quedan prohibidos donde es seguro por subcadena, y los roles se listan como términos a CONSERVAR). Deliberadamente NO hecho todavía: una restricción CHECK sobre architectural_role y cualquier renombrado de piezas — cada uno es una decisión aparte del operador.
---
El arnés, 2026-09-01 (sprint 4.31)
La recomendación 3 y los puntos 1 a 3 del libro de la regla 14 de arriba ya son código, en tools_corpus::vocabulary_panel (agreement, votes, sample, store).
Los puntos 1 a 3 quedan saldados. scratchpad/s1_extract.py, s1_agreement.py y s1_to_sql.py ya no estaban en el disco para cuando se escribió el reemplazo, así que los doce valores de métrica publicados arriba son la única declaración que sobrevive de lo que calculaban. Son, por tanto, la prueba de aceptación de la implementación en Rust: agreement reproduce las cuatro celdas de s1-2026-08-14 y las dos de s1b-2026-08-14 a tres decimales, a partir de los TSV de votos bajo control de versiones. Los números de las tablas de arriba no cambiaron y no se recalcularon — se reprodujeron.
La recomendación 3, dicha de nuevo por lo que se construyó. La recomendación lee el conteo de 0 abstenciones en 540 como un comportamiento del panel que necesita un campo de confianza obligatorio. El mecanismo construido toma una lectura más fuerte: 0 de 540 no es evidencia de que el panel estuviera seguro, es evidencia de que el instrumento no podía registrar incertidumbre. El formato de voto tenía cuatro columnas — celda / agente / pieza / rol — sin ningún lugar donde decir que los hechos no decidían la pregunta, así que un panelista que se sintiera inseguro tenía exactamente una forma de expresarlo: elegir un rol. La regla vivía en la instrucción; nada en el archivo podía sostenerla.
Así que confidence es una quinta columna obligatoria sin valor por omisión, los votos por debajo del umbral de la corrida los convierte a unclassified el cargador y no la memoria del panelista, y las abstenciones declaradas se cuentan aparte de las forzadas. abstention_rate y coerced_abstention_rate se guardan por celda, y el umbral se guarda junto con la corrida. Las dos corridas publicadas ahora reportan una tasa de abstención, y es 0.000 — el mismo hecho que antes, pero en un campo donde su ausencia habría sido visible.
Recalificado a través de la línea de comandos (corpus vocabulary-panel --score --no-confidence) el 2026-09-01: las ocho celdas de S1 y las dos de S1b devuelven los valores publicados.
Kappa se reporta como Undefined cuando una sola categoría se llevó todos los votos, nunca como 1.0: un panel que se abstiene por completo produce exactamente esa forma, y eso no es acuerdo perfecto.
La ruta de ejecución existe desde ese mismo día: corpus vocabulary-panel --sample saca la muestra y escribe las cargas de los dos brazos; --score lee un archivo de votos devuelto; --score --write --run-id <id> --cell <celda> guarda métricas y clasificaciones. Una muestra sobre este taller saca 30 de 416 piezas.
Una corrección que la revisión atrapó antes de que se guardara nada. El consenso estaba indexado solo por la pieza, mientras su documentación afirmaba alcance por celda. El archivo de votos de S1 abarca cuatro celdas de dos vocabularios, así que calificarlo entero mezclaba votos emitidos bajo el vocabulario retirado con votos emitidos bajo el ratificado y devolvía un solo renglón — que entonces se habría escrito sellado como ddd-hexagonal-v2. Cada fixture de prueba usaba una sola celda, así que nada falló. Ahora el consenso está indexado por (celda, pieza) y el escritor rechaza renglones que abarquen varias celdas en vez de guardar el que caiga al último, ya que la llave de crate_classification no tiene celda. Qué brazo guardar ahora se pregunta (--cell), porque era una decisión que S1 tomaba en silencio al guardar solo el brazo tipado.
---
Corrida H8, 2026-09-01 — qué se le estaba mostrando al panel
Corrieron dos paneles sobre las mismas 30 piezas de S1b, tomadas de sus votos publicados (h8-2026-09-01-sample.txt) para que la muestra no pudiera confundir la comparación. El mismo diseño que S1b: 3 evaluadores sonnet por celda, contexto nuevo, un archivo de carga cada uno, sin acceso al repositorio. Umbral de confianza 0.5. Votos: h8-2026-09-01-votes.tsv (180) y h8-2026-09-01-structural-votes.tsv (90).
| Celda | Carga | Acuerdo total | Modal medio | κ de Fleiss | Abstención |
|---|---|---|---|---|---|
| s1b V2·tipado (2026-08-14) | nombre, ruta, descripción, ≤5 dependencias | 0.900 | 0.967 | 0.914 | no registrable |
| h8 V2·tipado (delgada) | los mismos cuatro hechos | 0.833 | 0.933 | 0.848 | 0.244 |
| h8 V3·estructural | + superficie pública, + dependientes entrantes | 0.900 | 0.967 | 0.921 | 0.100 |
El 0 de 540 era el instrumento, y esto mide cuánto
Dado un campo para ello, el mismo diseño sobre las mismas piezas se abstiene en el 24.4% de los votos del brazo tipado. S1b registró 0.0% sobre esas mismas piezas seis semanas antes. La certeza del panel no había cambiado; el archivo de votos había ganado una columna.
La mayor parte de esa abstención era inanición, no ambigüedad
Añadir qué expone la pieza y quién depende de ella reduce la abstención a la mitad (0.244 → 0.100) y sube el acuerdo a la mejor celda de todo el estudio (κ 0.921, por encima del 0.914 de S1b). Los renglones de consenso que volvían como unclassified bajaron de 8 de 30 a 3 de 30.
Las dos direcciones importan. Más evidencia no solo subió la confianza: subió el acuerdo y dejó un residuo de ambigüedad genuina que ninguna cantidad de descripción habría resuelto. Las abstenciones de la carga delgada eran en su mayoría el panel reportando que le habían mostrado un nombre y preguntado por una estructura.
Ese es el hallazgo que el formato de cuatro columnas no podía producir. Una corrida sin campo de abstención reporta 0.0% tanto si la evidencia era abrumadora como si estaba ausente, y S1 y S1b leyeron ese silencio como acuerdo.
Por qué la carga estructural no es «más acceso»
Los roles de ddd-hexagonal-v2 son afirmaciones estructurales: un aggregate posee invariantes sobre sus hijos, un port es una interfaz que algo implementa, la infrastructure es aquello sobre lo que otros se paran. Los dependientes entrantes y la superficie pública son la evidencia de la que tratan esas afirmaciones; una descripción de una línea no lo es. El panelista sigue leyendo un solo archivo, sigue sin poder alcanzar el código fuente, y la carga sigue sin nombrar ningún archivo fuente — la propiedad anti-alucinación de S1 no cambia.
Un límite del almacén, encontrado al correrlo dos veces
La llave natural de crate_classification es (pieza, versión de vocabulario, provenance_class), así que dos corridas de modelo sobre las mismas piezas chocan: los renglones de la corrida estructural reemplazaron a los de la delgada, y solo provenance registra qué archivo produjo lo que sobrevive. Las métricas están a salvo (run_measurement está indexado por run_id, y las dos corridas están ahí), y los TSV de votos son el registro real — pero la base guarda una clasificación de modelo por pieza, no una historia de ellas. Anotado como límite, no arreglado: añadir una dimensión de corrida a esa llave es una decisión del operador sobre para qué sirve la tabla.
Estado
crate_classification tenía 489 renglones sobre 426 piezas distintas, 381 de ellos unclassified, antes de esta corrida. 30 piezas ahora llevan una clasificación de modelo del brazo estructural, 3 de ellas unclassified porque el panel lo dijo y el instrumento pudo registrarlo.