Skip to content

refactor(cli): improve index jobs and query coverage UX - #234

Merged
Moskize91 merged 10 commits into
mainfrom
refactor/index-job-artifacts
Aug 4, 2026
Merged

refactor(cli): improve index jobs and query coverage UX#234
Moskize91 merged 10 commits into
mainfrom
refactor/index-job-artifacts

Conversation

@Moskize91

Copy link
Copy Markdown
Contributor

Summary

  • keep index artifact build jobs queued but make build output/help explicit about queued work and watch commands
  • make queued job resume idempotent and fix resume wording
  • clarify Summary Artifact coverage in inspect output and JSON help
  • add --skip-unindexed coverage warnings to search, related, and evidence outputs across text/json/jsonl

Validation

  • pnpm test:run test/cli/archive/related.test.ts test/cli/archive/evidence-pack.test.ts test/cli/archive/query.test.ts test/cli/archive/object.test.ts test/cli/archive/chapter.test.ts test/cli/queue.test.ts test/core/api/build-queue.test.ts packages/cli/src/args/help.test.ts
  • pnpm exec tsc --noEmit
  • pnpm run lint:fix
  • git diff --check

Notes

  • SQL_READONLY, KG estimate, and worker autostart are intentionally deferred.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added --skip-unindexed for archive and library searches, related queries, evidence, and index synchronization.
    • Searches can target chapters with current index coverage while excluding uncovered chapters.
    • Added warnings across text, JSON, and JSONL output for indexed-only searches.
    • Chapter index builds now report queued status and can be monitored by job ID.
    • Improved index artifact validation and recovery during queued builds.
  • Documentation

    • Updated help with indexed-search behavior, option restrictions, and job lifecycle guidance.
    • Clarified summary artifact coverage in archive inspection reports.

Walkthrough

This change adds --skip-unindexed support for archive and library queries. It scopes index checks and retrieval to chapters with current queryable artifacts, preserves the option across continuation cursors, and emits warnings in text, JSON, and JSONL output. It adds validated JSONL exchange for queued index artifacts, separates serial cleanup operations, centralizes word counting, repairs stale sentence counts during schema upgrades, and updates queued job handling and inspection output.

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant ArchiveCommand
  participant ArchiveIndex
  participant Retrieval
  participant Output
  CLI->>ArchiveCommand: Parse --skip-unindexed
  ArchiveCommand->>ArchiveIndex: Resolve queryable chapters
  ArchiveCommand->>Retrieval: Execute scoped query
  Retrieval-->>Output: Return paginated results
  Output-->>CLI: Emit indexed-only warning and results
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title follows the required format and accurately summarizes the CLI index-job and query-coverage changes.
Description check ✅ Passed The description directly covers the queued index jobs, resume behavior, inspect output, and skip-unindexed warnings in the changeset.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch refactor/index-job-artifacts

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 9

🧹 Nitpick comments (1)
test/cli/archive/object.test.ts (1)

231-234: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a JSON assertion for help.summaryCoverage. The JSON test does not check this field or its explanation.

🤖 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 `@test/cli/archive/object.test.ts` around lines 231 - 234, Add a JSON-output
assertion in the relevant archive CLI test to verify help.summaryCoverage and
its explanatory text, alongside the existing summary coverage assertions. Use
the established archiveMockState JSON output and preserve the current
text-output checks.
🤖 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 `@packages/cli/src/args/parse.ts`:
- Around line 172-174: Update the argument parser configuration around the
"skip-unindexed" option so it is accepted only by query parsers and explicitly
rejected by non-query commands such as gc. Add negative tests covering
representative non-query commands and verify they fail when passed
--skip-unindexed.

In `@packages/cli/src/commands/archive-output/write/evidence.ts`:
- Line 71: Emit the JSONL skip-unindexed warning only on the first page of each
--all command. In packages/cli/src/commands/archive-output/write/evidence.ts:71,
pass the first-page state into writeEvidenceWithoutContinuation; update
writeFindHitsWithoutContinuation in
packages/cli/src/commands/archive-output/write/find.ts:110-121 and
writeListWithoutContinuation in
packages/cli/src/commands/archive-output/write/list.ts:102-113 to accept and
honor a suppression flag for subsequent JSONL pages.

In `@packages/cli/src/commands/queue/worker.ts`:
- Around line 359-366: Update the index-fts flow in the worker to pass
chapterTitles, summarySentences, chunks, and mentions from the chapter snapshot
to createFtsIndexArtifactInput alongside sentences, preserving all available FTS
row kinds. In test/cli/queue.test.ts:1049, extend the assertion to verify the
available non-source rows.

In `@packages/core/src/retrieval/index-artifact/output.ts`:
- Around line 23-36: The embedding metadata contracts are inconsistent across
createEmbeddingIndexArtifactInput, createOutputManifest, readNumberMetadata, and
manifestSchema. Make identity optional when the provider has no identity,
enforce nonnegative integer dimensions while reading and writing metadata, and
add a round-trip test covering a provider without identity.
- Around line 70-90: Update the stream-writing flow around createWriteStream and
closeWritableStream to apply backpressure: await the stream’s drain event
whenever write() returns false before emitting the next record. Add error
propagation for the stream so failures during writes or closing reject the
operation, while preserving manifest, lexical-row, segment output, and
guaranteed cleanup.

In `@packages/core/src/retrieval/query/continuation-cursor/payload.ts`:
- Line 125: Update getPayloadOptionalBoolean and its callers in the cursor
payload parsing flow so the boolean is assigned to the requested key, preserving
skipUnindexed and preventing it from overwriting backlinks. Add round-trip
coverage for search, evidence, and related cursors to verify skipUnindexed
survives persistence and resumption.

In `@packages/core/src/runtime/jobs/jobs.ts`:
- Around line 344-356: Make the queued-state check and paused-to-queued
transition atomic in the resume flow around requireBuildJobById and the
transition helper, so concurrent callers cannot both observe paused and cause
one to fail. Prefer keeping both operations on the same database transaction;
alternatively, make the transition helper treat an already-queued job as an
idempotent no-op without adding another event. Add a regression test covering
concurrent resume calls.

In `@packages/core/src/storage/schema-upgrade/index.ts`:
- Around line 335-367: Replace the all-stream textCache in the row-processing
loop with state for only the current stream, reloading when the stream name or
chapterId changes. Represent a loaded-but-missing stream explicitly so
subsequent rows for that stream are skipped without rereading it, while
preserving sentence extraction for available text and allowing previously held
buffers to be released.

In `@packages/core/src/utils/text-word-count.ts`:
- Around line 2-23: Update countTextWords and WORD_CHARACTER_PATTERN so Unicode
combining Mark characters continue an already active word without starting one
when inWord is false; preserve existing Han-character and separator behavior.
Add regression coverage for decomposed text such as e\u0301clair, verifying it
counts as one word and prevents incorrect words_count updates.

---

Nitpick comments:
In `@test/cli/archive/object.test.ts`:
- Around line 231-234: Add a JSON-output assertion in the relevant archive CLI
test to verify help.summaryCoverage and its explanatory text, alongside the
existing summary coverage assertions. Use the established archiveMockState JSON
output and preserve the current text-output checks.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3eb74a27-b7b8-4328-a281-fae85fc67464

📥 Commits

Reviewing files that changed from the base of the PR and between e456fa9 and 2cdb4f1.

📒 Files selected for processing (82)
  • packages/cli/src/args/archive-index.test.ts
  • packages/cli/src/args/archive.test.ts
  • packages/cli/src/args/archive.ts
  • packages/cli/src/args/help.test.ts
  • packages/cli/src/args/parse.ts
  • packages/cli/src/args/types.ts
  • packages/cli/src/args/uri/archive-objects.ts
  • packages/cli/src/commands/archive-command/chapter.ts
  • packages/cli/src/commands/archive-command/index.ts
  • packages/cli/src/commands/archive-command/inspect.ts
  • packages/cli/src/commands/archive-command/run/next.ts
  • packages/cli/src/commands/archive-command/run/options.ts
  • packages/cli/src/commands/archive-command/search-index.ts
  • packages/cli/src/commands/archive-output/object/cursor.ts
  • packages/cli/src/commands/archive-output/object/objects.ts
  • packages/cli/src/commands/archive-output/object/types.ts
  • packages/cli/src/commands/archive-output/write/evidence.ts
  • packages/cli/src/commands/archive-output/write/find.ts
  • packages/cli/src/commands/archive-output/write/list.ts
  • packages/cli/src/commands/archive-output/write/warnings.ts
  • packages/cli/src/commands/queue/output.ts
  • packages/cli/src/commands/queue/worker.ts
  • packages/core/data/help/commands/library.jinja
  • packages/core/data/help/commands/predicate.jinja
  • packages/core/data/help/commands/uri.jinja
  • packages/core/data/help/topics/library.jinja
  • packages/core/data/help/topics/readiness.jinja
  • packages/core/data/help/topics/uri.jinja
  • packages/core/src/api/chapter/generate.ts
  • packages/core/src/api/chapter/manage.ts
  • packages/core/src/document/directory/core.ts
  • packages/core/src/document/directory/index-artifact-invalidation.test.ts
  • packages/core/src/document/directory/serial-cleanup.ts
  • packages/core/src/document/directory/types.ts
  • packages/core/src/document/fragments/sentence.ts
  • packages/core/src/document/text-streams/sentence.ts
  • packages/core/src/graph/knowledge-build/commit.ts
  • packages/core/src/graph/reading-build/artifact.ts
  • packages/core/src/index.ts
  • packages/core/src/library/query.ts
  • packages/core/src/library/search-index.ts
  • packages/core/src/library/search-query.ts
  • packages/core/src/retrieval/index-artifact/build.test.ts
  • packages/core/src/retrieval/index-artifact/index.ts
  • packages/core/src/retrieval/index-artifact/output.ts
  • packages/core/src/retrieval/query/archive-view/evidence.ts
  • packages/core/src/retrieval/query/archive-view/index-state.test.ts
  • packages/core/src/retrieval/query/archive-view/index-state.ts
  • packages/core/src/retrieval/query/archive-view/index.ts
  • packages/core/src/retrieval/query/archive-view/related/core.ts
  • packages/core/src/retrieval/query/archive-view/related/entity.ts
  • packages/core/src/retrieval/query/archive-view/related/query.ts
  • packages/core/src/retrieval/query/archive-view/search/core.ts
  • packages/core/src/retrieval/query/archive-view/search/hydration.ts
  • packages/core/src/retrieval/query/archive-view/source-evidence/core.ts
  • packages/core/src/retrieval/query/archive-view/text-streams.ts
  • packages/core/src/retrieval/query/archive-view/types.ts
  • packages/core/src/retrieval/query/continuation-cursor/payload.ts
  • packages/core/src/retrieval/query/continuation-cursor/types.ts
  • packages/core/src/retrieval/query/index.ts
  • packages/core/src/retrieval/query/search-cache/sessions.ts
  • packages/core/src/retrieval/query/search-cache/store.ts
  • packages/core/src/runtime/jobs/jobs.ts
  • packages/core/src/storage/schema-upgrade/index.ts
  • packages/core/src/text/reader/segment/intl-segmenter.ts
  • packages/core/src/text/serial/generation.ts
  • packages/core/src/text/serial/source.ts
  • packages/core/src/text/source/epub/content.ts
  • packages/core/src/utils/text-word-count.test.ts
  • packages/core/src/utils/text-word-count.ts
  • test/cli/archive/chapter.test.ts
  • test/cli/archive/evidence-pack.test.ts
  • test/cli/archive/mock.ts
  • test/cli/archive/object.test.ts
  • test/cli/archive/query.test.ts
  • test/cli/archive/related.test.ts
  • test/cli/queue.test.ts
  • test/core/api/build-queue.test.ts
  • test/core/api/knowledge-graph-build.test.ts
  • test/core/library/query.test.ts
  • test/core/retrieval/query/search-cache.test.ts
  • test/core/storage/schema-upgrade/index.test.ts
💤 Files with no reviewable changes (1)
  • packages/core/src/text/serial/generation.ts

Comment thread packages/cli/src/args/parse.ts
Comment thread packages/cli/src/commands/archive-output/write/evidence.ts Outdated
Comment thread packages/cli/src/commands/queue/worker.ts
Comment thread packages/core/src/retrieval/index-artifact/output.ts
Comment thread packages/core/src/retrieval/index-artifact/output.ts
Comment thread packages/core/src/retrieval/query/continuation-cursor/payload.ts
Comment thread packages/core/src/runtime/jobs/jobs.ts Outdated
Comment thread packages/core/src/storage/schema-upgrade/index.ts Outdated
Comment thread packages/core/src/utils/text-word-count.ts
@Moskize91 Moskize91 changed the title Refactor index artifact jobs and query coverage UX refactor(cli): improve index jobs and query coverage UX Aug 4, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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 `@packages/core/src/retrieval/index-artifact/output.ts`:
- Around line 407-445: Update writeIndexArtifactOutput so its stream error
listener remains installed after settle rejects a failed write, rather than
being removed by cleanup; keep that listener through closeWritableStream
completion and route stream errors through the existing rejection path. Add a
regression test using a failing Writable to verify the write callback error is
rejected without an unhandled stream error.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aee6b311-719f-4fc2-af3a-56219b23898d

📥 Commits

Reviewing files that changed from the base of the PR and between 145b569 and 4a6d7e8.

📒 Files selected for processing (17)
  • packages/cli/src/args/gc.test.ts
  • packages/cli/src/args/parse.ts
  • packages/cli/src/commands/archive-output/write/evidence.ts
  • packages/cli/src/commands/archive-output/write/find.ts
  • packages/cli/src/commands/archive-output/write/list.ts
  • packages/cli/src/commands/queue/worker.ts
  • packages/core/src/retrieval/index-artifact/build.test.ts
  • packages/core/src/retrieval/index-artifact/output.ts
  • packages/core/src/retrieval/query/continuation-cursor/payload.test.ts
  • packages/core/src/retrieval/query/continuation-cursor/payload.ts
  • packages/core/src/runtime/jobs/jobs.ts
  • packages/core/src/storage/schema-upgrade/index.ts
  • packages/core/src/utils/text-word-count.test.ts
  • packages/core/src/utils/text-word-count.ts
  • test/cli/archive/object.test.ts
  • test/cli/queue.test.ts
  • test/core/api/build-queue.test.ts
🚧 Files skipped from review as they are similar to previous changes (11)
  • packages/cli/src/commands/archive-output/write/find.ts
  • packages/core/src/runtime/jobs/jobs.ts
  • test/cli/archive/object.test.ts
  • packages/cli/src/commands/archive-output/write/evidence.ts
  • test/cli/queue.test.ts
  • packages/core/src/retrieval/query/continuation-cursor/payload.ts
  • packages/cli/src/commands/archive-output/write/list.ts
  • packages/core/src/storage/schema-upgrade/index.ts
  • packages/cli/src/commands/queue/worker.ts
  • packages/core/src/utils/text-word-count.ts
  • packages/core/src/utils/text-word-count.test.ts

Comment thread packages/core/src/retrieval/index-artifact/output.ts Outdated
@Moskize91

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (2)
packages/core/src/retrieval/index-artifact/build.test.ts (1)

325-357: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the regression assertion explicit.

The test relies on the trailing await new Promise((resolve) => setImmediate(resolve)) to surface an unhandled "error" event. Whether that failure is reported depends on the test runner configuration for unhandled errors. The test can pass even if the implementation removes its "error" listener too early.

Add a direct assertion instead. For example, record this.listenerCount("error") inside the fixture at emit time and assert it is greater than zero.

♻️ Proposed fixture change
 class CallbackThenStreamErrorWritable extends Writable {
   readonly `#error` = new Error("write failed");
+  public errorListenerCountAtEmit = -1;
 
   public override _final(callback: (error?: Error | null) => void): void {
     setTimeout(() => callback(), 10);
   }
 
   public override _write(
     _chunk: unknown,
     _encoding: BufferEncoding,
     callback: (error?: Error | null) => void,
   ): void {
     callback(this.#error);
     setImmediate(() => {
+      this.errorListenerCountAtEmit = this.listenerCount("error");
       this.emit("error", this.#error);
     });
   }
 }

Then assert in the test:

await new Promise((resolve) => setImmediate(resolve));
expect(stream.errorListenerCountAtEmit).toBeGreaterThan(0);
🤖 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 `@packages/core/src/retrieval/index-artifact/build.test.ts` around lines 325 -
357, Update CallbackThenStreamErrorWritable to record
this.listenerCount("error") immediately before emitting the delayed error,
expose that recorded count to the test, and replace the trailing timing-only
wait with an assertion that errorListenerCountAtEmit is greater than zero after
writeIndexArtifactOutputToStream rejects.
packages/core/src/retrieval/index-artifact/output.ts (1)

455-479: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Bound the wait for "close".

closePromise never resolves if the stream does not emit "close". A Writable created with emitClose: false produces an unresolved await here. writeIndexArtifactOutputToStream is exported, so a caller can pass such a stream and the queue worker then hangs without an error.

Consider resolving the close wait when the stream reports closed or destroyed after end() completes, instead of requiring the event.

🤖 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 `@packages/core/src/retrieval/index-artifact/output.ts` around lines 455 - 479,
Update writeIndexArtifactOutputToStream’s close-wait logic so completion does
not depend solely on the "close" event: after stream.end() completes, resolve
the wait when the stream reports closed or destroyed, including streams
configured with emitClose: false. Preserve error propagation through
streamErrors.race and the existing early handling for already-destroyed streams.
🤖 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.

Nitpick comments:
In `@packages/core/src/retrieval/index-artifact/build.test.ts`:
- Around line 325-357: Update CallbackThenStreamErrorWritable to record
this.listenerCount("error") immediately before emitting the delayed error,
expose that recorded count to the test, and replace the trailing timing-only
wait with an assertion that errorListenerCountAtEmit is greater than zero after
writeIndexArtifactOutputToStream rejects.

In `@packages/core/src/retrieval/index-artifact/output.ts`:
- Around line 455-479: Update writeIndexArtifactOutputToStream’s close-wait
logic so completion does not depend solely on the "close" event: after
stream.end() completes, resolve the wait when the stream reports closed or
destroyed, including streams configured with emitClose: false. Preserve error
propagation through streamErrors.race and the existing early handling for
already-destroyed streams.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0d8d7ccc-bf85-425b-9830-6afae881777d

📥 Commits

Reviewing files that changed from the base of the PR and between 4a6d7e8 and 1f0ae24.

📒 Files selected for processing (2)
  • packages/core/src/retrieval/index-artifact/build.test.ts
  • packages/core/src/retrieval/index-artifact/output.ts

@Moskize91
Moskize91 merged commit 830c8f4 into main Aug 4, 2026
4 checks passed
@Moskize91
Moskize91 deleted the refactor/index-job-artifacts branch August 4, 2026 07:31
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.

1 participant