Skip to content

Validate immutable portable tool records - #91

Merged
omry merged 1 commit into
pr90from
pr91
Aug 24, 2026
Merged

Validate immutable portable tool records#91
omry merged 1 commit into
pr90from
pr91

Conversation

@omry

@omry omry commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Add record-local validation for every v1 record family: tool version policy and aliases, release manifests and contracts, target identities and records, binding contracts and artifacts, payloads, artifact sources, native package sets, integration fixtures, and validation profiles. Version policy follows each record's declared scheme, artifacts require exact size and digest, and every diagnostic has focused negative coverage.

Validate dimension-keyed selection combinations against declared dimensions, permit omitted optional dimensions, reject undeclared keys and values, and require canonical encoded-byte ordering.

Wire record-local validation into record decoding, which PTD-03 deliberately left unhooked.

Scope authority

Task: PTD-04 — Validate Immutable Portable Tool Records, defined in docs/PORTABLE_TOOL_DEFINITION_IMPLEMENTATION_PLAN.md, under the normative Portable Tool Definition Design.

Acceptance criteria:

  • each kind validates without graph traversal;
  • version policy uses the declared scheme;
  • artifacts require exact size and digest;
  • diagnostics have focused negative tests;
  • go.mod promotes the shared version dependency and stays stable under go mod tidy.

Included from the retired PR 85

The release-alias correction moves here as the plan directs: release aliases must be a bounded array of canonical, unique, sorted values, each different from the exact version.

Exclusions: target coverage, reachability, source-mapping completeness, and resolution. Sources: parked extraction sources b39985d247e5 and 37ca781bd6cb (alias correction).

@omry
omry changed the base branch from main to pr90 August 17, 2026 16:28
@omry
omry force-pushed the pr91 branch 5 times, most recently from 637c09a to ae01823 Compare August 17, 2026 21:33
@omry
omry force-pushed the pr91 branch 2 times, most recently from 50be9b8 to ab7be22 Compare August 18, 2026 05:35
@omry
omry force-pushed the pr91 branch 3 times, most recently from 4317e9c to 14aead6 Compare August 18, 2026 06:01
@omry
omry force-pushed the pr91 branch 2 times, most recently from 22bef58 to a06b11a Compare August 18, 2026 06:12
@omry
omry force-pushed the pr91 branch 2 times, most recently from c7b6caf to fb90459 Compare August 18, 2026 11:42
Comment thread internal/toolcatalog/records_validate.go Outdated
@omry omry removed the approved PR reviewed and approved label Aug 22, 2026
@omry

omry commented Aug 22, 2026

Copy link
Copy Markdown
Owner Author

@codex review 8e05bb3

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 8e05bb39d7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@omry

omry commented Aug 22, 2026

Copy link
Copy Markdown
Owner Author

@codex review cf3ad38

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf3ad38297

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/toolcatalog/records_validate.go
@omry

omry commented Aug 22, 2026

Copy link
Copy Markdown
Owner Author
Exact head: cf3ad38
Exact parent: 7593096 (PR 90)
Exact-head reviews: Gitar 4999401842; Codex 4999417849. Gitar confirmed the dead-helper fix. Codex P1 3835450493 was classified non-reproducible because Go logical OR short-circuits before segments[:3] whenever the exact segment count differs; thread resolved with evidence.
Checks: Linux CI, six platform smoke jobs, and Gitar all completed successfully.
Local validation: internal/toolcatalog tests with 85.9% statement coverage; go vet ./...; go test -timeout 2m ./...; formatting check all pass.
Native stack 104 exact order: 81, 82, 88, 89, 90, 91.
Descendant PR heads 93, 94, 95, 96, 97, 99, and 100 remain untouched.
All 15 review threads resolved. Historical AWD state comment 5329685639 preserved unchanged.

@omry omry added the approved PR reviewed and approved label Aug 22, 2026
@omry

omry commented Aug 23, 2026

Copy link
Copy Markdown
Owner Author

PR-cycle state — maintained automatically. Do not edit by hand.

