Skip to content

feat(ci): one gap id, one gap — the allocator guard, closing GT-638 - #300

Merged
beyondnetPeru merged 1 commit into
mainfrom
feat/gt-638-id-allocator-guard
Jul 30, 2026
Merged

feat(ci): one gap id, one gap — the allocator guard, closing GT-638#300
beyondnetPeru merged 1 commit into
mainfrom
feat/gt-638-id-allocator-guard

Conversation

@beyondnetPeru

Copy link
Copy Markdown
Contributor

A gap id is chosen by reading the highest GT-* on whichever branch you are on, and nothing contrasts that with any other branch. 8449af3d had to renumber GT-634 → GT-637 for exactly this. 08-validate-tracking cannot help: it validates within one working tree by construction, and branches are outside its world.

49-validate-gap-id-allocation compares every id's **Title:** on HEAD against the title the same id carries on the base branch:

on base verdict
absent newly allocated — fine
present, same title the same gap, edited — fine
present, different title one number, two gaps

The title is the discriminator on purpose. "The id exists on base" is the normal case for 515 rows and says nothing; what makes it a defect is the id naming a different gap on each side.

It found a second collision on its first real run

Against origin/develop it reports GT-633:

  • on develop: "evolith init scaffolds a repository that cannot pass its own governance on the first run"c8270e48, 2026-07-29
  • on main: the tautological-guard row — c3221276, 2026-07-30

Two gaps, one number, and the merge had not surfaced it. By the guard's own advice the newer row is the one to renumber — which is mine. That renumber is deliberately not bundled here; it touches the board row, the catalog anchor, the closure record and cross-references in both languages, and it is a decision, not a side effect of shipping a guard.

It refuses to guess which side is wrong: a retitle and a collision are indistinguishable from outside, so it names both titles and both refs and says so in the failure.

Wiring

Into Governance guards (GT-578), with an explicit git fetch of the base — a shallow CI checkout does not have it, and a guard that failed for that reason would teach people to ignore it.

Anti-vacuous

A missing catalog, an unreadable base ref, and a parse yielding zero ids on either side are all hard failures. "Unable to answer" is not "nothing to report" — a quiet skip is how the original collision reached main.

What it still cannot see

An id allocated on a branch with no open PR. It compares HEAD against one base, so two feature branches that both take GT-640 stay invisible to each other until the first merges. The --verbose output warns on every newly allocated id rather than implying coverage it does not have; closing that remainder needs the open-PR claim set tracked in GT-639.

Verified

  • 13/13 fixtures over real git repositories — not a mock of git show
  • 43-validate-guard-negative-fixtures38/38 observed red, up from 37 · 42 → 61 guards classified
  • 08-validate-tracking (637 gaps, 579 closure records) · 41 at 38 dead against a budget of 40 · 01-validate-docs (1491 files) · 04 bilingual parity · 46 chain at a fixed point
  • counters 596/637 → 597/637

Evolith Core Quality Gates

  • Bilingual Parity: row and catalog entry updated in EN and ES.
  • Validation Scripts: 01-validate-docs.mjs green.
  • Bilingual Validation: 04-check-bilingual-parity.mjs green.
  • Agnosticism: no new dependency; git only.

Linked ADRs / Issues

  • Link to Issue: GT-638 (closed here); the remainder is GT-639

Conventional Commits

  • Commit follows Conventional Commits.

🤖 Generated with Claude Code

A gap id is chosen by reading the highest `GT-*` on whichever branch you are on,
and nothing contrasts that with any other branch. `8449af3d` had to renumber
GT-634 -> GT-637 for exactly this. `08-validate-tracking` cannot help: it
validates within ONE working tree by construction, and branches are outside its
world. This guard is the part that needs two.

`49-validate-gap-id-allocation` compares every id's **Title:** on HEAD against the
title the same id carries on the base branch:

  absent from base        -> newly allocated, fine
  present, same title     -> the same gap, edited; fine
  present, DIFFERENT title -> one number, two gaps

THE TITLE IS THE DISCRIMINATOR ON PURPOSE. "The id exists on base" is the normal
case for 515 rows and says nothing; what makes it a defect is the id naming a
different gap on each side.

IT FOUND A SECOND COLLISION ON ITS FIRST REAL RUN, which nobody knew about.
Against origin/develop it reports GT-633: there it is "`evolith init` scaffolds a
repository that cannot pass its own governance on the first run" (c8270e4,
2026-07-29); on main it is the tautological-guard row (c322127, 2026-07-30). Two
gaps, one number, and the merge had not surfaced it. By the guard's own advice the
NEWER row is the one to renumber — which is mine.

It refuses to guess which side is wrong. A retitle and a collision are
indistinguishable from outside, so it names both titles and both refs and says in
the failure that it should not guess.

Wired into `Governance guards (GT-578)` with an explicit `git fetch` of the base:
a shallow CI checkout does not have it, and a guard that failed for THAT reason
would teach people to ignore it.

Anti-vacuous: a missing catalog, an unreadable base ref, and a parse yielding zero
ids on either side are all hard failures. "Unable to answer" is not "nothing to
report" — a quiet skip is how the original collision reached main.

WHAT IT STILL CANNOT SEE, said out loud rather than implied: an id allocated on a
branch with no open PR. It compares HEAD against ONE base, so two feature branches
that both take GT-640 stay invisible to each other until the first merges. The
`--verbose` output warns on every newly allocated id, and closing that remainder
needs the open-PR claim set tracked in GT-639.

Verified: 13/13 fixtures over real git repositories (not a mock of `git show`);
43-validate-guard-negative-fixtures 38/38 observed red, up from 37;
42-validate-guard-denominators 61 guards classified; 08-validate-tracking (637
gaps, 579 closure records), 41 at 38 dead against a budget of 40, 01-validate-docs
(1491 files), 04 bilingual parity, 46 chain at a fixed point. Counters 596/637 ->
597/637.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru
beyondnetPeru requested a review from a team as a code owner July 30, 2026 15:33
@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

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 524
Total ES files 498
Paired files 0
Coverage 0%

Good: All EN changes have ES counterparts.


Generated by GitHub Actions

@beyondnetPeru
beyondnetPeru merged commit a34548a into main Jul 30, 2026
33 of 35 checks passed
@beyondnetPeru
beyondnetPeru deleted the feat/gt-638-id-allocator-guard branch July 30, 2026 19:54
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