Skip to content

fix(infra): GT-622 delete the 210 orphaned CodeQL analyses; GT-656 make a wrong gap title correctable - #440

Merged
beyondnetPeru merged 5 commits into
developfrom
gt-622-orphaned-codeql-configuration
Aug 8, 2026
Merged

fix(infra): GT-622 delete the 210 orphaned CodeQL analyses; GT-656 make a wrong gap title correctable#440
beyondnetPeru merged 5 commits into
developfrom
gt-622-orphaned-codeql-configuration

Conversation

@beyondnetPeru

Copy link
Copy Markdown
Contributor

Advances GT-622.

What landed

The irreversible half the board had deliberately deferred is executed: the 210 code-scanning analyses under the dead key .github/workflows/ci.yml:codeql are deleted from refs/heads/main (201) and refs/heads/develop (9). Each DELETE was preceded by a GET asserting analysis_key and results_count == 0 against a pre-built id allowlist, so no ordering mistake could reach a live-key analysis. 210 deleted, 0 refused, 0 errors.

Measuring first refuted three of the row's own claims

The row had already been re-measured twice without any of these surfacing, because every pass checked the COUNT and none checked the CLAIM.

  1. It was not red. The check-run conclusion was neutralgh pr checks renders it skipping — from PR docs(gaps): close GT-601 on verification — a sweep of the 20 in-progress rows #250 onward; only PR Develop #217 was ever failure. The row's central argument (a permanently RED check trains reviewers to discount red) described a state that ended eleven days after it was written.
  2. The branch was wrong. The warning's own summary names refs/heads/develop, not main. PRs into main came back clean from chore(sync): develop → main — .dockerignore + entrypoint assertions #420 onward with all 201 orphans still in place — four minutes apart from feat(core): GT-654 one /health shape, GT-655 three orphan operations bound #433 still warning on develop. main stopped warning without any deletion, which refutes the row's causal model and means the cleanup was never the only thing that could have resolved it.
  3. The 9 analyses on develop were never counted. The real total was 210, not 201 — and the 9 outside the row's scope were the ones producing the symptom.

What made the owner decision cheap had never been read: all 210 carry results_count: 0. They are 210 records of "scanned, found nothing" from a configuration dead since June. The irreversibility was real; the loss was not.

Verification

Before After
Alerts (open / dismissed / fixed) 242 / 82 / 60 242 / 82 / 60
Open by tool CodeQL 75 · Scorecard 158 · Trivy 9 CodeQL 75 · Scorecard 158 · Trivy 9
Dead key on main / develop 201 / 9 0 / 0
CodeQL SAST REQUIRED, green REQUIRED, green

22 analyses under the dead key are deliberately left on refs/pull/{4..17}/merge — ephemeral per-PR refs from May that can never be the base of a PR, so they produce no symptom.

Guards run locally, all exit 0: 04-check-bilingual-parity, 08-validate-tracking, 40-validate-path-literals, 47-validate-joined-paths, 49-validate-gap-id-allocation, bilingual-terminology-lint.

Why the row is still PENDING

Criterion 1 — "gh pr checks on a fresh PR into develop shows no CodeQL check reporting configuration not found" — can only be observed on a PR into develop. This is that PR. The closure lands in a follow-up commit once the check actually reports, not on the assumption that it will.

Not a retitle

The catalog title still says "Eighty-two" and is knowingly left wrong: 49-validate-gap-id-allocation reads any title change against the base as a possible id collision and has no escape hatch for a deliberate retitle, so correcting it turns a required check red. The 2026-08-01 re-measure set that precedent (82 → 201 in the evidence, title untouched). A guard that makes titles immutable guarantees every re-measured row keeps its now-wrong headline forever — worth its own row.

🤖 Generated with Claude Code

…ct three claims the row got wrong

The irreversible half the board had deliberately deferred is executed: the
210 code-scanning analyses under the dead key `.github/workflows/ci.yml:codeql`
are deleted from `refs/heads/main` (201) and `refs/heads/develop` (9), each
DELETE preceded by a GET asserting `analysis_key` and `results_count == 0`
against a pre-built id allowlist. 210 deleted, 0 refused, 0 errors.

Measuring before deleting refuted three of the row's own claims, and the row
had already been re-measured twice without any of them surfacing, because
every pass checked the COUNT and none checked the CLAIM:

1. It was not red. The check-run conclusion was `neutral` (`gh pr checks`
   renders it `skipping`) from PR #250 onward; only PR #217 was `failure`.
   The row's central argument — a permanently RED check trains reviewers to
   discount red — described a state that ended eleven days after it was written.
2. The branch was wrong. The warning names `refs/heads/develop`, not `main`.
   PRs into `main` came back clean from #420 with all 201 orphans still in
   place, four minutes apart from #433 still warning on `develop`. `main`
   stopped warning without any deletion, which refutes the row's causal model.
3. The 9 analyses on `develop` were never counted. The real total was 210.

What made the owner decision cheap had never been read: all 210 carry
`results_count: 0`. The irreversibility was real; the loss was not.

Verified unchanged across the deletion: 242 open / 82 dismissed / 60 fixed
alerts, open-by-tool CodeQL 75 / Scorecard 158 / Trivy 9. `CodeQL SAST` is
still REQUIRED on both branches and green. 22 analyses under the dead key are
deliberately left on `refs/pull/{4..17}/merge` — ephemeral per-PR refs that can
never be the base of a PR.

The row stays PENDING on purpose. Its first criterion can only be observed on
a PR into `develop`, which is what this PR is; the closure lands in a follow-up
commit once the check reports, not on the assumption that it will.

Criterion 2 was restated: it demanded the only keys on `main` be the two from
`sdk-cli-ci.yml`, but a third legitimate key has since appeared
(`openssf-scorecard.yml:analysis`), so the test is the ABSENCE of the dead key.

NOT a retitle: the catalog title still says "Eighty-two" and is knowingly left
wrong, because `49-validate-gap-id-allocation` reads any title change as a
possible id collision and has no escape hatch. The 2026-08-01 re-measure set
that precedent (82 -> 201 in the evidence, title untouched). Worth its own row.

Guards run locally: 04 bilingual parity, 08 tracking, 40 path literals,
47 joined paths, 49 gap-id allocation, bilingual-terminology-lint — all exit 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru
beyondnetPeru requested a review from a team as a code owner August 8, 2026 14:11
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

📊 Bilingual Coverage Impact

PR Changes

  • Paired EN/ES files modified: 3
  • New EN files needing ES translation: 0

Repository Coverage

Metric Value
Total EN files 527
Total ES files 501
Paired files 0
Coverage 0%

Good: All EN changes have ES counterparts.


Generated by GitHub Actions

beyondnetPeru and others added 3 commits August 8, 2026 09:16
…at carries it

Criterion 1 of GT-622 could only be satisfied by a pull request into `develop`,
the one base that still carried the missing-configuration warning. PR #440 is
that pull request, and the check reported 105s after it opened:

  gh pr checks 440 -> CodeQL  pass
  check-run output title -> "No new alerts in code changed by this pull request"

The five PRs into `develop` on 2026-08-04 (#425, #427, #429, #431, #433) all
returned `neutral` / "1 configuration not found" against the same base. The
closure was written after reading the check, not on the assumption it would
turn out that way.

GT-622 -> DONE. Board counters recomputed from the rows: 640 / 653 done,
3 in progress, 3 pending, 7 deferred. Closure evidence record added, with the
22 analyses left on refs/pull/{4..17}/merge recorded as an explicit
accepted-scope exemption rather than a silent one.

Also corrected while measuring, and NOT part of this gap: GT-653 still carried
"Remaining: promotion to required context on main/develop". That promotion has
happened — `Secret Detection (gitleaks)` is a required context on both branches
and the required set went 7 -> 8, read back from branch protection. The row was
describing as pending something already done.

Guards run locally: 04 bilingual parity, 08 tracking, 40 path literals,
41 evidence commands (--strict --max-dead 17, 0 dead over 1223 commands in 622
closures), 47 joined paths, 49 gap-id allocation, bilingual-terminology-lint —
all exit 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…it is pinned to

`09-reconcile-maturity --check` requires `maturity-evidence.json`'s `asOf` to
equal the board's `Last Updated`, and rotating that header to 2026-08-08 broke
the equality — a real coupling this change introduced, caught by the required
`Validate documentation` job rather than by me.

`asOf` is the reconciliation date, not a claim that the readiness checks were
re-observed: each check keeps its own `observedAt` (2026-07-20) untouched.

Regenerated artifact carries only the counters that actually moved:
asOf 2026-07-26 -> 2026-08-08, done 639 -> 640, pending 4 -> 3,
closureRecords 621 -> 622. No other drift.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…the collision check

Closes GT-656.

`49-validate-gap-id-allocation` discriminates an id collision from an ordinary
edit by comparing the catalog `**Title:**` against the base branch, and failed
on any difference. Right for a collision, wrong for a retitle — and the guard
could not tell them apart. Its own message admitted this and asked for the
distinction "in the commit", which nothing reads and a squash merge rewrites.
The practical effect was that gap titles were IMMUTABLE.

The cost was already paid, not hypothetical. GT-622 was re-measured twice —
82 -> 201 -> 210 orphaned analyses, and the branch still carrying the warning
turned out to be `develop`, not `main` — while its headline went on reading
"Eighty-two ... every PR", because correcting it turns a REQUIRED check red on
the PR carrying the correction. The 2026-08-01 re-measure set that precedent
silently; this change found it about to be followed a third time. A board whose
purpose is that debt is not described inaccurately was accumulating rows whose
first line was inaccurate.

Fixed by turning the deferred human judgement into DATA, not by softening the
check. A retitle is declared in reference/core/control-center/gaps/gap-retitles.json
as { id, from, to, declaredAt, reason }, and exempts only when BOTH titles match
the two branches exactly. That exactness is the design: it cannot be written as a
blanket "this id may be retitled", so a real collision later landing on the same
number still fails, because its titles are not the declared pair.

The registry is itself guarded, because an exemption list that rots silently is
worse than the defect it fixes:
  active -> exempts its collision
  spent  -> the retitle reached the base; reported, not fatal
  rot    -> describes neither side; FAILS
and a registry that exists but cannot be parsed, or has no `retitles` array, is
a hard failure rather than an empty list. Every active exemption is printed with
its reason — an exemption nobody can see is indistinguishable from a hole.

First use in the same change: GT-622's title is corrected, 82 -> 210 and
"every PR" -> "PRs into `develop`", in both languages. Guard green against
`origin/main` and `origin/develop` with the retitle applied.

Also corrected: GT-622's evidence claimed the title was "knowingly left wrong".
That is no longer true, and leaving it would have been the same class of stale
claim this row is about.

Verified: node --test 49-validate-gap-id-allocation.test.mjs 27/27, including
the negative twins — the same retitle WITHOUT a declaration is still red, a
declaration quoting a title the catalog never carried does not launder it, an
unparseable registry stops the run, and a real collision on an already-retitled
id still fails. Guards 04, 08, 09 --check, 40, 41 (--strict --max-dead 17, 0
dead over 1226 commands), 42, 43, 47, 49 and bilingual-terminology-lint all
exit 0.

Board: 641 / 654 done, 3 in progress, 3 pending, 7 deferred.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru beyondnetPeru changed the title fix(infra): GT-622 delete the 210 orphaned CodeQL analyses, and correct three claims the row got wrong fix(infra): GT-622 delete the 210 orphaned CodeQL analyses; GT-656 make a wrong gap title correctable Aug 8, 2026
@beyondnetPeru

Copy link
Copy Markdown
Contributor Author

Follow-up: GT-656 — the retitle this PR could not make

Closing GT-622 hit a second defect and it is now fixed in this same PR.

49-validate-gap-id-allocation tells an id collision from an ordinary edit by comparing the catalog **Title:** against the base branch, and failed on any difference. Correct for a collision, wrong for a retitle — and it could not tell them apart. Its own failure text admitted this and asked for the distinction "in the commit", which nothing reads and a squash merge rewrites. Gap titles were therefore immutable.

That cost was already paid. GT-622 was re-measured twice — 82 → 201 → 210 analyses, and the branch still carrying the warning turned out to be develop, not main — while its headline went on reading "Eighty-two ... every PR", because correcting it turns a required check red on the PR carrying the correction. The 2026-08-01 re-measure set that precedent silently; this was about to follow it a third time.

The fix is data, not a softer check

A retitle is declared in reference/core/control-center/gaps/gap-retitles.json as { id, from, to, declaredAt, reason } and exempts only when both titles match the two branches exactly. That exactness is the point: it cannot be written as a blanket "this id may be retitled", so a genuine collision later landing on the same number still fails — its titles are not the declared pair.

The registry is itself guarded, because an exemption list that rots silently is worse than the defect it fixes:

state meaning verdict
active reproduces a live collision exempts it, printed with its reason
spent the retitle reached the base branch reported, not fatal
rot describes neither side fails

An unparseable registry, or one with no retitles array, is a hard failure rather than an empty list.

Verification

node --test 27/27, including the negative twins that keep the hatch from being abused: the same retitle without a declaration is still red; a declaration quoting a title the catalog never carried does not launder it; a real collision on an already-retitled id still fails; an unreadable registry stops the run.

Guard green against both origin/main and origin/develop with the retitle applied — GT-622's title is now "Two hundred and ten … PRs into develop", in both languages, and its evidence no longer claims the title was "knowingly left wrong".

One thing this PR does not fix

Security Audit is red here and it is not from this change: the PR touches doc and JSON files only, zero dependency files, and the dependabot PRs of 2026-08-05 were green. A js-yaml advisory (GHSA-5p4m-2wfm-xmqj / CVE-2026-59870) was published between then and 2026-08-08 and now hits every branch including main. It is not a required context. It needs its own row.

🤖 Generated with Claude Code

Both were found by the runner, not by me, and both are real.

1. GT-656's recorded validationCommands were EXECUTED and failed.
   `41-validate-evidence-commands --execute` runs what the closure registry
   records, and two of GT-656's entries passed `--base origin/main` /
   `--base origin/develop`. A remote ref is not resolvable in the runner
   checkout, so the guard refused to compare — which is its correct behaviour
   ("unable to answer is not the same as nothing to report"), reported as a red
   Governance guards job. The registry now records only self-contained proof:
   `node --test` over the 27 fixtures (the negative twins included) and the
   negative-fixture guard. The two branch comparisons stay in the catalog
   section as prose, where an unrunnable command belongs.

2. The executive summary was left stale by the maturity reconciliation.
   `46-validate-derived-artifact-order` stops at the FIRST stale link on
   purpose: maturity-reconciliation.json feeds the executive summary, and
   regenerating the upstream without the downstream breaks the chain.
   Regenerated; the chain is current and at a fixed point — replaying all 8
   links changes nothing.

Verified: `41-validate-evidence-commands --execute --strict --max-dead 17`
now reports 113 executed / 112 exit 0, with the single remaining non-zero being
GT-78's root-cleanliness guard objecting to an untracked local `.DS_Store` that
does not exist on the runner. `46-validate-derived-artifact-order --verbose`
exit 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru
beyondnetPeru merged commit 1fc9ea5 into develop Aug 8, 2026
31 of 32 checks passed
@beyondnetPeru
beyondnetPeru deleted the gt-622-orphaned-codeql-configuration branch August 8, 2026 14:45
beyondnetPeru added a commit that referenced this pull request Aug 8, 2026
…ix, and name the half that has none (#441)

GHSA-5p4m-2wfm-xmqj / CVE-2026-59870 turned `Security Audit` red on every
branch. Attribution measured first: the dependabot PRs of 2026-08-05 were green,
PR #440 of the 8th was red, and it changed 8 doc/JSON files with zero dependency
files — pre-existing branch debt, not a regression.

The half that had a fix: the root override already carried `js-yaml: 4.3.0`,
added for an EARLIER advisory, and the new one is vulnerable through 4.3.0
inclusive — one patch short. Bumped to 4.3.1; three nested copies collapsed into
the hoisted one.

The half that has none: the remainder arrives through @nestjs/swagger, which
pins js-yaml exactly, and all three published releases pin a vulnerable version
(11.4.4 -> 4.1.1, 11.4.5 -> 4.3.0, 11.4.6 -> 5.2.1). npm overrides do not reach
a nested exact pin — measured four ways, same tree every time. That experiment
also REFUTES the generalisation GT-636 recorded; corrected in the catalog.

`63-validate-npm-audit-gate` keeps the same HIGH threshold and requires that an
advisory with no upstream fix be NAMED, with the path it arrives by. It fails on
an undeclared advisory, on a declaration for a different id or path, and on a
declaration whose advisory has DISAPPEARED — so the good news arrives as a red
check asking for the entry's removal. Its own fixtures run in the job.

Recorded for the next reader: `Trivy` flags this as a new high alert because the
advisory id at that lockfile position changed. Reverting the swagger bump makes
it worse — 11.4.4's js-yaml 4.1.1 carries three advisories (two HIGH) against
11.4.6's one. The revert was attempted during this work and had to be undone,
so the measurement lives in the exceptions entry and in GT-657.

node --test 19/19; core-api 160/160; core-domain 1704/1704; 13 guards exit 0.
Board: 642 / 655 done, 3 in progress, 3 pending, 7 deferred.
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