Skip to content

Pre-publish: correct the crates.io README snapshot + harden release gates - #76

Merged
Navi Bot (project-navi-bot) merged 4 commits into
mainfrom
chore/pre-publish-readme-and-release-gates
May 26, 2026
Merged

Pre-publish: correct the crates.io README snapshot + harden release gates#76
Navi Bot (project-navi-bot) merged 4 commits into
mainfrom
chore/pre-publish-readme-and-release-gates

Conversation

@Fieldnote-Echo

Copy link
Copy Markdown
Member

Why

The pre-publish pass for the first ordvec crates.io + PyPI release. The root
README.md becomes the immutable crates.io snapshot at publish time, and
the release workflows must not let an ungreen commit ship — so this PR (a) makes
every claim/link in the snapshot true at publish time, and (b) tightens the
release gates and fixes a latent trap that would block the wheel release.

Nothing here publishes anything. cargo publish / maturin publish stay
workflow_dispatch-only and held behind the environment required-reviewer.

docs: — publish-snapshot corrections

  • Quickstart → ordvec = "0.2" (was "being prepared… add as a git dependency");
    the git dependency is kept as a commented alternative for tracking main.
  • Python → released-state pip install ordvec.
  • "sub-linear two-stage path" → "two-stage compressed-scan path" in the README,
    and docs/RANK_MODES.md reconciled (it ships in the crate). The built-in
    bitmap/sign prefilter scans the compressed corpus — two-stage, not
    algorithmically sub-linear.
  • Co-authorship → "potential named co-authorship where contributions meet the
    paper's authorship bar".
  • crates.io + docs.rs badges uncommented; docs.rs "(available after release)"
    parenthetical dropped.
  • Dangling-link fixes (found via cargo package --list): links to
    crate-excluded targets are now absolute GitHub URLs so they don't dangle in
    an unpacked .crateREADME → ordvec-python/,
    README → docs/ALTERNATIVES_CONSIDERED.md,
    GOVERNANCE.md → .github/CODEOWNERS.

The Lean monotone-invariance claim is intentionally unchanged — the
declaration is complete in the Takens formalisation, so softening it would
understate it.

ci: — release-gate hardening

  • require-ci-green now requires a successful per-SHA-on-main run of
    fuzz.yml + codeql.yml (crate) and + python.yml (wheel), on top of
    ci.yml. Intentionally not gated: audit (schedule-only, no per-SHA run),
    coverage*/scorecard (advisory/external-service-flaky), zizmor/actionlint
    (pre-merge hygiene, not artifact safety).
  • python.yml now runs on every main push (paths filter dropped from
    push:, kept on pull_request). Without this, a docs/workflow-only release
    tip — including this very commit — produces no python.yml run for the SHA,
    making the wheel gate unsatisfiable.
  • Gate query hardened with &status=success so a per_page page-1 miss under
    heavy re-runs cannot falsely block (fail-closed either way).
  • RELEASING.md documents the expanded gate set and the cancel-in-progress /
    merge-tip release preconditions.

The gate stays fail-closed and not spoofable; the PUBLISH-HELD posture
(dispatch-only, env required-reviewer, late OIDC mint, attest-before-publish) is
unchanged.

Verification

Two independent read-only subagent audits:

  • Docs: clean — benchmark table matches benchmarks/rank_modes_results.txt
    row-for-row (no fiction), every documented method exists in src/,
    byte/bit formulas + MSRV 1.89 consistent, no remaining dangling links.
  • Pipeline: fail-closed, no bypass, PUBLISH-HELD posture intact; the two
    satisfiability traps it found (python paths filter, pagination) are fixed here.

Local: all 13 workflow YAML files parse; cargo package --list cross-checked
against every shipped-doc relative link; stale-language sweep clean.

Test plan (CI on this PR)

  • ci.yml green
  • python.yml green (now runs — this PR touches .github/workflows/python.yml)
  • fuzz.yml smoke green
  • codeql.yml green
  • actionlint.yml green (validates the workflow edits)
  • bot (copilot/gemini/qodo) + Codex review loop

The root README is the crates.io README (Cargo.toml `readme = "README.md"`) and
is snapshotted immutably at publish time, so pre-release wording and relative
links to crate-excluded files become wrong/dangling the moment we publish.

- Quickstart: `ordvec = "0.2"` (was "being prepared… add as a git dependency");
  keep the git dependency as a commented alternative for tracking `main`.
- Python: released-state `pip install ordvec` (was "in progress / pending /
  until then").
- "sub-linear two-stage path" -> "two-stage compressed-scan path": the built-in
  bitmap/sign prefilter still scans the compressed corpus, so it is two-stage,
  not algorithmically sub-linear. Reconcile docs/RANK_MODES.md (which ships in
  the crate) to match ("sub-linear retriever" -> "fast two-stage retriever").
- Co-authorship invite scoped to "potential named co-authorship where
  contributions meet the paper's authorship bar".
- Uncomment the crates.io + docs.rs badges; drop the docs.rs
  "(available after release)" parenthetical.
- Make links to crate-excluded targets absolute GitHub URLs so they do not
  dangle in an unpacked .crate (verified against `cargo package --list`):
  README -> ordvec-python/ and docs/ALTERNATIVES_CONSIDERED.md;
  GOVERNANCE.md -> .github/CODEOWNERS.

The Lean monotone-invariance claim is left as-is: the declaration is complete in
the Takens formalisation, so softening it would understate it.

Signed-off-by: Nelson Spence <nelson@projectnavi.ai>
Both release workflows are workflow_dispatch-only and gate publish behind a
require-ci-green job. Extend that gate to the checks that scan the shipped
artifact, and close two satisfiability traps that would block a legitimate
release.

- require-ci-green now asserts a successful per-SHA-on-main run of fuzz.yml
  (loader/FastScan smoke) and codeql.yml (static scan of the shipped Rust +
  Python) on top of ci.yml — plus python.yml for the wheel. audit.yml
  (schedule-only), coverage*/scorecard (advisory/external-flaky), and zizmor/
  actionlint (pre-merge hygiene, not artifact safety) are intentionally not
  gated.
- python.yml: drop the paths filter on the push:main trigger so it runs on
  every main commit. Otherwise a docs/workflow-only release tip produces no
  python.yml run for that SHA and the wheel gate is unsatisfiable. The
  pull_request paths filter is kept.
- Harden the gate query with `&status=success` so a page-1 miss under heavy
  re-runs cannot falsely block (fail-closed either way).
- RELEASING.md: document the expanded gate set and the cancel-in-progress /
  merge-tip release preconditions.

The gate stays fail-closed and not spoofable; the PUBLISH-HELD posture
(dispatch-only, env required-reviewer, late OIDC mint, attest-before-publish)
is unchanged.

Signed-off-by: Nelson Spence <nelson@projectnavi.ai>

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request updates the documentation across several files to reflect the first official release of the ordvec crate on crates.io and PyPI. Key changes include updating installation instructions in README.md to use crates.io and pip instead of git, making document links absolute, clarifying co-authorship guidelines, and expanding the release process documentation in RELEASING.md to detail CI gating requirements. Additionally, a minor terminology correction was made in docs/RANK_MODES.md. There are no review comments, and I have no feedback to provide.

@codecov

codecov Bot commented May 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Fieldnote-Echo

Copy link
Copy Markdown
Member Author

/agentic_review

@qodo-code-review

qodo-code-review Bot commented May 26, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0)

Grey Divider


Remediation recommended

1. Main-only release not enforced 🐞 Bug ☼ Reliability ⭐ New
Description
RELEASING.md states the environment refuses any ref other than main, but the release workflows
themselves don’t enforce github.ref == refs/heads/main, so this invariant is not source-controlled
and can silently become false if environment branch policies aren’t configured.
Code

RELEASING.md[R59-60]

Evidence
The new checklist text asserts the environment blocks non-main refs, but both release workflows are
only workflow_dispatch and contain no YAML-level check restricting the ref to main, so this
guarantee is not enforceable from the repo content alone.

RELEASING.md[59-62]
.github/workflows/release-crate.yml[21-23]
.github/workflows/release-python.yml[18-20]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RELEASING.md` claims releases can only be dispatched from `main` because “the environment refuses any other ref”, but the repository’s release workflows are `workflow_dispatch` without an in-workflow ref check. This means the main-only invariant depends on out-of-band GitHub Environment configuration and can drift.

### Issue Context
The release gate logic keys off `${{ github.sha }}`. Without an explicit ref assertion, a maintainer could dispatch from a non-`main` ref (branch/tag) that points at some SHA that also exists on `main`, and the in-repo workflows would not reject it.

### Fix Focus Areas
- RELEASING.md[59-62]
- .github/workflows/release-crate.yml[21-23]
- .github/workflows/release-python.yml[18-20]

### Suggested fix
- Add an explicit guard early in both `release-crate.yml` and `release-python.yml` (e.g., a first step in every job or a job-level `if`) to fail unless `github.ref == 'refs/heads/main'`.
- Alternatively (or additionally), soften/clarify the documentation to say this is enforced by GitHub Environment branch policies and must be configured, rather than stating it as an unconditional fact.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Rerun guidance misses required jobs 🐞 Bug ⚙ Maintainability ⭐ New
Description
The checklist says only ci.yml/python.yml are cancelled by cancel-in-progress and suggests
rerunning a single “HEAD run”, but fuzz.yml and codeql.yml also use cancel-in-progress and are
required by require-ci-green, so following the checklist can still leave the gate unsatisfied.
Code

RELEASING.md[R65-72]

Evidence
The checklist text mentions only ci.yml/python.yml cancellation, but the repo config shows
fuzz.yml and codeql.yml also cancel superseded runs; and the release gate requires successful
fuzz.yml/codeql.yml, so those cancelled runs must also be rerun to satisfy the gate.

RELEASING.md[65-72]
.github/workflows/fuzz.yml[31-33]
.github/workflows/codeql.yml[37-39]
.github/workflows/release-crate.yml[83-90]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RELEASING.md`’s Step 3 cancellation/rerun guidance is incomplete after the gate expansion: it calls out `ci.yml`/`python.yml` cancellation, but `fuzz.yml` and `codeql.yml` can also be cancelled and are now required for release.

### Issue Context
`require-ci-green` now requires successful runs for `ci.yml`, `fuzz.yml`, and `codeql.yml` (and `python.yml` for the wheel). Multiple of these workflows are configured with `cancel-in-progress: true`, so “rerun that HEAD run” can be insufficient/ambiguous.

### Fix Focus Areas
- RELEASING.md[65-73]

### Suggested fix
- Update the bullet(s) to explicitly state that **all gated workflows** may be cancelled and must be rerun for the release SHA: `ci.yml`, `fuzz.yml`, `codeql.yml` (and `python.yml` for wheels).
- Replace “re-run that HEAD run” with explicit instructions such as “re-run any cancelled required workflow runs for the HEAD SHA until all required workflows complete successfully.”

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Docs link to moving main 🐞 Bug ⚙ Maintainability
Description
README.md and GOVERNANCE.md now link to GitHub blob/main / tree/main, so the published 0.2.0
crate snapshot can later point to different content (or 404) as main changes. This makes the
crates.io README / shipped docs potentially misleading after future refactors or file moves.
Code

README.md[R126-134]

Evidence
The repo is already at version 0.2.0 and the README is the published crate readme, but the updated
links target main, which will change independently of the released version snapshot.

Cargo.toml[1-10]
README.md[87-139]
GOVERNANCE.md[6-13]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The crate’s published docs are a release snapshot (e.g., v0.2.0), but several links were changed to point at the moving `main` branch (`blob/main` / `tree/main`). As `main` evolves, these links can drift away from the released snapshot or break.

### Issue Context
This affects the crates.io-rendered README and any markdown files shipped in the crate that users read alongside that version.

### Fix Focus Areas
- README.md[126-134]
- GOVERNANCE.md[11-11]

### Suggested fix
- Replace `.../blob/main/...` and `.../tree/main/...` with links pinned to the release tag (e.g. `.../blob/v0.2.0/...`, `.../tree/v0.2.0/...`) or a commit permalink for the exact release SHA.
- If you want to avoid manual updates each release, consider linking to documentation that is inherently versioned (e.g., docs.rs URLs) where applicable, or ensure the referenced markdown is included in the crate so relative links remain stable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Previous review results

Review updated until commit cb065b0

Results up to commit 50b21fa


🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)


Remediation recommended
1. Docs link to moving main 🐞 Bug ⚙ Maintainability
Description
README.md and GOVERNANCE.md now link to GitHub blob/main / tree/main, so the published 0.2.0
crate snapshot can later point to different content (or 404) as main changes. This makes the
crates.io README / shipped docs potentially misleading after future refactors or file moves.
Code

README.md[R126-134]

Evidence
The repo is already at version 0.2.0 and the README is the published crate readme, but the updated
links target main, which will change independently of the released version snapshot.

Cargo.toml[1-10]
README.md[87-139]
GOVERNANCE.md[6-13]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The crate’s published docs are a release snapshot (e.g., v0.2.0), but several links were changed to point at the moving `main` branch (`blob/main` / `tree/main`). As `main` evolves, these links can drift away from the released snapshot or break.

### Issue Context
This affects the crates.io-rendered README and any markdown files shipped in the crate that users read alongside that version.

### Fix Focus Areas
- README.md[126-134]
- GOVERNANCE.md[11-11]

### Suggested fix
- Replace `.../blob/main/...` and `.../tree/main/...` with links pinned to the release tag (e.g. `.../blob/v0.2.0/...`, `.../tree/v0.2.0/...`) or a commit permalink for the exact release SHA.
- If you want to avoid manual updates each release, consider linking to documentation that is inherently versioned (e.g., docs.rs URLs) where applicable, or ensure the referenced markdown is included in the crate so relative links remain stable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Qodo Logo

@Fieldnote-Echo

Copy link
Copy Markdown
Member Author

Codex (@codex) review

@chatgpt-codex-connector

Copy link
Copy Markdown

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

ℹ️ 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 (@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 (@codex) address that feedback".

Copilot AI 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.

Pull request overview

Pre-publish cleanup to ensure the crates.io README snapshot is accurate at publish time and to harden the manual release workflows so they only ship commits that have a successful, per-SHA run of the required CI workflows on main.

Changes:

  • Update published-facing docs (README.md, docs/RANK_MODES.md, GOVERNANCE.md) to reflect released crate/PyPI install paths and fix links that would dangle in the packaged crate.
  • Harden release gates in release-crate.yml / release-python.yml to require successful ci.yml + fuzz.yml + codeql.yml (and python.yml for wheels) runs for the exact SHA on main.
  • Make python.yml run on every main push (no paths filter) so wheel releases can always satisfy the per-SHA gating requirement.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
RELEASING.md Expands release checklist/docs to match the strengthened CI gating model.
README.md Updates crates.io snapshot (version install, PyPI install, wording, and non-dangling links).
GOVERNANCE.md Fixes Codeowners link to avoid a dangling path in packaged artifacts.
docs/RANK_MODES.md Rewords two-stage path description to avoid “sub-linear” phrasing.
.github/workflows/release-python.yml Extends the per-SHA “require-ci-green” gate to include fuzz + CodeQL and hardens the API query.
.github/workflows/release-crate.yml Extends the per-SHA “require-ci-green” gate to include fuzz + CodeQL and hardens the API query.
.github/workflows/python.yml Removes push paths filter so every main commit produces a gating-eligible run.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread RELEASING.md Outdated
Comment thread RELEASING.md Outdated
The cancellation-recovery note added in the previous commit said "re-run the
affected workflow for the SHA from the Actions UI, then dispatch" without tying
"the SHA" to the publish target. A release always dispatches from `main` (the
environment restricts the ref), so the gate checks `main` HEAD's SHA — the
instruction could be read as "re-run the older, superseded commit's CI to green,
then dispatch", which would publish HEAD: a different SHA than the one
re-validated.

Reword so the recovery is anchored to `main` HEAD: release from the new HEAD
once its own CI completes green, never from or by re-validating the superseded
commit; if HEAD's own run was cancelled, re-run that HEAD run (the exact SHA to
be published) and wait for green. Do not hand-clear the gate on any other
commit.

(Codex stop-gate review finding.)

Signed-off-by: Nelson Spence <nelson@projectnavi.ai>
@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Pre-publish: correct README snapshot and harden release gates

✨ Enhancement 📝 Documentation

Grey Divider

Walkthroughs

Description
• Correct README/docs for crates.io publish snapshot (quickstart, Python, terminology,
  co-authorship, badges, dangling links)
• Harden release gates to require fuzz.yml and codeql.yml success alongside ci.yml
• Fix wheel-gate satisfiability by removing python.yml paths filter on main pushes
• Add &status=success query parameter to prevent pagination misses in gate checks
• Document release preconditions and cancel-in-progress merge-tip constraints in RELEASING.md
Diagram
flowchart LR
  A["README/docs corrections"] --> B["Publish-ready snapshot"]
  C["python.yml paths filter removal"] --> D["Wheel gate satisfiable"]
  E["fuzz.yml + codeql.yml gating"] --> F["Comprehensive CI coverage"]
  G["status=success query param"] --> H["Pagination-safe gate checks"]
  I["RELEASING.md preconditions"] --> J["Safe release workflow"]

Loading

Grey Divider

File Changes

1. README.md 📝 Documentation +19/-16

Correct README for crates.io publish snapshot

• Uncommented crates.io and docs.rs badges; removed "(available after release)" parenthetical
• Updated quickstart from git dependency to ordvec = "0.2" with commented git alternative
• Changed "sub-linear two-stage path" to "two-stage compressed-scan path" for accuracy
• Updated Python section from "in progress" to released state with pip install ordvec
• Converted relative links to absolute GitHub URLs for crate-excluded files (ordvec-python/,
 ALTERNATIVES_CONSIDERED.md)
• Scoped co-authorship invitation to "potential named co-authorship where contributions meet the
 paper's authorship bar"

README.md


2. docs/RANK_MODES.md 📝 Documentation +1/-1

Reconcile terminology with README

• Changed "sub-linear retriever" to "fast two-stage retriever" to match README terminology

docs/RANK_MODES.md


3. GOVERNANCE.md 📝 Documentation +1/-1

Fix dangling CODEOWNERS link

• Converted relative link to .github/CODEOWNERS to absolute GitHub URL to prevent dangling link in
 unpacked .crate

GOVERNANCE.md


View more (4)
4. .github/workflows/python.yml ⚙️ Configuration changes +6/-8

Remove paths filter from main push trigger

• Removed paths filter from push: trigger so python.yml runs on every main commit (not just
 binding/src changes)
• Kept paths filter on pull_request: to avoid redundant runs on PRs that don't touch bindings
• Updated comment to explain that release-python.yml's gate requires a python.yml run for the exact
 release SHA

.github/workflows/python.yml


5. .github/workflows/release-crate.yml ✨ Enhancement +27/-19

Gate crate release on fuzz and codeql workflows

• Extended require-ci-green gate to check fuzz.yml and codeql.yml in addition to ci.yml
• Added &status=success query parameter to prevent pagination misses under heavy re-runs
• Updated gate logic to loop through all four workflows (ci.yml, fuzz.yml, codeql.yml) and verify
 each has a successful run
• Expanded documentation to explain which workflows are gated (per-push-to-main) vs. not gated
 (schedule-only, advisory, pre-merge hygiene)

.github/workflows/release-crate.yml


6. .github/workflows/release-python.yml ✨ Enhancement +15/-7

Gate wheel release on fuzz and codeql workflows

• Extended require-ci-green gate to check fuzz.yml and codeql.yml in addition to ci.yml and
 python.yml
• Added &status=success query parameter to prevent pagination misses under heavy re-runs
• Updated gate logic to loop through all four workflows and verify each has a successful run on main
• Expanded documentation to clarify which workflows are gated vs. not gated and why

.github/workflows/release-python.yml


7. RELEASING.md 📝 Documentation +21/-4

Document expanded release gates and merge-tip preconditions

• Updated gate description to include fuzz.yml and codeql.yml alongside ci.yml and python.yml
• Added detailed preconditions for step 3: confirm CI is green for current main HEAD with completed,
 successful runs
• Documented cancel-in-progress merge-tip constraint: do not merge another PR between release
 commit and dispatch
• Added guidance on re-running cancelled runs and releasing only from merge-commit tips with
 push-to-main CI runs

RELEASING.md


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented May 26, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit cb065b0

"Release only from a merge-commit tip" was narrower than what require-ci-green
enforces — a *successful push-to-main run for the SHA*. Squash and rebase merges
also produce a main tip with a push-to-main run, so they are releasable too; the
old wording wrongly implied only "create a merge commit" merges qualify.

Reword to "a commit on main with a successful push-to-main run of each gated
workflow — in practice the tip the merge produced (squash commit, rebased tip,
or merge commit)". Keep the accurate part: an interior PR-branch commit only ran
CI as a pull_request and has no push-to-main run, so it is not releasable.

(Copilot PR #76 review finding.)

Signed-off-by: Nelson Spence <nelson@projectnavi.ai>
@project-navi-bot
Navi Bot (project-navi-bot) merged commit 9e0ad6d into main May 26, 2026
31 checks passed
@project-navi-bot
Navi Bot (project-navi-bot) deleted the chore/pre-publish-readme-and-release-gates branch May 26, 2026 16:08
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.

3 participants