Skip to content

GT-616 + GT-617: governance spans that can be switched on, and doc inventories derived from the code - #80

Merged
beyondnetPeru merged 1 commit into
developfrom
feat/gt-616-617-telemetry-docs
Jul 31, 2026
Merged

GT-616 + GT-617: governance spans that can be switched on, and doc inventories derived from the code#80
beyondnetPeru merged 1 commit into
developfrom
feat/gt-616-617-telemetry-docs

Conversation

@beyondnetPeru

Copy link
Copy Markdown
Contributor

Closes GT-616 and GT-617 (both P2, Tracker). Both rows came from an external product diagnostic and were registered as not verified against code. Both were verified first — and in each case the diagnostic was directionally right and factually off.


GT-616 — verified, and worse than claimed

The literal claim holds: TrackerTracing.cs:55 returns early on an empty Otlp:Endpoint, and no config source set it. But that default is deliberateT-049 ratified it and ObservabilityConventionTests already guarded it. It was NOT reverted: switching traces on in the default configmap would manufacture the exporter retry storm the ADR rejects.

Underneath it, three defects no ADR defends:

  1. Zero StartActivity anywhere in the repo. TrackerTracing.Source was registered in the pipeline and called by nobody — so even with a collector wired up, the backend would have received ASP.NET and HttpClient plumbing and not one governance fact. This is the actual gap.
  2. The chart had no switchconfigmap.yaml never emitted Otlp__Endpoint, so an operator with a collector could only hand-inject via extraEnv.
  3. .env.example:40 documents OTEL_EXPORTER_OTLP_ENDPOINT and a code comment claimed that variable "finally has a consumer". It did not — ASP.NET binds Otlp__Endpoint, so setting the documented variable turned nothing on.

Added GovernanceTraceTags (tenant / actor / initiative / phase / agent / outcome), StartGovernanceActivity + SetGovernanceOutcome, instrumentation at gate-decide, Core-evaluate and assistant-converse, an otlp: block in the chart (still "" by default), and the env-var fallback.

Negative half — production code reverted, tests kept: 3 failed / 4 passed, including LosPuntosDeGobiernoAbrenUnSpanDeDominio → "Puntos instrumentados hoy: [], but found 0: {empty}". With the fix: 10/10. Three further tests are compile-coupled to the new API and therefore cannot run against pristine code — stated plainly rather than dressed up as evidence.


GT-617 — verified; the diagnostic's own numbers were also wrong

Measured from the code rather than copied from the report: 54 decisions (badge said 30), 8 schemas / 49 tables (doc said 10 / 32), 12 robots (README listed 3). The diagnostic's "real 7 and 45" undercounted — it missed the masterdata EF context (TenantProjectionDbContext), which T-047 declares as an exception with motive. The five non-existent schemas it named are exactly five, and that part was right.

The fix is derivation, not correction. .harness/scripts/doc-inventory.mjs reads EF ModelSnapshot files, | T-NNN | rows, and imports the robot modules — the same discovery run.mjs uses, because a regex picks up a fixture name: inside governance-journey. It writes marked blocks into 5 docs and its --check is wired into Validate documentation. It fails closed: a source yielding zero, or a target missing its markers, exits 2 — deleting the markers cannot turn it green.

Rewriting five blocks was not enough: the false counts had been copied into 12 more live docs, so a second pass lints hand-written figures against the derived truth. Its first version fired 29 times on legitimate things (heading numbers, ADR ids, per-schema table counts) and was narrowed to unambiguous global claims — a noisy guard gets disabled, which ends the same place as one that can only pass. Historical corpora (DECISIONS*, docs/adrs/, docs/audit/) are excluded on purpose: T-028 must remain able to say it declared 10 schemas.

Negative half: the guard exits 1 naming each stale block. Two mutation tests confirm it is not vacuous — appending a T-055 row goes red (reales: 55), adding a table to the EF snapshot goes red (reales: 9). Independently re-run by the integrating session: mutation → exit 1, restored → exit 0.


Incidental find, worth its own attention

RepoRoot() in the source-scanning guards looked for a .git directory. In a git worktree .git is a file, so it walked up to the main checkout and scanned a different branch — a silent false green. It was caught only because a guard stayed red with the fix already on disk. Fixed here. (The same class of bug was fixed in Evolith Core's hooks days ago, which suggests it is worth grepping for elsewhere.)

Build & test

  • dotnet build Tracker.sln -c Release -warnaserror0 warnings, 0 errors
  • dotnet test Tracker.sln -c Release1027/1027 + 14/14, after starting PostgreSQL 16 as CI does (the 2 initial failures were tests correctly refusing to skip without a DB)
  • Observability suite independently re-run by the integrating session: 32/32

Deliberately left out

  • The ~1,300 lines of aspirational DDL in §3–12 of the data-design doc — rewriting them is a separate decision. They are now marked as the 2026-06-07 target design superseded by T-047, with the generated block flagged as the only part describing reality.
  • values-local.yaml traces stay off: no local collector exists, and turning them on is the coupling T-049 rejects.
  • No xunit wrapper shelling out to node for the doc guard — it would add a Node dependency to the .NET suite for no assurance the CI step does not already give.

🤖 Generated with Claude Code

…umentales derivados

GT-616 — VERIFICADO, y peor de lo denunciado.
La ficha decía que `TrackerTracing` retorna temprano con `Otlp:Endpoint` vacío,
que es el valor por defecto. Cierto (`TrackerTracing.cs:55`), pero ese apagado por
defecto lo decidió `T-049` a propósito y NO se revierte: un exportador que no
alcanza a nadie reintenta para siempre y ata la disponibilidad del producto a la
de un sumidero de telemetría. Lo que no defendía ningún ADR son otras tres cosas
que la ficha no vio:

  1. No existía UNA SOLA llamada a `StartActivity` en el repositorio. La fuente
     `Evolith.Tracker` se registraba en el pipeline y no la invocaba nadie, así que
     encender el exportador sólo habría llenado el backend de fontanería de ASP.NET.
  2. El configmap no emitía `Otlp__Endpoint` en absoluto: un operador CON colector
     no tenía forma soportada de encenderlas.
  3. `.env.example:40` declara `OTEL_EXPORTER_OTLP_ENDPOINT` y el comentario del
     código afirmaba que ésa era «la variable que por fin tiene consumidor». No lo
     era: el enlace de ASP.NET traduce `Otlp__Endpoint`. El interruptor documentado
     no encendía nada.

Se añaden `GovernanceTraceTags` (tenant/actor/iniciativa/fase/agente/desenlace),
`StartGovernanceActivity` + `SetGovernanceOutcome`, y se instrumentan los tres
puntos donde se decide gobierno: decidir una compuerta, evaluar contra el Core y
un turno de agente. Sin listener el helper devuelve null y no cuesta nada, así que
los puntos de llamada no se esconden tras un `if`.

De paso, `RepoRoot()` de las guardas de fuente no reconocía un worktree de git
(`.git` es un FICHERO, no un directorio): subía hasta el checkout PRINCIPAL y
escaneaba otra rama. Se detectó al ver una guarda seguir en rojo con el arreglo ya
en disco.

GT-617 — VERIFICADO, con cifras propias (las del diagnóstico también fallaban).
Medido contra el código: 54 decisiones (no 30), 8 schemas y 49 tablas (no 10/33,
y tampoco los 7/45 que el diagnóstico daba por reales — omitía el contexto EF
`masterdata`), 12 robots (no 3). Los cinco schemas inexistentes sí son cinco.

El arreglo NO es corregir los números: se DERIVAN. `.harness/scripts/doc-inventory.mjs`
los saca de los `ModelSnapshot` de EF, de las filas `| T-NNN |` de DECISIONS.md y de
importar `robosoft/robots/*.robot.mjs` con el mismo mecanismo del runner, y los
escribe en bloques marcados de cinco documentos. `--check` falla el build ante deriva
y va cableado a `Validate documentation`.

Reescribir cinco bloques no bastaba: la cifra falsa se había copiado a doce sitios
más (índices de área, C4, hoja de ruta, spec de CI/CD). Una segunda pasada rastrea
cifras a mano en el corpus vivo y las contrasta con lo derivado; se corrigieron las
doce. El corpus histórico (DECISIONS, ADRs, docs/audit) queda fuera a propósito:
`T-028` DEBE poder decir que declaraba 10 schemas.

Verificación (salida real):
  - GT-616 rojo con el código pristino: 3 pruebas en rojo, `Puntos instrumentados
    hoy: [], but found 0: {empty}`. Verde con el arreglo: 10/10.
  - GT-617 rojo antes de generar: los 5 bloques en deriva, exit 1. Verde tras
    `--write`, exit 0. Dos pruebas de mutación (una decisión nueva en DECISIONS.md,
    una tabla nueva en el snapshot de EF) vuelven a ponerlo rojo.
  - `dotnet build -c Release -warnaserror`: 0 avisos, 0 errores.
  - `dotnet test Tracker.sln -c Release` contra PostgreSQL 16: 1027/1027 + 14/14.
  - Validadores de documentación de CI, incluida la paridad bilingüe: en verde.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru
beyondnetPeru merged commit 8871005 into develop Jul 31, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant