Skip to content

contract/issue-codes.json registers two codes twice, one with disagreeing severity, and nothing gates key uniqueness #467

Description

@alpCaner

contract/issue-codes.json registers two codes twice, and one pair disagrees on severity:

bootstrap.adopted-venv-unusable   :804  "severity": "warning"
bootstrap.adopted-venv-unusable   :844  "severity": "error"
bootstrap.venv-recreated          :820  (duplicate of :852)

Introduced by a6563d7 / f3208e1. Not a regression of any current work — found while reviewing the tan-cli#464 stage-2 commit.

Why it matters

The registry is a published contract. alp-sdk-vscode hard-asserts every entry's shape, and consumers key off severity to decide whether an issue is advisory or blocking. With a duplicate key, JSON parsing is last-wins, so the effective severity of bootstrap.adopted-venv-unusable is whichever entry happens to be later in the file — today error, silently overriding the warning someone wrote at :804. Reorder the file and the contract changes with no diff to any code.

Nothing catches it

tests/gates/test_every_issue_code_is_registered.py checks that every emitted code is registered and test_issue_code_registry_shape.py checks each entry's shape, but neither asserts key uniqueness — a duplicate key is invisible to both because json.load collapses it before the tests ever see it. All 292 codes match ISSUE_CODE_SHAPE = /^[a-z][a-z0-9-]*\.[a-z0-9-]+$/; the shape is fine, the multiplicity is not.

Fix

  1. Resolve each duplicate to one entry, deciding deliberately which severity is correct for bootstrap.adopted-venv-unusable — the two entries were written for different situations and the answer is not automatically "the later one".
  2. Add a gate that reads the file with a duplicate-key-rejecting hook (e.g. json.load(f, object_pairs_hook=...) raising on a repeated key) so the next duplicate fails loudly instead of silently winning.

The gate is the point. Without it this recurs the moment two changes append entries independently, which is exactly how these two arrived.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions