release: prepare v0.2.0#19
Conversation
Why: - add the first SwiftlyFetch product facade for one corpus write feeding FetchKit and RAGKit - record the settled semantic retry decisions, including delete cleanup retries - include release and CI hardening already present in the worktree for this branch checkpoint Verification: - swift test --filter SwiftlyFetch - swift test - scripts/repo-maintenance/validate-all.sh
Why: - add a literal searchAndRetrieve facade call before any ranked hybrid score policy - add TinyStories as a second checked-in text source for corpus-based tests - move corpus fixtures into a shared test fixture target for FetchKit and SwiftlyFetch coverage Verification: - swift test --filter 'SwiftlyFetchLibraryTests|FixtureCorpusQualityTests|SearchKitFetchIndexTests' - scripts/repo-maintenance/validate-all.sh
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (11)
📝 WalkthroughWalkthroughThis pull request introduces the SwiftlyFetch umbrella facade—a coordinated ingestion surface unifying conventional full-text search via FetchKit with semantic vector search via RAGKit. The change adds semantic index persistence through Core Data, deterministic fingerprinting for semantic change tracking, a retry queue for deferred semantic indexing, expanded test fixtures with a second corpus source, and release/CI infrastructure improvements. ChangesSwiftlyFetch Umbrella Facade with Semantic Persistence
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
AGENTS.md (1)
24-24: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winReconcile the persistence boundary with the new approved architecture.
This file still tells contributors to stop before adding persistence layers, but this PR formalizes persisted semantic index state under
RAGKit/SwiftlyFetch. Leaving both statements in place makes the repo’s top-level guidance self-contradictory for the next change. Please carve out the now-approved semantic-persistence exception explicitly instead of keeping the blanket ban unchanged.Based on learnings: Work is done when the package still builds and tests cleanly, repo-maintenance validation passes, and nearby maintainer docs stay aligned with the code when the implementation meaningfully changes.
Also applies to: 69-72, 103-103
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@AGENTS.md` at line 24, AGENTS.md currently forbids adding persistence but the PR approves persisted semantic-index state under RAGKit/SwiftlyFetch; update the top-level guidance to explicitly carve out a semantic-persistence exception by adding a short clause that permits persisted semantic index state implemented under the RAGKit/SwiftlyFetch boundary and references the approved pattern, and then reconcile the other occurrences (around the current guidance at the other two spots mentioned) so they no longer contradict the exception; ensure the new wording is concise, mentions RAGKit/SwiftlyFetch by name, and keeps the original “stop and surface” rule for other scope changes.
🧹 Nitpick comments (5)
Tests/SwiftlyFetchTests/SwiftlyFetchDocumentMapperTests.swift (1)
40-55: ⚡ Quick winAdd one test for non-empty title with
.plainTextcontent.Line 37-39 in the mapper has a distinct path (
"Title: …"prefix) that isn’t covered yet. Adding this test closes a real branch gap with minimal effort.Proposed test addition
struct SwiftlyFetchDocumentMapperTests { @@ `@Test`("Mapper preserves plain text body when title is empty") func mapperPreservesPlainTextBodyWhenTitleIsEmpty() { @@ `#expect`(document.metadata["contentType"] == .string("plainText")) } + + `@Test`("Mapper prefixes plain text content when title is present") + func mapperPrefixesPlainTextBodyWhenTitleIsPresent() { + let mapper = SwiftlyFetchDocumentMapper() + let record = FetchDocumentRecord( + id: "doc-note-title", + title: "Daily Note", + body: "A standalone note.", + contentType: .plainText + ) + + let document = mapper.document(from: record) + + `#expect`(document.content == .text("Title: Daily Note\n\nA standalone note.")) + `#expect`(document.metadata["title"] == .string("Daily Note")) + `#expect`(document.metadata["contentType"] == .string("plainText")) + } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Tests/SwiftlyFetchTests/SwiftlyFetchDocumentMapperTests.swift` around lines 40 - 55, Add a complementary unit test that verifies SwiftlyFetchDocumentMapper handles a non-empty title when contentType is .plainText: create a FetchDocumentRecord with title set to a non-blank string (e.g., "Note title"), body set to plain text, and contentType .plainText, call SwiftlyFetchDocumentMapper.document(from:), and assert the resulting document.content includes the "Title: …" prefixed text path and that metadata["title"] contains the title and metadata["contentType"] equals .string("plainText"); use a descriptive test name like mapperPreservesPlainTextBodyWhenTitleIsNonEmpty to mirror the existing test.Tests/SwiftlyFetchTests/SwiftlyFetchLibraryTests.swift (1)
482-496: 💤 Low valueConsider cleaning up temporary test directories.
The
temporaryDirectory()helper creates unique directories under the system temp folder but doesn't schedule cleanup. Over many test runs, these directories accumulate. Consider adding cleanup in a deinit or usingaddTeardownBlockif the test framework supports it, or documenting that manual cleanup may be needed.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Tests/SwiftlyFetchTests/SwiftlyFetchLibraryTests.swift` around lines 482 - 496, The temporaryDirectory() helper creates unique temp folders but never removes them; update the test to schedule cleanup by removing the created directory after test completion: either modify temporaryDirectory() to register a teardown (e.g., using addTeardownBlock or the test framework's equivalent) that calls FileManager.default.removeItem(at:) for the returned URL, or change callers to receive the URL and explicitly remove it in their teardown. Ensure error handling/logging is present when removing the directory so failures don't silently pass.Tests/RAGKitTests/CoreDataVectorIndexTests.swift (1)
1-5: ⚖️ Poor tradeoffConsider using Swift Testing instead of XCTest.
As per coding guidelines, tests should prefer Swift Testing by default unless an external constraint requires XCTest. This file uses XCTest, but the tests appear to be straightforward async tests that would work well with Swift Testing's
@Testand#expectmacros.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Tests/RAGKitTests/CoreDataVectorIndexTests.swift` around lines 1 - 5, The tests currently import XCTest and define final class CoreDataVectorIndexTests: XCTestCase; replace XCTest usage with Swift Testing by swapping the import (import SwiftTesting) and refactoring the test file to use Swift Testing's style: remove the XCTestCase subclass and replace each test method with a top-level or struct-scoped `@Test` function (or annotate the test container accordingly) and use the `#expect` macros for assertions and async expectations; update any uses of XCTest assertions (XCTAssert*, expectation/wait) to their Swift Testing equivalents so CoreDataVectorIndexTests and its test functions compile and run under Swift Testing.Sources/RAGKit/KnowledgeBase+NaturalLanguage.swift (1)
4-10: 💤 Low valueConsider removing unnecessary
async throwsfrom in-memory factory.
hashingDefaultcreates anInMemoryVectorIndexwhich doesn't require async initialization or throw. Theasync throwssignature adds unnecessary ceremony for callers.Suggested simplification
- static func hashingDefault(dimension: Int = 64) async throws -> KnowledgeBase { + static func hashingDefault(dimension: Int = 64) -> KnowledgeBase { KnowledgeBase( chunker: DefaultChunker(), embedder: HashingEmbedder(dimension: dimension), index: InMemoryVectorIndex() ) }Note: This would be a breaking change if callers already use
try await. Consider whether API stability or ergonomics is more important here.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/RAGKit/KnowledgeBase`+NaturalLanguage.swift around lines 4 - 10, Remove the unnecessary async/throwing signature from the factory: change static func hashingDefault(dimension: Int = 64) async throws -> KnowledgeBase to a synchronous, non-throwing factory (e.g. static func hashingDefault(dimension: Int = 64) -> KnowledgeBase) because it only constructs DefaultChunker, HashingEmbedder, and InMemoryVectorIndex (which have no async or throwing init); update any callers that currently use try/await to call it synchronously, and ensure the returned KnowledgeBase construction still uses DefaultChunker(), HashingEmbedder(dimension:), and InMemoryVectorIndex() as before.Sources/RAGKit/CoreDataVectorIndex.swift (1)
343-372: 💤 Low valueSearch loads all chunks into memory before filtering.
The current implementation fetches all stored chunks, then filters and sorts in-memory. This is acceptable for small-to-medium corpora but will become a memory concern as corpus size grows.
For v1 this is pragmatic; consider adding a note or TODO for future optimization (e.g., Core Data fetch batching, pre-filtering by document ID sets, or approximate nearest neighbor indexing).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/RAGKit/CoreDataVectorIndex.swift` around lines 343 - 372, The search(_ query: SearchQuery, embedding: EmbeddingVector) method currently fetches all IndexedChunk entities into memory before applying query.filter and ranking; update the implementation by adding a clear TODO comment inside CoreDataVectorIndex.search indicating this is a pragmatic v1 approach and should be optimized later (e.g., use NSFetchRequest batching, predicate pre-filtering by metadata/document IDs, or integrate an ANN index) and include which parts to change (the performRead fetch of EntityName.indexedChunk and the in-memory filtering/ranking pipeline) so future work knows to move filtering/sorting into the Core Data fetch or replace it with an ANN-backed query.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/maintainers/hybrid-search-persistence-plan.md`:
- Around line 121-123: Update the three bullet items in
hybrid-search-persistence-plan.md to use "Extend" instead of "Add" and rephrase
each to indicate incremental hardening (e.g., "Extend the bridge from
FetchDocumentRecord to RAGCore.Document", "Extend the umbrella library facade to
own one ingestion operation and call both sibling systems", "Extend the
umbrella-owned semantic retry queue keyed by document ID with attempt counts and
next retry dates"); ensure the wording clarifies these are follow-up extensions
rather than net-new features and, if relevant, add a brief note referencing
where roadmap/maintainer updates should be made (docs/maintainers/ or
ROADMAP.md) to reflect the change in milestone scope.
In `@docs/maintainers/retrieval-package-plan.md`:
- Around line 180-181: The bullets at lines mentioning "the one-corpus umbrella
ingestion facade that coordinates `FetchKit` writes and `RAGKit` semantic
indexing" and "umbrella-owned retry scheduling for semantic indexing failures
after a durable corpus write succeeds" understate implemented behavior; update
those two bullets to mark the facade and retry flow as implemented/partially
complete and rephrase to narrow the remaining gap to follow-up lifecycle work
(e.g., indicate that the umbrella ingestion facade and retry scheduling are
shipped, and remaining work is lifecycle/cleanup/edge-case follow-ups). Ensure
you reference the terms "one-corpus umbrella ingestion facade", "FetchKit", and
"RAGKit" in the revised text so readers can map the doc to the code.
In `@README.md`:
- Line 36: Replace the branch-coupled sentence that mentions "`v0.1.2`" and "the
development branch" and references the `SwiftlyFetch` surface with evergreen
wording that avoids specific branch names or versions and instead points readers
to the project's Releases for the current tagged release and status (e.g.,
mention "see Releases for the latest tagged release and status of
SwiftlyFetch"). Ensure the updated line still notes that SwiftlyFetch is
implemented but uses the Releases page as the single source of truth.
In `@Sources/RAGKit/SemanticFingerprints.swift`:
- Around line 98-99: The "double:\(double)" interpolation in the .double case of
SemanticFingerprints is non-deterministic across platforms; replace it with a
deterministic formatter (e.g., use a NumberFormatter configured with en_US_POSIX
or use String(format: Locale(identifier: "en_US_POSIX"), ...) with a chosen
fixed precision/significant-digit setting such as 17 significant digits) so the
string representation is stable across platforms and Swift versions; update the
.double handling to format the Double deterministically rather than relying on
default interpolation.
In `@Sources/SwiftlyFetch/SwiftlyFetchDocumentMapper.swift`:
- Around line 75-83: The normalizedTitle(from record: FetchDocumentRecord)
function currently trims whitespace but leaves internal newlines which can
produce malformed markdown headings; update normalizedTitle to replace all
internal newlines and other line-break sequences with single spaces (e.g., map
"\n", "\r\n", "\r" to " "), then collapse multiple consecutive whitespace into a
single space and trim, returning nil if the result is empty so downstream
templating (heading generation) gets a single-line safe title.
In `@Tests/FetchKitTests/SearchKitFetchIndexTests.swift`:
- Around line 294-301: The test currently asserts the TinyStories result is at
rank 1 by using results.first and specific assertions on it; change this to
search the returned results array for the document with id
"tinystories-row-0-needle" (e.g., use results.first(where: { $0.document.id ==
"tinystories-row-0-needle" }) or XCTAssertTrue(results.contains(where: {
$0.document.id == "..."}))) and then run the matched assertions against that
foundResult (matchedFields contains .body and snippet text contains "needle")
instead of using results.first; keep the same call to
index.search(FetchSearchQuery(...)) and the same assertions but applied to the
located result.
---
Outside diff comments:
In `@AGENTS.md`:
- Line 24: AGENTS.md currently forbids adding persistence but the PR approves
persisted semantic-index state under RAGKit/SwiftlyFetch; update the top-level
guidance to explicitly carve out a semantic-persistence exception by adding a
short clause that permits persisted semantic index state implemented under the
RAGKit/SwiftlyFetch boundary and references the approved pattern, and then
reconcile the other occurrences (around the current guidance at the other two
spots mentioned) so they no longer contradict the exception; ensure the new
wording is concise, mentions RAGKit/SwiftlyFetch by name, and keeps the original
“stop and surface” rule for other scope changes.
---
Nitpick comments:
In `@Sources/RAGKit/CoreDataVectorIndex.swift`:
- Around line 343-372: The search(_ query: SearchQuery, embedding:
EmbeddingVector) method currently fetches all IndexedChunk entities into memory
before applying query.filter and ranking; update the implementation by adding a
clear TODO comment inside CoreDataVectorIndex.search indicating this is a
pragmatic v1 approach and should be optimized later (e.g., use NSFetchRequest
batching, predicate pre-filtering by metadata/document IDs, or integrate an ANN
index) and include which parts to change (the performRead fetch of
EntityName.indexedChunk and the in-memory filtering/ranking pipeline) so future
work knows to move filtering/sorting into the Core Data fetch or replace it with
an ANN-backed query.
In `@Sources/RAGKit/KnowledgeBase`+NaturalLanguage.swift:
- Around line 4-10: Remove the unnecessary async/throwing signature from the
factory: change static func hashingDefault(dimension: Int = 64) async throws ->
KnowledgeBase to a synchronous, non-throwing factory (e.g. static func
hashingDefault(dimension: Int = 64) -> KnowledgeBase) because it only constructs
DefaultChunker, HashingEmbedder, and InMemoryVectorIndex (which have no async or
throwing init); update any callers that currently use try/await to call it
synchronously, and ensure the returned KnowledgeBase construction still uses
DefaultChunker(), HashingEmbedder(dimension:), and InMemoryVectorIndex() as
before.
In `@Tests/RAGKitTests/CoreDataVectorIndexTests.swift`:
- Around line 1-5: The tests currently import XCTest and define final class
CoreDataVectorIndexTests: XCTestCase; replace XCTest usage with Swift Testing by
swapping the import (import SwiftTesting) and refactoring the test file to use
Swift Testing's style: remove the XCTestCase subclass and replace each test
method with a top-level or struct-scoped `@Test` function (or annotate the test
container accordingly) and use the `#expect` macros for assertions and async
expectations; update any uses of XCTest assertions (XCTAssert*,
expectation/wait) to their Swift Testing equivalents so CoreDataVectorIndexTests
and its test functions compile and run under Swift Testing.
In `@Tests/SwiftlyFetchTests/SwiftlyFetchDocumentMapperTests.swift`:
- Around line 40-55: Add a complementary unit test that verifies
SwiftlyFetchDocumentMapper handles a non-empty title when contentType is
.plainText: create a FetchDocumentRecord with title set to a non-blank string
(e.g., "Note title"), body set to plain text, and contentType .plainText, call
SwiftlyFetchDocumentMapper.document(from:), and assert the resulting
document.content includes the "Title: …" prefixed text path and that
metadata["title"] contains the title and metadata["contentType"] equals
.string("plainText"); use a descriptive test name like
mapperPreservesPlainTextBodyWhenTitleIsNonEmpty to mirror the existing test.
In `@Tests/SwiftlyFetchTests/SwiftlyFetchLibraryTests.swift`:
- Around line 482-496: The temporaryDirectory() helper creates unique temp
folders but never removes them; update the test to schedule cleanup by removing
the created directory after test completion: either modify temporaryDirectory()
to register a teardown (e.g., using addTeardownBlock or the test framework's
equivalent) that calls FileManager.default.removeItem(at:) for the returned URL,
or change callers to receive the URL and explicitly remove it in their teardown.
Ensure error handling/logging is present when removing the directory so failures
don't silently pass.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 8e220ad2-537d-41f6-b71d-4acdcf200c1b
📒 Files selected for processing (36)
.github/workflows/validate-repo-maintenance.ymlAGENTS.mdPackage.swiftREADME.mdROADMAP.mdSources/RAGKit/CoreDataVectorIndex.swiftSources/RAGKit/DefaultChunker.swiftSources/RAGKit/HeadingAwareMarkdownChunker.swiftSources/RAGKit/KnowledgeBase+NaturalLanguage.swiftSources/RAGKit/KnowledgeBase.swiftSources/RAGKit/NaturalLanguageEmbedder.swiftSources/RAGKit/SemanticFingerprints.swiftSources/RAGKit/SemanticIndexState.swiftSources/SwiftlyFetch/CoreDataSwiftlyFetchSemanticRetryStore.swiftSources/SwiftlyFetch/SwiftlyFetchDocumentMapper.swiftSources/SwiftlyFetch/SwiftlyFetchLibrary+Persistence.swiftSources/SwiftlyFetch/SwiftlyFetchLibrary.swiftSources/SwiftlyFetch/SwiftlyFetchMutationResult.swiftSources/SwiftlyFetch/SwiftlyFetchSearchAndRetrieve.swiftSources/SwiftlyFetch/SwiftlyFetchSemanticRetry.swiftTests/FetchKitTests/FixtureCorpusQualityTests.swiftTests/FetchKitTests/SearchKitFetchIndexTests.swiftTests/RAGKitTests/CoreDataVectorIndexTests.swiftTests/SwiftlyFetchTestFixtures/GutenbergMiniCorpus.swiftTests/SwiftlyFetchTestFixtures/TinyStoriesMiniCorpus.swiftTests/SwiftlyFetchTests/SwiftlyFetchDocumentMapperTests.swiftTests/SwiftlyFetchTests/SwiftlyFetchLibraryTests.swiftdocs/maintainers/fixture-corpus.mddocs/maintainers/hybrid-search-persistence-plan.mddocs/maintainers/retrieval-package-plan.mddocs/maintainers/swiftlyfetch-facade-plan.mdscripts/repo-maintenance/config/release.envscripts/repo-maintenance/lib/common.shscripts/repo-maintenance/release.shscripts/repo-maintenance/release/30-push-release.shscripts/repo-maintenance/release/40-github-release.sh
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 646dd9ea97
ℹ️ 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".
|
|
||
| review_decision="$(gh pr view "$pr_number" --json reviewDecision --jq '.reviewDecision // ""')" | ||
| comment_count="$(gh pr view "$pr_number" --json comments,reviews --jq '([.comments[]?, .reviews[]?] | length)')" | ||
| comment_count="$(gh pr view "$pr_number" --json comments,reviews --jq '([.comments[]?, (.reviews[]? | select(.state == "COMMENTED"))] | length)')" |
There was a problem hiding this comment.
Include approved review comments in PR comment gate
The comment gate now counts only issue comments and reviews whose state is COMMENTED, so reviews submitted as APPROVED with a non-empty review body are ignored. In this workflow, that lets release.sh proceed without --review-comments-addressed even when a reviewer left actionable review comments alongside approval, which contradicts the script’s own “review or discussion comments” stop condition and can cause releases to bypass intended comment triage.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0f6c498bb3
ℹ️ 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".
|
|
||
| while :; do | ||
| last_state="$(gh pr checks "$pr_number" --json name,state,workflow --jq 'map(.name + ":" + .state) | join(", ")' 2>/dev/null || printf 'no checks reported')" | ||
| check_count="$(gh pr checks "$pr_number" --json name,state,workflow --jq 'length' 2>/dev/null || printf '0')" |
There was a problem hiding this comment.
Treat pending PR checks as discovered
wait_for_initial_pr_checks currently appends a fallback printf '0' when gh pr checks ... --jq 'length' exits non-zero, but gh pr checks documents exit code 8 for pending checks. In that common state, the command can output a valid length and still exit 8, so the fallback corrupts check_count (e.g., "3\n0"), the numeric guard resets it to 0, and the loop can incorrectly timeout after 120s even though checks were already discovered. This can make standard/deferred release runs fail on normal CI startup latency.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fea5f2d32b
ℹ️ 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".
| merge_pr "$pr_number" | ||
| fast_forward_base_branch | ||
| create_release_tag | ||
| push_release_tag |
There was a problem hiding this comment.
Keep post-merge release steps resumable
Move the tag/release creation before the branch is merged, or relax the branch-context guard for resume paths. In this flow, merge_pr runs before create_release_tag/push_release_tag/create_github_release, and gh pr merge --delete-branch is documented to delete the local and remote branch; if any post-merge step fails (e.g., transient GitHub/API failure), rerunning release.sh is blocked by ensure_branch_release_context because the script has already switched to main and the release branch may be gone. That leaves a merged PR without a tag/release and no straightforward recovery path through the same command.
Useful? React with 👍 / 👎.
Release
rag/persist-vector-indexmainupdates behind pull request review and CIv0.2.0will be created after CI and the review-comment gate pass, so failed or still-discussed release candidates do not get taggedReview Loop
Before merge and tagging,
scripts/repo-maintenance/release.shwatches CI and stops on review comments unless the maintainer has already addressed or resolved them and reruns with--review-comments-addressed.Summary by CodeRabbit
New Features
Tests
Documentation
Chores