{
  "approval": {
    "approval_evidence_fingerprint": "sha256:8d37de723b66473ba0b7e8cf80c3c99ee5123257264933a52e5ad612593946c9",
    "evidence": {
      "checks": [
        {
          "conclusion": "success",
          "name": "Gitar"
        },
        {
          "conclusion": "success",
          "name": "Linux CI checks"
        },
        {
          "conclusion": "success",
          "name": "Target smoke (darwin-amd64)"
        },
        {
          "conclusion": "success",
          "name": "Target smoke (darwin-arm64)"
        },
        {
          "conclusion": "success",
          "name": "Target smoke (linux-amd64)"
        },
        {
          "conclusion": "success",
          "name": "Target smoke (linux-arm64)"
        },
        {
          "conclusion": "success",
          "name": "Windows host smoke (windows-amd64)"
        },
        {
          "conclusion": "success",
          "name": "Windows host smoke (windows-arm64)"
        }
      ],
      "delivery_deferrals_digest": "sha256:fff9756b6c0fd1a0650c744291fce54a4b895c0aeb6e40688dfbfe8b2ade05ff",
      "review": {
        "dispositions": [
          {
            "classification": "verified-non-actionable",
            "source_comment_id": 3839136293,
            "source_thread_id": "PRRT_kwDOTFQCkM6bg6rA",
            "status": "non-actionable"
          }
        ],
        "request": {
          "body_digest": "sha256:74e881e224853d5d76beac92d4b999b113114813a661806849443dc946b5009f",
          "id": 5387487100
        },
        "result": {
          "body_digest": "sha256:b0e7ab0dbb1e732f9e3ae27288e39a91515f5ef408fdf12b969e40929ac6c42c",
          "commit_id": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
          "id": 5387505536
        }
      }
    },
    "head_sha": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
    "revision_fingerprint": "sha256:44aa83dc55fbbdc3133709b5eb0bfbd713d9f5a4ae026aab0a95bdc7a7595b66"
  },
  "candidate": {
    "approval_evidence_fingerprint": "sha256:8d37de723b66473ba0b7e8cf80c3c99ee5123257264933a52e5ad612593946c9",
    "head_sha": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
    "review_request_id": 5387487100,
    "review_result_id": 5387505536,
    "revision_fingerprint": "sha256:44aa83dc55fbbdc3133709b5eb0bfbd713d9f5a4ae026aab0a95bdc7a7595b66",
    "status": "approval-evidence-recorded"
  },
  "checks": {
    "conclusions": [
      {
        "conclusion": "success",
        "name": "Gitar"
      },
      {
        "conclusion": "success",
        "name": "Linux CI checks"
      },
      {
        "conclusion": "success",
        "name": "Target smoke (darwin-amd64)"
      },
      {
        "conclusion": "success",
        "name": "Target smoke (darwin-arm64)"
      },
      {
        "conclusion": "success",
        "name": "Target smoke (linux-amd64)"
      },
      {
        "conclusion": "success",
        "name": "Target smoke (linux-arm64)"
      },
      {
        "conclusion": "success",
        "name": "Windows host smoke (windows-amd64)"
      },
      {
        "conclusion": "success",
        "name": "Windows host smoke (windows-arm64)"
      }
    ],
    "policy": "all_current_head_checks_no_branch_protection",
    "root_cause": null,
    "status": "passed"
  },
  "delivery_deferrals": [
    {
      "classification": "legacy-design-level",
      "disposition": "retain for current-design adjudication; not current-head approval evidence",
      "id": "distinct-ids-for-same-platform-binding-artifacts",
      "source_comment_id": 5329685639,
      "statement": "binding artifact IDs are platform-keyed, so one binding cannot own two ABI-specific wheels on the same platform",
      "status": "active"
    },
    {
      "classification": "legacy-PTD-05-owned",
      "disposition": "adjudicate in PR 94 under current authority; not current-head approval evidence",
      "id": "binding-contract-package-must-be-among-its-requirement-roots",
      "source_comment_id": 5329685639,
      "statement": "BindingContractV1 validates Package and parses requirements but does not require Package among their roots",
      "status": "active"
    }
  ],
  "findings": [
    {
      "classification": "current-slice-defect",
      "evidence": "Current-head CI compilation failures and regular review comment 3839081162 show SelectionCombinationV1 has no Values field",
      "fix_evidence": "dimension-keyed validation and focused negative coverage pass; full repository tests and vet pass; successor head synchronized",
      "fixed_head": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
      "id": "selection-combination-model-mismatch",
      "invariant": "PTD-04 validators and tests must compile against and validate the dimension-keyed SelectionCombinationV1 model owned by approved PR 89",
      "location": "internal/toolcatalog/records_validate.go:951",
      "proposed_fix": "Replace retired positional Values access with dimension-keyed validation, permit omitted optional dimensions, reject undeclared keys, and compare canonical JSON bytes; update focused fixtures and negative coverage",
      "source_comment_id": 3839081162,
      "source_head": "6afba9c0be22410a581df503367cc86523fab1a9",
      "source_review_id": 5002909226,
      "source_thread_id": "PRRT_kwDOTFQCkM6bgxS8",
      "status": "fixed",
      "verified_by": "clean current-head review 5387505536 and passing local validation"
    },
    {
      "classification": "verified-non-actionable",
      "disposition": "No code change; rejecting {} would add an unstated acceptance criterion",
      "evidence": "docs/PORTABLE_TOOL_DEFINITION_DESIGN.md:1259-1267 permits optional-dimension omission and exact map matching without a nonempty-map rule",
      "id": "empty-selection-combination-map",
      "invariant": "Optional dimensions may be omitted and omission is distinct from an empty value list; the design specifies no minimum number of present optional dimensions",
      "location": "internal/toolcatalog/records_validate.go:953-956",
      "source_comment_id": 3839136293,
      "source_head": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
      "source_review_id": 5002959342,
      "source_thread_id": "PRRT_kwDOTFQCkM6bg6rA",
      "status": "non-actionable"
    }
  ],
  "legacy_state": {
    "comment_id": 5329685639,
    "disposition": "archived after head migration; historical findings and deferrals retained, approval not current",
    "record_version": 5,
    "revision_fingerprint": "sha256:d417c452aff7285e2e65cb79636c5020534a60129ed339aadfe64c9f583cd9e0"
  },
  "local": {
    "mapped_nodes": [
      "31fb08f64060aef767b344d2fc05dbf4db4f0ec2"
    ],
    "remote_relation": "identical",
    "repo_root": "/home/omry/dev/reploy"
  },
  "phase": "approved-evidence",
  "pr": {
    "base_ref": "pr90",
    "base_sha": "c8b096bb5044360a28a52629ee0a4e52247be5da",
    "body_digest": "sha256:f951a96b9de5a5aed2a44e670386c3ddce6ad2dac297b4e84d507294b85c4053",
    "diff_digest": "sha256:5de6e61d2dd44f42ac28a27b0d455c099f0dc21dd6e4d00506e28b46e1bc8e16",
    "head_ref": "pr91",
    "head_sha": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
    "pr": 91,
    "repository": "omry/reploy",
    "scope_authority": [
      {
        "digest": "sha256:1f9281e471d17009da99183c9383959c88abe6be2638cb8e408fc04ada8beda6",
        "path": "AGENTS.md"
      },
      {
        "digest": "sha256:cc5a7ac158d0bfa72609c991262ae5be9911b3369b39f127b4281ad400a719f1",
        "path": "docs/PORTABLE_TOOL_DEFINITION_DESIGN.md"
      },
      {
        "digest": "sha256:c60e0dfc109214d84f9b4424258c4b54faea3137d5807114870f05da9dccf292",
        "path": "docs/PORTABLE_TOOL_DEFINITION_IMPLEMENTATION_PLAN.md"
      }
    ],
    "title_digest": "sha256:e35aa9f06efb187ccf8fd64e01a01e9d83f7fe36a3ad7a7efd4e7f776e3406a1"
  },
  "predicates": {
    "local_head_matches_remote": true,
    "one_local_mapping": true,
    "pr_open": true,
    "scope_authority_current": true,
    "scope_authority_present": true,
    "worktree_clean": true
  },
  "record_version": 8,
  "review": {
    "messages": [],
    "request": {
      "created_at": "2026-08-23T17:35:31Z",
      "id": 5387487100,
      "url": "https://github.com/omry/reploy/pull/91#issuecomment-5387487100"
    },
    "result": {
      "author": "chatgpt-codex-connector[bot]",
      "commit_id": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
      "id": 5387505536,
      "kind": "clean-comment",
      "state": "APPROVED",
      "submitted_at": "2026-08-23T17:39:36Z",
      "url": "https://github.com/omry/reploy/pull/91#issuecomment-5387505536"
    },
    "source_head": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
    "status": "clean",
    "unresolved_threads": [
      {
        "comment_id": 3839136293,
        "disposition": "The current design permits omitted optional dimensions and does not require at least one optional key; rejecting an empty combination map would invent an unstated rule.",
        "id": "PRRT_kwDOTFQCkM6bg6rA",
        "line": 956,
        "path": "internal/toolcatalog/records_validate.go",
        "start_line": 953,
        "status": "verified-non-actionable"
      }
    ]
  },
  "revision_fingerprint": "sha256:44aa83dc55fbbdc3133709b5eb0bfbd713d9f5a4ae026aab0a95bdc7a7595b66",
  "rounds": [
    {
      "attempt": 1,
      "disposition": "fixed; current-head review and checks required",
      "effective_diff_digest": "sha256:5de6e61d2dd44f42ac28a27b0d455c099f0dc21dd6e4d00506e28b46e1bc8e16",
      "finding_ids": [
        "selection-combination-model-mismatch"
      ],
      "fix_footprint": [
        "internal/toolcatalog/records_validate.go",
        "internal/toolcatalog/records_validate_test.go"
      ],
      "resulting_head": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
      "reviewed_head": "6afba9c0be22410a581df503367cc86523fab1a9",
      "root_cause": "checkpoint validator retained the retired positional Values representation after PR 89 changed combinations to dimension-keyed maps"
    },
    {
      "attempt": 2,
      "disposition": "clean current-head review; Gitar suggestion verified non-actionable under current design",
      "effective_diff_digest": "sha256:5de6e61d2dd44f42ac28a27b0d455c099f0dc21dd6e4d00506e28b46e1bc8e16",
      "finding_ids": [
        "empty-selection-combination-map"
      ],
      "fix_footprint": [],
      "resulting_head": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
      "reviewed_head": "31fb08f64060aef767b344d2fc05dbf4db4f0ec2",
      "root_cause": null
    }
  ],
  "schema": "awd:swe:pr-cycle-state",
  "version": 1
}

@omry omry removed the approved PR reviewed and approved label Aug 23, 2026
@omry

omry commented Aug 23, 2026

Copy link
Copy Markdown
Owner Author

@codex, regular review 6afba9c

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6afba9c0be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/toolcatalog/records_validate.go Outdated
Add record-local validation for every v1 record family: tool version policy and aliases, release manifests and contracts, target identities and records, binding contracts and artifacts, payloads, artifact sources, native package sets, integration fixtures, and validation profiles. Version policy follows each record's declared scheme, artifacts require exact size and digest, and every diagnostic has focused negative coverage.

Validate dimension-keyed selection combinations against declared dimensions, permit omitted optional dimensions, reject undeclared keys and values, and require canonical encoded-byte ordering.

Wire record-local validation into record decoding, which the decoding slice deliberately left unhooked.

Move PR 85's release-alias correction here: release aliases must be a bounded array of canonical, unique, sorted values, each different from the exact version.

Promote the shared version dependency to direct in go.mod, because this is the first slice to import go-version/pkg/semver directly.

Delivers PTD-04 of docs/PORTABLE_TOOL_DEFINITION_IMPLEMENTATION_PLAN.md.
Comment thread internal/toolcatalog/records_validate.go
@gitar-bot

gitar-bot Bot commented Aug 23, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 resolved / 2 findings

Adds record-local validation across all v1 tool definition record families, wiring validation directly into decoding and cleaning up dead alias validation code. Consider handling empty combination maps in validateSelectionSchemaV1 when dimensions are declared to prevent unintended bypasses.

✅ 2 resolved
Quality: validateToolVersionAliasV1 is dead code

📄 internal/toolcatalog/records_validate.go:774-788 📄 internal/toolcatalog/records_validate.go:95-102
validateToolVersionAliasV1 (records_validate.go:774-804) is defined with full scheme-aware SemVer/PEP440/integer/opaque alias logic but is never called anywhere in the package. Release manifest aliases are instead validated only via encodeToolVersionSegmentV1 (line 96), which checks canonical encodability but not scheme conformance. Either wire this function into alias validation where the scheme is known, or delete it to avoid confusion and potential lint (staticcheck unused) failures.

Edge Case: Empty combination map is accepted when dimensions are declared

📄 internal/toolcatalog/records_validate.go:953-956
In validateSelectionSchemaV1, a non-nil but empty combination map {} passes the combination == nil guard, then skips the per-dimension loop entirely (no keys to iterate), and encodes to {}. With declared dimensions present, this permits a degenerate combination that constrains nothing. If a fully-empty selection is not intended to be valid (the design only calls out permitting omitted optional dimensions, not omitting all of them), add an explicit len(combination) == 0 rejection and a negative test. If it is intended, this is a no-op.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

@omry

omry commented Aug 23, 2026

Copy link
Copy Markdown
Owner Author

@codex, regular review 31fb08f

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 31fb08f640

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@omry omry added the approved PR reviewed and approved label Aug 23, 2026
@omry
omry merged commit 2c45f79 into main Aug 24, 2026
8 checks passed
@omry
omry deleted the pr91 branch August 24, 2026 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved PR reviewed and approved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant