Skip to content

Add automatic OCI tag pagination to the library and CLI - #70

Merged
toddysm merged 12 commits into
mainfrom
feature/tag-pagination/issue-69-fd2ca782
Oct 30, 2026
Merged

toddysm merged 12 commits into
mainfrom
feature/tag-pagination/issue-69-fd2ca782

Conversation

@toddysm

@toddysm toddysm commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

Implement #69 with list_tags_all() and the opt-in regshape tag list --all command, following the Open Container Initiative (OCI) Distribution Specification v1.1.1 tag-pagination rules.

  • Prefer next links, including on short/empty pages; otherwise use exclusive tag cursors and the effective page size of each request.
  • Preserve tag spelling, opaque query bytes, and relative URI path semantics. The all-pages default is 100; single-page behavior, including n=0, remains unchanged.
  • Reject duplicate/overlapping tags and returned exclusive-cursor values before aggregation, including across redirects. Output files are not overwritten with partial results.
  • Validate redirect origins before dispatch and authentication, with bounded same-origin authentication-probe redirects in both transport modes. Shared URL checks require ASCII authorities; punycode remains supported for international names.
  • Sanitize low-level Requests parser errors before logging and preserve redirect-policy cache isolation, ordinary request defaults, telemetry, and output options.
  • Bound non-progressing traversal at ten consecutive empty linked pages, with explicit failure rather than a partial result.
  • Update public exports, source contracts, operations/CLI specifications, examples, and regression coverage.

This branch includes repaired main from #71 and the now-merged referrer feature from #68. Release automation is unchanged.

Current validation

Testing mode: hosted. Tested/pushed head: f0166d0bd0d317f00a38ecd73aa7a9d46221e9b4.

  • Main 5fdd598a3233d5cb53b4380c22f104e4a91bf439 (merged Support tag references when listing referrers #68) is integrated without rewriting history or resolving any conflicts. Only the three previously reviewed referrer source/test/specification files were brought in.
  • Local full suite: PYTHONDONTWRITEBYTECODE=1 python3 -B -m pytest -q -p no:cacheprovider — 1300 passed on Python 3.12.4, validating both features together.
  • Targeted pagination suite: 229 passed, including 13 boundary/reset/redirect/output-safety cases for the approved limit and 43 malformed-tag/cursor and valid-boundary regressions.
  • Scoped mypy (--follow-imports=silent) passes for the modified tag operation after restoring missing Requests stubs in an isolated validation environment. Bandit and whitespace checks pass. Default Ruff reports the same 14 pre-existing style diagnostics as the pre-change source, with no additional findings; unrelated style normalization is not included.
  • Local self-review covers the operation, new fixtures/tests, and library/CLI documentation; no new findings. Single-page behavior, redirect accounting, and output safety remain covered.
  • Hosted run 40982412596: 1300 passed on each of Python 3.10, 3.11, and 3.12 at the combined head. CodeQL and its Python/Actions analyses pass. Current-head Copilot recommends approval with no active issues; Codex completed with no findings, and there are no unresolved inline threads. Scoped mypy also passes for both the referrer CLI and tag operations.
  • Tests use mocked network responses, including adapter-level coverage that exercises real Requests parsing. No live registry was used, and no failing tests were skipped or disabled.

Human-approved empty-page safety policy

The owner selected 10, rather than the initially proposed 30, as the maximum consecutive empty linked-page count. Commit a8519be92c6a996161e7f316632f79dc52fd5cdf fails explicitly on the tenth empty page carrying a next link, before requesting its continuation, even when opaque URLs keep changing. Receiving tags resets the counter; an empty page without a next link still completes normally. Redirect responses neither increment nor reset it.

This is a documented RegShape safety policy, not an OCI-mandated limit or a cap on total pages. The error returns no partial list, writes no partial standard output, and leaves output files untouched. Tests check the exact threshold and request count, nine-page success, terminal-empty completion, reset through linked and cursor-only continuation, redirects, and plain/JSON output to stdout or new/existing files.

All previous inline findings have fixes, reproducing tests, SHA-confirmation replies, and resolved threads. The empty-page assessment is addressed by the approved ten-page policy. A refreshed summary also identified malformed tag strings: commit e53b4fd0eeadb9b15a0684cf9729312e285ed2d3 validates returned tags and initial/linked cursors against the OCI grammar before output or encoding, without changing single-page behavior or opaque continuation fields. Bounded offline probes reproduced newline output distortion and an unhandled surrogate-encoding error before the fix; regression tests now verify explicit TagError failures and preserved output. Merged with owner authorization as ed17d2eef64da73528998e5c0917dff4e91820c5, after #68 merged as 5fdd598a3233d5cb53b4380c22f104e4a91bf439. Both GitHub merge signatures are verified, and the final main tree exactly matches the tested/reviewed combined head. Issues #46 and #69 are closed. Post-merge main run 40982870365 passed 1300 tests on each of Python 3.10, 3.11, and 3.12. No release or branch/worktree cleanup was performed; both owned worktrees and remote branches are retained clean and fully pushed.

Closes #69

Add list_tags_all and opt-in tag list --all with Link preference, exclusive cursor fallback, effective page-size handling, same-origin guards, and explicit progress errors. Preserve single-page semantics, exercise library/CLI/transport regressions, and document OCI requirements and client policies.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 29, 2026 17:40
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T00:55:34.960783Z f0166d0 Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Cursor fallback corrupts opaque query values, which can cause failed or incorrect page requests and false cycle detection for distinct continuation links.

1 open issue
What changed in this PR

Adds automatic OCI tag pagination through list_tags_all() and the opt-in regshape tag list --all command, while retaining single-page behavior.

Changes:

  • Adds link-based traversal, cursor fallback, and pagination safety checks.
  • Preserves CLI output options and delays results until traversal succeeds.
  • Adds regression coverage, hosted tests, and pagination documentation.
File Description
src/​regshape/​tests/​test_tag_pagination.py Adds library, CLI, and transport pagination regressions.
src/​regshape/​libs/​tags/​operations.py Implements all-pages traversal and shared page fetching.
src/​regshape/​libs/​tags/​__init__.py Exports list_tags_all().
src/​regshape/​libs/​models/​tags.py Clarifies ordering and spelling preservation in documentation.
src/​regshape/​cli/​tag.py Adds --all, validation, and operation selection.
specs/​operations/​tags.md Documents traversal, safety checks, and error behavior.
specs/​cli/​tag.md Documents pagination options and output guarantees.
README.md Adds automatic pagination examples.
CONTRIBUTING.md Documents test setup and hosted validation.
.github/​workflows/​tests.yml Runs pytest on Python 3.10, 3.11, and 3.12.

Review effort: Balanced

Comment thread src/regshape/libs/tags/operations.py Resolved
Decode only n and last for pagination validation. Preserve raw opaque fields during cursor fallback and page identity so non-UTF-8 continuation bytes are neither rewritten nor conflated. Add reproducing regressions and document the preservation rule.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Relative pagination links lose empty path segments during URL resolution, potentially sending valid same-origin continuations to the wrong endpoint and breaking traversal or fetching the wrong page.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity Preserve empty path segments in relative next-link resolution

src/​regshape/​libs/​tags/​operations.py:256

urljoin() collapses empty segments in relative next links: pages/token//part?n=2 becomes .../tags/pages/token/part?n=2, while the equivalent absolute link preserves the double slash. These are distinct URI paths, so a valid same-origin continuation can reach the wrong endpoint and fail traversal or fetch the wrong page. Preserve empty path segments during relative resolution while retaining dot-segment handling and same-origin checks, and add a relative-link regression.

1 resolved since last review

Review effort: Balanced

Resolve references with RFC 3986 component and dot-segment rules instead of collapsing empty path segments. Preserve base-path segments and distinguish empty from absent reference queries. Add reproducing public traversal tests and standard URI-resolution cases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Pagination redirects can expose stored registry credentials to an off-origin authentication realm, and URL-parser errors can leak embedded credentials to CLI stderr.

No open issues 🎉

2 previously missed issues

In code that hasn't changed since last review

High severity Prevent credential leakage through off-origin pagination redirects

src/​regshape/​libs/​tags/​operations.py:139

A same-origin next link can redirect off-origin, and client.get() processes the redirected response's authentication challenge before this origin check runs. An off-origin 401 with a Bearer realm can therefore send stored registry credentials to that realm before pagination rejects the response. Disable automatic redirects for pagination in both transport modes, validate each redirect target before following it or processing authentication, and add a regression asserting that an off-origin redirected challenge triggers no credential exchange.

High severity Sanitize URL parsing errors to prevent credential disclosure

src/​regshape/​libs/​tags/​operations.py:260

Forwarding str(exc) can expose credentials before the userinfo check runs: https://user:secret@registry.example.com/ignored/tags makes urlsplit() raise a Unicode normalization error containing user:secret. That text becomes the TagError message and is printed to CLI stderr. Return a sanitized detail for URL-parser failures, suppress the raw exception chain, and add this malformed credential-bearing URL to the redaction regression test.

Review effort: Balanced

Disable automatic pagination redirects through both transport modes, authentication probes/retries, and cache variants. Follow only validated same-origin redirects with a bounded hop count. Sanitize URL-parser errors and suppress credential-bearing exception context. Add security regressions and preserve default redirect behavior for other callers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Valid same-origin redirects that only reorder query parameters are incorrectly rejected as pagination cycles, preventing the redirected page from being fetched.

1 open issue

Review effort: Balanced

Comment thread src/regshape/libs/tags/operations.py Resolved
Allow safe redirects that canonicalize pagination query order while retaining separate exact redirect-cycle tracking, completed-page detection, and the redirect limit. Add reproducing success and cycle regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues are reported for the automatic tag-pagination change.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@toddysm
toddysm requested a balanced review from Copilot October 29, 2026 21:11
@toddysm

toddysm commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@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: 39929611b3

ℹ️ 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 src/regshape/libs/tags/operations.py Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Requests can fail while parsing a redirect before URL sanitization, potentially exposing embedded credentials in logs or tracebacks and bypassing handled CLI errors.

1 open issue

Review effort: Balanced

Comment thread src/regshape/libs/tags/operations.py Resolved
Share credential-safe URI resolution with bounded auth-probe redirects in both transport modes. Reject overlapping tag pages without partial output. Sanitize pre-return Requests parser errors before logging and cover the real redirect parser at the adapter boundary. Preserve ordinary request defaults and document the new consistency checks.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@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: 35a19a2f0c

ℹ️ 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 src/regshape/libs/tags/operations.py Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The review has no active issues for the automatic OCI tag-pagination change.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

Retain requested cursor boundaries across redirects and reject any returned cursor tag before aggregation, including short pages. Preserve existing duplicate/no-progress diagnostics and add initial, linked, and redirected cursor regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@toddysm
toddysm requested a balanced review from Copilot October 29, 2026 22:00
@toddysm

toddysm commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: b3319b6659

ℹ️ 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".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Human assessment is needed because cursor cycles with changing opaque query fields can bypass pagination guards, risking unbounded traversal or misleading partial results.

No open issues 🎉

Review effort: Balanced

@toddysm toddysm added needs-human Needs a human decision before proceeding and removed needs-human Needs a human decision before proceeding labels Oct 29, 2026
Fail on the tenth consecutive empty linked page, reset on tags, and preserve terminal-empty completion and atomic CLI output. Document the client policy and test exact boundaries, redirects, and output safety.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@toddysm

toddysm commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

Fixed the remaining empty-page non-progress concern in a8519be92c6a996161e7f316632f79dc52fd5cdf. The owner approved a 10-consecutive-empty-linked-page client safety limit: fail on the tenth before following another link, reset on received tags, and retain successful terminal-empty completion. Redirects do not count as pages or reset progress. Library/CLI documentation and 13 boundary, reset, redirect, and no-partial-output cases are included. Local full suite: 1233 passed; hosted validation is pending.

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: a8519be92c

ℹ️ 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".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Human assessment is needed because malformed tag strings can distort CLI output or trigger an unhandled cursor-encoding error.

No open issues 🎉

Review effort: Balanced

Validate all-pages tag values and initial/linked cursors against the OCI grammar before output or encoding. Preserve single-page behavior and opaque continuation fields, with valid-boundary and malformed-output regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@toddysm

toddysm commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

Fixed the latest malformed-tag assessment in e53b4fd0eeadb9b15a0684cf9729312e285ed2d3. Bounded probes reproduced newline output distortion and an unhandled surrogate-encoding failure. All-pages traversal now validates returned tags and initial/linked tag cursors against the OCI grammar before rendering or encoding; opaque continuation values and single-page behavior remain unchanged. The approved ten-empty-linked-page policy remains intact. Local full suite: 1276 passed; focused pagination suite: 229 passed, including 43 additional malformed-tag/cursor and valid-boundary cases. Scoped mypy/Bandit pass; Ruff matches the unchanged baseline.

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: e53b4fd0ee

ℹ️ 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".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues are recorded for the automatic tag-pagination change.

No open issues 🎉

Review effort: Balanced

Integrate the reviewed referrer feature before validating and merging tag pagination.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@toddysm
toddysm requested a balanced review from Copilot October 30, 2026 00:52
@toddysm

toddysm commented Oct 30, 2026

Copy link
Copy Markdown
Owner Author

Integrated merged #68 into this branch as f0166d0bd0d317f00a38ecd73aa7a9d46221e9b4, with no conflicts or manual source changes. The full combined local suite passes 1300 tests. Existing pagination safety policies are unchanged. Please review this integration before the authorized merge.

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: f0166d0bd0

ℹ️ 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".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues remain for the OCI tag pagination change.

No open issues 🎉

Review effort: Balanced

@toddysm
toddysm merged commit ed17d2e into main Oct 30, 2026
7 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.

Implement automatic tag pagination in the library and CLI

2 participants