Qué pasó
Durante una cadena de charters en un proyecto adoptante (ri-ceiba, CLI 3.48.0), un script de edición mío borró por accidente el encabezado ## Archivos a modificar de un Charter in-progress, dejando la tabla huérfana en el cuerpo.
straymark charter drift lo detectó correctamente y avisó:
WARN: no files extracted from §Files to modify in .straymark/charters/33-....md
Either the section is missing, the table format is unusual, or the
declared paths don't have recognized extensions. Script can't help — exit clean.
Y salió con código 0.
$ straymark charter drift CHARTER-33 --range main...HEAD >/dev/null 2>&1
$ echo $?
0
El parser no tiene ningún fallo. Leí core/src/charter_files.rs::parse_files_to_modify y hace exactamente lo correcto: el encabezado no estaba, así que no había nada que extraer. El problema es qué ocurre después.
Por qué importa
El Charter estuvo así diez commits, y no lo noté. .githooks/pre-push invoca straymark-pre-pr.sh, que corre el drift check sobre los Charters in-progress; como sale con 0, el hook pasó en verde en cada push.
O sea: el mecanismo que existe para detectar que lo ejecutado se apartó de lo declarado estuvo apagado durante todo un Charter, y su forma de decírmelo fue idéntica a la de decirme que todo iba bien — un mensaje en stderr que se pierde entre la salida de un hook que también compila y corre 3 900 tests.
Lo descubrí por casualidad, al preparar el PR y ver que el conteo de «Declared» no aparecía.
La asimetría
El comando ya distingue dos situaciones y las trata igual:
| Situación |
Significado |
Hoy |
declared.is_empty() |
No pude comprobar |
WARN, exit 0 |
modified.is_empty() |
El Charter no se ejecutó |
WARN, exit 0 |
| Deriva detectada |
Comprobé y hay problema |
Reporte, exit ≠ 0 |
«No pude comprobar» se comporta como «comprobé y está bien». Para una herramienta cuyo propósito es que los artefactos de gobernanza no deriven en silencio, es justo el modo de fallo que busca prevenir — el mismo argumento del #419, aplicado al comprobador en vez de al artefacto.
Lo que sugeriría
No tengo preferencia fuerte entre estas, y quizá haya mejores:
- Salir ≠ 0 cuando la sección falta y el Charter está
in-progress. Es cuando el drift check debería estar vigilando de verdad. Un Charter declared sin sección es legítimo (aún no hay reconocimiento hecho); uno in-progress sin ella es una sección perdida.
- Una bandera
--strict que convierta los WARN en error, para que los hooks puedan optar. Menos intrusivo, pero deja el valor por omisión inseguro y los adoptantes que más lo necesitan son los que no saben que existe.
- Distinguir los dos casos en el mensaje: «la sección no existe» (probablemente un error) frente a «existe y no extraje rutas» (probablemente formato). Ayuda al diagnóstico aunque el código de salida no cambie.
La (1) me parece la que más se acerca al espíritu del framework, pero rompería builds de adoptantes con Charters mal formados — que es exactamente lo que se quiere, aunque conviene decidirlo a conciencia.
Nota sobre el diagnóstico
Mi primera hipótesis fue que el parser se detenía ante texto suelto entre el encabezado y la tabla, y estuve a punto de reportarlo así. Leer parse_files_to_modify la descartó: recorre hasta el siguiente ## sin detenerse en párrafos. Lo menciono porque el mensaje actual lista tres causas posibles y la primera —«the section is missing»— era la correcta; con un código de salida distinto la habría mirado antes en vez de asumir la del formato.
Reportado desde ri-ceiba (CLI 3.48.0, fw 4.33). Con gusto pruebo un parche contra este repositorio, que tiene la cadena CHARTER-32→36 en curso.
Qué pasó
Durante una cadena de charters en un proyecto adoptante (ri-ceiba, CLI 3.48.0), un script de edición mío borró por accidente el encabezado
## Archivos a modificarde un Charterin-progress, dejando la tabla huérfana en el cuerpo.straymark charter driftlo detectó correctamente y avisó:Y salió con código 0.
El parser no tiene ningún fallo. Leí
core/src/charter_files.rs::parse_files_to_modifyy hace exactamente lo correcto: el encabezado no estaba, así que no había nada que extraer. El problema es qué ocurre después.Por qué importa
El Charter estuvo así diez commits, y no lo noté.
.githooks/pre-pushinvocastraymark-pre-pr.sh, que corre el drift check sobre los Chartersin-progress; como sale con 0, el hook pasó en verde en cada push.O sea: el mecanismo que existe para detectar que lo ejecutado se apartó de lo declarado estuvo apagado durante todo un Charter, y su forma de decírmelo fue idéntica a la de decirme que todo iba bien — un mensaje en stderr que se pierde entre la salida de un hook que también compila y corre 3 900 tests.
Lo descubrí por casualidad, al preparar el PR y ver que el conteo de «Declared» no aparecía.
La asimetría
El comando ya distingue dos situaciones y las trata igual:
declared.is_empty()modified.is_empty()«No pude comprobar» se comporta como «comprobé y está bien». Para una herramienta cuyo propósito es que los artefactos de gobernanza no deriven en silencio, es justo el modo de fallo que busca prevenir — el mismo argumento del #419, aplicado al comprobador en vez de al artefacto.
Lo que sugeriría
No tengo preferencia fuerte entre estas, y quizá haya mejores:
in-progress. Es cuando el drift check debería estar vigilando de verdad. Un Charterdeclaredsin sección es legítimo (aún no hay reconocimiento hecho); unoin-progresssin ella es una sección perdida.--strictque convierta los WARN en error, para que los hooks puedan optar. Menos intrusivo, pero deja el valor por omisión inseguro y los adoptantes que más lo necesitan son los que no saben que existe.La (1) me parece la que más se acerca al espíritu del framework, pero rompería builds de adoptantes con Charters mal formados — que es exactamente lo que se quiere, aunque conviene decidirlo a conciencia.
Nota sobre el diagnóstico
Mi primera hipótesis fue que el parser se detenía ante texto suelto entre el encabezado y la tabla, y estuve a punto de reportarlo así. Leer
parse_files_to_modifyla descartó: recorre hasta el siguiente##sin detenerse en párrafos. Lo menciono porque el mensaje actual lista tres causas posibles y la primera —«the section is missing»— era la correcta; con un código de salida distinto la habría mirado antes en vez de asumir la del formato.Reportado desde ri-ceiba (CLI 3.48.0, fw 4.33). Con gusto pruebo un parche contra este repositorio, que tiene la cadena CHARTER-32→36 en curso.