Skip to content

🦄 new(pipeline): entry body model (§6.0) - #36

Merged
UniquePixels merged 71 commits into
v2from
spec/entry-body-model
Aug 6, 2026
Merged

🦄 new(pipeline): entry body model (§6.0)#36
UniquePixels merged 71 commits into
v2from
spec/entry-body-model

Conversation

@UniquePixels

@UniquePixels UniquePixels commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

Lands the complete Entry Body Model (§6.0) implementation — all 17
tasks of docs/superpowers/plans/2026-07-11-entry-body-model.md,
the migration prerequisite for migrate.ts.

  • Rule modules under admin/pipeline/body/: source reader, citation
    detector, gloss-head rejoin, grammar index, label normalization,
    lettered a)/b)/c) splitter (incl. Task 15 italic-marker classes),
    B12 form-section splitter, conservative unit segmentation — each
    unit-tested against a committed fixture corpus (12 edge-class files).
  • Formal JSON Schema (B11, draft 2020-12) with fixture validation.
  • Full-corpus dry-run over all 32,512 entries: rejoin / units /
    lettered / form-section round-trips all 32,512/32,512; 6 label
    quarantines; 0 grammar quarantines.
  • Migration dry-run (Task 16): the eight §6.0 review-approved repair
    passes over the healed corpus — 0 label quarantines, 0 empty binyan
    forms, 0 schema failures, 0 unresolved orphans after repair.
  • Review-doc protection (Task 17): bun body:review preserves the
    maintainer's hand-recorded 2026-08-05 decisions on regen.
  • Eyes-on evidence in docs/v2/ (census, dry-run, migration,
    review packages) with maintainer decisions recorded.

Pre-PR review battery

  • bun qa green: biome format + lint --error-on-warnings, 212 tests,
    tsc (exactOptionalPropertyTypes).
  • extract.ts --check: all fixture files match extraction.
  • Local CodeRabbit review (base v2): 25 findings triaged; fixes in
    64fab47 (sample-rid catch-up, repairs write-back guard, own-key
    vocab lookup, tsc guard in review.ts, lint hoists, stale doc numbers).
  • Semgrep (--config auto): 3 detect-non-literal-regexp warnings —
    accepted; patterns derive from the closed marker vocabulary and
    escapeRegExp-ed reviewed refs in an offline pipeline over trusted
    committed data.
  • SonarQube: not configured for this repo (no sonar-project.properties).

Review findings intentionally not applied

  • cite.ts trailing-unclosed-anchor early return: deliberate, pinned by
    test, and measured zero occurrences corpus-wide.
  • Maintainer-authored review-doc content (typos in 02-orphan-refs.md
    note, 01-broken-sequences.md Q00997 classification, 03's Sefaria
    claim wording): left untouched — they are hand-recorded decision
    records; flagged for the maintainer instead.
  • Plan-doc history (missing Task 14 section, tasks.json wording): the
    tracker's outcome fields already record reality.

Notes

  • Fixture *.jsonl files are committed entry snapshots (hence
    bulk-data-ok).
  • Machine reports stay gitignored (D2); only human summaries in
    docs/v2/ are committed.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a structured Entry Body Model for dictionary entries, citations, grammar, labels, senses, forms, and definition units.
    • Added full-corpus census, dry-run, migration verification, review-report, and schema-validation workflows.
    • Added representative dictionary fixtures for complex entry structures and edge cases.
  • Bug Fixes

    • Added corrections for malformed numbering, citations, labels, references, form sections, and grammatical data.
  • Documentation

    • Added design specifications, migration results, census reports, validation summaries, and maintainer review materials.

UniquePixels and others added 30 commits July 12, 2026 14:50
Resolves the data-architecture spec's 6.0 prerequisite: ideal-form-
first schema (maintainer directive) with prose collapse + typed
grammar index, senses as {label, gloss, units[]} trees, stems for
binyan sections. Drops refs (98.1k items measured 99.97% derivable
from inline citations) and quotes (vestigial Sefaria importer
artifact, unused even by Sefaria). Import mapping with per-region
confidence + fallbacks, census/fixture plan (72 broken sense
sequences, ibid classes, orphan refs), byte round-trip gates.

Also ignores .superpowers/ (brainstorm scratch) and Word lock files.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Maintainer review round 1: merge <ref rid>/<cite ref> into one
<cite ref> tag (value is rid or canonical Sefaria ref; validator
and app router dispatch on the unambiguous rid pattern); record the
dual-destination routing requirement (internal primary link +
Sefaria arrow icon, both derived per D7); commit to a formal JSON
Schema as the documented generic spec (B11).

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
13-task plan for the 6.0 prerequisites: source reader, citation
detector, corpus census, fixture corpus, five TDD parse rules with
byte round-trip gates, formal JSON Schema (validator dep deferred
to maintainer per CP-2a), read-only full-corpus dry-run, maintainer
eyes-on review gate, and parent-spec amendment PR.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Rename mislabeled linesOf test (it asserts blanks are yielded, not
skipped) and document the linesOf export in the module README —
both from Task 1 quality re-review.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Add hadLeadingSlash and malformed to CitationHit. When an
anchor's href quote is never closed, findCitations now flags
it instead of silently swallowing the following valid anchor
and cross-attributing its data-ref (D00478, J00597). Also
short-circuits when a string has no closing </a> at all.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
findNextBoundary's nested-open-tag path silently dropped the
outer anchor whenever a valid open tag's own </a> was missing
and a following refLink open tag was found first. Corpus-wide
this fired 474 times: 471 are the benign Sefaria nested-
duplicate quirk (outer/inner share an identical href), but 3
were genuine citation losses with no hit and no flag at all
(D00478, J00597, J00603).

Now every such open tag is emitted as a malformed hit whose
span covers just the open tag, then scanning resumes from the
nested tag as before. Consumers can mechanically tell the two
classes apart: adjacent hits with an identical href are the
benign duplicate quirk.

Also softened the stale O(N²)-on-blobs doc-comment: measured
linear in practice after the earlier rewrite.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Mirror grammar.ts's parseMarker convention: quarantine now
returns {unknown: raw} instead of bare null, so the raw
sense.number token survives for reporting. Narrows the letter
class from [A-Za-z] to [a-z] (corpus has zero letter labels;
lettered.ts's synthesized sub-item labels are lowercase-only).
Updates README.md's module table — the listed modules are all
implemented now, only dry-run.ts/review.ts remain planned.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Task 11 review follow-up: prove evaluateRoundTrip actually
catches corruption instead of only passing clean fixtures, and
note why trace.problems goes unused on the run path.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
PR #34 widened the biome pipeline override to subdirectories and
sanctioned snake_case type properties, making the per-field
suppressions in types.ts unused (warning-level under qa:lint).

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Repair passes landed in 43e2afc; gates green, three rows
deferred to eyes-on (D00470, K00081, R00519) per the report.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Parent-spec amendments landed as PR #35 (doc/body-model-amendments,
docs-only to main): four edit groups, changelog row, forward links
resolving on spec-branch merge.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Census has long met its acceptance (report sections, unit-tested
classifiers, docs/v2/body-census.md with measured numbers; verify
command re-run clean 2026-08-05); status was stale in_progress.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
CP-1 passed 2026-07-10 and is recorded verbatim on main
(2026-07-03-v2-overhaul-design.md §7, PR #33). All acceptance
criteria re-verified: changelog row present via
'git show origin/main:...' grep, evidence and restart answer
recorded, Phase 2 proceeded. Status was stale pending.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Pre-PR local CodeRabbit review of the full branch diff (base v2),
25 findings triaged, each verified against code before acting:

- dry-run-report: FIXTURE_SAMPLE_RIDS catches up with Task 15's
  four lettered fixture rids (schema sample 129→133; surfaces a
  4th empty-binyan-form failure, same known Finding 3 root cause)
- repairs: cite-escape no longer materializes definition:"" onto
  grammar-only senses; write-back only on change
- grammar: own-key VOCAB lookup (inherited members can't match)
- review: explicit guard for docs[name] fixes pre-existing tsc
  error under noUncheckedIndexedAccess
- lint gate: hoist per-call regexes, reasoned noDelete suppression
  (bun qa now fully green: format, lint -w, 212 tests, tsc)
- form-sections test: no-collateral sweep now includes
  label-quarantines + numbering-extras classes
- body-dryrun doc: Finding 6 table was stale (pre-Task-15) vs the
  current headline; both now match the regenerated report; Finding
  3/7 renumbered totals re-anchored
- fixtures README: add missing plural/form-sections rows; note
  A00043's slash-less href; stale plural.ts comment refs updated
- design doc: status Draft → Reviewed (2026-08-05 §6.0 review)

Skipped (with reasons, see PR notes): cite.ts trailing-unclosed-
anchor change (deliberate pinned fast-path, zero corpus incidence
measured); maintainer-authored review-doc content edits; task 9
status revert (evidence recorded in prior commit).

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
@UniquePixels UniquePixels added the bulk-data-ok Large data-file changes are intentional; skip line-by-line data review label Aug 6, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
jastrow fb08458 Aug 06 2026, 02:51 PM

@socket-security

socket-security Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedajv@​8.20.09910010084100

View full report

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds the Entry Body Model pipeline. It includes source readers, parsers, census tools, deterministic fixtures, schema validation, dry-run verification, migration repairs, maintainer review documents, reports, and CLI scripts.

Changes

Entry Body Model pipeline

Layer / File(s) Summary
Source contracts and citation handling
admin/pipeline/body/types.ts, admin/pipeline/body/source.ts, admin/pipeline/body/cite.ts, admin/pipeline/body/rejoin.ts
Adds shared source and body types, chunk-safe JSONL reading, citation-anchor detection, and gloss-head rejoining.
Body parsing and round-trip rules
admin/pipeline/body/grammar.ts, labels.ts, lettered.ts, form-sections.ts, units.ts, census.ts
Adds grammar and label parsing, lettered and form-section splitting, citation-unit segmentation, and exact reconstruction tests.
Corpus census, fixtures, and validation
admin/pipeline/body/census.ts, admin/pipeline/body/fixtures/*, admin/pipeline/body/dry-run*.ts, admin/pipeline/schema/*
Adds corpus classifiers, deterministic fixtures, normalized body construction, round-trip gates, schema validation, and dry-run reports.
Migration repairs and maintainer review
admin/pipeline/body/repairs.ts, migrate-dry.ts, review.ts, docs/v2/*, docs/specs/*, docs/superpowers/*
Adds approved repairs, migration verification, guarded review-document generation, design records, measured reports, and implementation plans.
Project wiring
.gitignore, package.json, biome.json
Adds pipeline scripts, the AJV development dependency, report exclusions, and the admin/pipeline console-lint override.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • UniquePixels/jastrow#25: Supplies the source snapshot and pipeline layout consumed by the body-model tooling.
  • UniquePixels/jastrow#28: Defines the Entry Body Model architecture, schema, citation rules, and migration workflow implemented here.

Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Docstring Coverage ❌ Error Docstring coverage is 55.80% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the new pipeline Entry Body Model implementation, which is the main change in the pull request.
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.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch spec/entry-body-model

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Comment thread admin/pipeline/body/census.ts Fixed
Comment thread admin/pipeline/body/census.ts Fixed
Comment thread admin/pipeline/body/review.ts Fixed
Resolves the three CodeQL high alerts on PR #36:

- stripTags (census.ts, review.ts): strip to a fixed point so
  fragments re-composed by one pass can't survive
  (js/incomplete-multi-character-sanitization). Corpus-verified
  byte-identical to the single-pass version over all 32,512
  entries (0 differing strings), so no census/report drift.
- FORM_SECTION_PATTERNS (census.ts): escape every regex special,
  not just dots (js/incomplete-sanitization). No-op for the
  closed marker vocabulary; future markers safe by construction.

bun qa green; body:census and body:dry-run outputs unchanged.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
The one numbering-gap row of 39 absent from every repairs.ts
bucket (found via PR #36 review). Source verified: senses 1,2,4
with '—3) to save' in-text at the end of sense 2 — the same
swallowed-marker shape as Q00547. Listed as no-byte-change for
this PR's bookkeeping; the maintainer has since ruled the whole
swallowed-marker class must be structurally split — that lands
as its own fixtured rule (follow-up task), which will supersede
CONFIRMED_NO_CHANGE.

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
@UniquePixels

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 6, 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.

Actionable comments posted: 27

🤖 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 `@admin/pipeline/body/census.ts`:
- Around line 86-89: Update the JSDoc comment describing the phantom-sense
check, replacing the `*is*` emphasis markers with backticks or plain wording so
it no longer triggers useSingleJsDocAsterisk; preserve the surrounding
explanation.
- Line 63: Update the SENSE_NUMBER regular expression to use a named capture
group, then adjust its consumers to read the captured value through the match
result’s groups property. Preserve the existing numeric extraction behavior and
follow the named-group pattern used elsewhere in census.ts and labels.ts.
- Around line 444-506: Reduce cognitive complexity in censusEntry by extracting
the walkSenses per-sense processing—including definition counting, lettered and
plural detection, form-marker collection, and citation/boundary/ibid
tallying—into a helper. Have the helper return the per-entry flags and collected
form markers, then leave censusEntry responsible only for applying those results
to the accumulator and retaining the existing sequence and opener handling.

In `@admin/pipeline/body/cite.ts`:
- Around line 89-92: Update findCitations in admin/pipeline/body/cite.ts at
lines 89-92 to gate the fast path on the presence of class="refLink" rather than
</a>, so open tags are scanned without closing tags; at lines 114-118, push the
current hit with malformed: true before breaking when no closing content follows
the open tag, matching the nested-open handling.

In `@admin/pipeline/body/dry-run-verify.ts`:
- Line 166: Update the condition in the dry-run verification logic to use an
explicit length comparison for sibling.units, replacing the implicit non-empty
check while preserving the existing gloss comparison.

In `@admin/pipeline/body/dry-run.test.ts`:
- Around line 179-215: The test file exceeds the per-file line budget and the
round-trip sweep is too complex; split the four `evaluateRoundTrip` canary
suites out of the current `buildBody round-trip` block into a separate
`dry-run-verify.test.ts`. In the remaining test, update the loop that builds
`mismatches` around `loadFixture`, `buildTrace`, and `evaluateRoundTrip` to use
a small table-driven list of the four gate checks (`rejoin`, `units`,
`lettered`, `formSection`) so the per-entry validation stays the same while
lowering cognitive complexity.

In `@admin/pipeline/body/dry-run.ts`:
- Around line 188-197: Update buildStem to stop defaulting grammar.verbal_stem
to an empty string. Enforce a loud failure or record the missing verbal_stem for
quarantine at composition time, following the existing policy in repairs.ts, and
ensure no schema-invalid BodyStem is emitted.

In `@admin/pipeline/body/fixtures/extract.ts`:
- Around line 15-232: Resolve the noExcessiveLinesPerFile diagnostic for the RID
catalog in CLASSES while keeping the catalog reviewable: either move the
reviewed catalog data into an appropriate separate data file and preserve its
existing structure, or add a narrowly scoped Biome suppression around this
catalog with a clear reason. Do not alter the RID memberships or categories.

In `@admin/pipeline/body/grammar.test.ts`:
- Around line 56-58: Update the parseMarker census coverage setup around
describe.skipIf to avoid relying on an unpinned Bun-specific API: either pin the
repository’s Bun runtime to a compatible version or replace describe.skipIf with
a supported equivalent such as it.skipIf or a conditional guard, while
preserving the test’s behavior when REPORT_PATH is absent.

In `@admin/pipeline/body/labels.test.ts`:
- Around line 133-141: Update the corpus sweep test around readSourceEntries and
tallyLabels to tally entries inside the for-await loop instead of collecting
them in an entries array. Preserve the existing distinct-label assertions and
keep tallyLabels involved, adapting its input only if needed to support
streaming.

In `@admin/pipeline/body/lettered.test.ts`:
- Around line 10-11: Update the docstring describing the fixture set near the
test fixture declaration to state that it contains 9 entries instead of 5,
keeping it consistent with the split definitions and the assertion in the test.

In `@admin/pipeline/body/migrate-dry.ts`:
- Around line 164-195: Contain failures from applyRepairs within processEntry by
catching the per-entry error, recording the failure in the report, and allowing
the corpus walk to continue; preserve the loud-failure policy by rethrowing
after the walk completes. Update printSummary to include the recorded failure
count, using the report’s existing failure-tracking structure consistently.

In `@admin/pipeline/body/repairs.test.ts`:
- Around line 7-23: Update the FIXTURES paths used by loadFixtures to resolve
relative to the test file via import.meta.dir, matching dry-run.test.ts.
Preserve the existing fixture filenames and readSourceEntries iteration while
removing the dependency on the process working directory.

In `@admin/pipeline/body/repairs.ts`:
- Around line 293-300: Remove the duplicate recursive walkSensesDeep generator
from admin/pipeline/body/repairs.ts#L293-L300 and
admin/pipeline/body/migrate-dry.ts#L60-L67, then import and reuse the shared
source-sense walker exported by census.ts in both modules. Keep existing callers
unchanged and retain only one implementation.
- Around line 14-19: Replace the inline TODO in the repairs documentation with a
concrete tracking reference for the pending notes mechanism, linking the
design-doc changelog and required entry.schema.json update. Preserve the
existing explanation that deviations remain in the record and migration report
until notes support is implemented.

In `@admin/pipeline/body/source.ts`:
- Around line 20-34: Update the linesOf async generator to flush the TextDecoder
after the chunk loop by calling decoder.decode() without stream mode and
appending the result to tail before splitting or yielding the final content.
Preserve the existing line handling while ensuring incomplete trailing UTF-8
sequences surface as decoding errors.

In `@docs/superpowers/plans/2026-07-11-entry-body-model.md.tasks.json`:
- Line 151: Update the lastUpdated field in the task record to the actual final
modification timestamp reflecting completion of Tasks 15–17 on August 5, 2026,
replacing the stale July 15, 2026 value.

In `@docs/v2/body-census.md`:
- Around line 173-178: Correct the Finding 8 coverage statement to match the
`lettered` selection in `extract.ts`: either list all 189 RIDs as fixtures or
explicitly describe the fixtures as a reviewed sample, rather than claiming
exhaustive coverage.

In `@docs/v2/body-dryrun.md`:
- Around line 178-179: Update the reported non-zero evidentiary citation share
in the body dry-run statistics from 60.7% to 60.8%, while leaving the
accompanying counts and surrounding text unchanged.

In `@docs/v2/body-migration.md`:
- Line 28: Update the schema validation baseline in the “Schema validation”
table of body-migration.md to report 4 in-sample failures, matching the current
body-dryrun.md results; alternatively, explicitly label 3 as a dated historical
baseline.

In `@docs/v2/body-review/01-broken-sequences.md`:
- Around line 25-29: Complete the maintainer-review evidence in
docs/v2/body-review/01-broken-sequences.md lines 25-29 by filling every blank
Decision cell or adding an unambiguous section-level decision covering all
listed rows. Update docs/v2/body-review/00-INDEX.md lines 21-27 to replace
“awaiting review” with the recorded completed status for each reviewed document.

In `@docs/v2/body-review/02-orphan-refs.md`:
- Line 68: Correct the closing note by changing “where” to “were,” “concered” to
“concerned,” and “Jastow” to “Jastrow,” then ensure the file ends with exactly
one newline.

In `@docs/v2/body-review/03-quotes-stragglers.md`:
- Line 23: Update the provenance note to use “Sefaria developers” instead of
“Sefaria Devs” and correct the typo “supprised” to “surprised,” preserving the
rest of the note.

In `@docs/v2/body-review/04-label-quarantines.md`:
- Line 16: Correct the typo in the D00341 decision note by changing “begining”
to “beginning,” without altering the surrounding notation or content.

In `@docs/v2/sefaria-report.md`:
- Around line 292-303: Add the text language identifier to both fenced code
blocks in the documented examples, including the block showing the current
structure and the block showing the faithful structure, while leaving their
contents unchanged.
- Around line 156-167: The duplicated nested-anchor metric must use an explicit
scope consistently: in docs/v2/sefaria-report.md lines 156-167, either label 475
as definition anchors only or change it to the all-field total of 1,230; in
docs/v2/upstream-issues.md line 21, retain 1,230 only if the all-field scope,
including 475 definition and 755 language_reference anchors, is stated.

In `@docs/v2/upstream-issues.md`:
- Line 16: Update the issue row for P00855, P00856, and P00860 to list the
served headwords עָמַך I, עָמַך II, and עֶמַך separately from their corrected
print headwords עָמַד I, עָמַד II, and עֶמֶד, preserving the existing issue
references and status.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2a211f40-4873-4d6c-92a7-0b38ce8f6aed

📥 Commits

Reviewing files that changed from the base of the PR and between 2b779a5 and 1cb7d8d.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (65)
  • .gitignore
  • admin/pipeline/body/README.md
  • admin/pipeline/body/census.test.ts
  • admin/pipeline/body/census.ts
  • admin/pipeline/body/cite.test.ts
  • admin/pipeline/body/cite.ts
  • admin/pipeline/body/dry-run-report.ts
  • admin/pipeline/body/dry-run-verify.ts
  • admin/pipeline/body/dry-run.test.ts
  • admin/pipeline/body/dry-run.ts
  • admin/pipeline/body/fixtures/README.md
  • admin/pipeline/body/fixtures/baseline.jsonl
  • admin/pipeline/body/fixtures/broken-sequences.jsonl
  • admin/pipeline/body/fixtures/extract.ts
  • admin/pipeline/body/fixtures/form-sections.jsonl
  • admin/pipeline/body/fixtures/label-quarantines.jsonl
  • admin/pipeline/body/fixtures/lettered.jsonl
  • admin/pipeline/body/fixtures/numbering-extras.jsonl
  • admin/pipeline/body/fixtures/origin-splits.jsonl
  • admin/pipeline/body/fixtures/orphans.jsonl
  • admin/pipeline/body/fixtures/plural.jsonl
  • admin/pipeline/body/fixtures/quotes-stragglers.jsonl
  • admin/pipeline/body/fixtures/stems.jsonl
  • admin/pipeline/body/fixtures/units-hard.jsonl
  • admin/pipeline/body/form-sections.test.ts
  • admin/pipeline/body/form-sections.ts
  • admin/pipeline/body/grammar.test.ts
  • admin/pipeline/body/grammar.ts
  • admin/pipeline/body/labels.test.ts
  • admin/pipeline/body/labels.ts
  • admin/pipeline/body/lettered.test.ts
  • admin/pipeline/body/lettered.ts
  • admin/pipeline/body/migrate-dry.ts
  • admin/pipeline/body/rejoin.test.ts
  • admin/pipeline/body/rejoin.ts
  • admin/pipeline/body/repairs.test.ts
  • admin/pipeline/body/repairs.ts
  • admin/pipeline/body/review.test.ts
  • admin/pipeline/body/review.ts
  • admin/pipeline/body/source.test.ts
  • admin/pipeline/body/source.ts
  • admin/pipeline/body/types.ts
  • admin/pipeline/body/units.test.ts
  • admin/pipeline/body/units.ts
  • admin/pipeline/schema/entry.schema.json
  • admin/pipeline/schema/entry.schema.test.ts
  • biome.json
  • docs/specs/2026-07-11-entry-body-model-design.md
  • docs/superpowers/plans/2026-07-03-v2-phase0-1.md.tasks.json
  • docs/superpowers/plans/2026-07-11-entry-body-model.md
  • docs/superpowers/plans/2026-07-11-entry-body-model.md.tasks.json
  • docs/v2/body-census.md
  • docs/v2/body-dryrun.md
  • docs/v2/body-migration.md
  • docs/v2/body-review/00-INDEX.md
  • docs/v2/body-review/01-broken-sequences.md
  • docs/v2/body-review/02-orphan-refs.md
  • docs/v2/body-review/03-quotes-stragglers.md
  • docs/v2/body-review/04-label-quarantines.md
  • docs/v2/body-review/05-unit-segmentation-sample.md
  • docs/v2/body-review/06-empty-binyan-forms.md
  • docs/v2/body-review/07-italic-lettered-markers.md
  • docs/v2/sefaria-report.md
  • docs/v2/upstream-issues.md
  • package.json
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Workers Builds: jastrow
⚠️ CI failures not shown inline (1)

GitHub Check: Workers Builds: jastrow: Workers Builds: jastrow

Conclusion: failure

View job details

Build ID: [710d9e31-4017-43fe-8310-f32514330f91](https://dash.cloudflare.com/cf68e0017c53376defadebeecd91fda2/workers/services/view/jastrow/production/builds/710d9e31-4017-43fe-8310-f32514330f91)
Script: [jastrow](https://dash.cloudflare.com/cf68e0017c53376defadebeecd91fda2/workers/services/view/jastrow/production)
🧰 Additional context used
📓 Path-based instructions (2)
**

⚙️ CodeRabbit configuration file

**: General project rules:

  • This is a vanilla JS static site PWA. No bundler, no framework, no npm packages at runtime.
  • All JS runs in the browser unless under admin/ (maintainer tooling, which uses Bun).
  • Repo layout (v2): app/ public app, admin/ tooling (incl. admin/pipeline/), data/ data only.
  • Biome enforces lint and formatting.
  • DOMPurify is loaded via CDN with SRI for XSS sanitization.

Files:

  • docs/superpowers/plans/2026-07-03-v2-phase0-1.md.tasks.json
  • admin/pipeline/body/fixtures/stems.jsonl
  • admin/pipeline/body/review.test.ts
  • admin/pipeline/body/fixtures/baseline.jsonl
  • admin/pipeline/body/fixtures/numbering-extras.jsonl
  • admin/pipeline/body/fixtures/README.md
  • admin/pipeline/body/fixtures/orphans.jsonl
  • admin/pipeline/body/fixtures/label-quarantines.jsonl
  • biome.json
  • admin/pipeline/body/fixtures/lettered.jsonl
  • admin/pipeline/body/fixtures/form-sections.jsonl
  • admin/pipeline/body/rejoin.test.ts
  • docs/v2/upstream-issues.md
  • admin/pipeline/body/grammar.test.ts
  • docs/v2/body-review/01-broken-sequences.md
  • admin/pipeline/body/types.ts
  • docs/v2/body-dryrun.md
  • docs/v2/body-review/02-orphan-refs.md
  • admin/pipeline/body/rejoin.ts
  • admin/pipeline/body/fixtures/origin-splits.jsonl
  • package.json
  • admin/pipeline/body/fixtures/quotes-stragglers.jsonl
  • admin/pipeline/body/lettered.test.ts
  • docs/v2/body-review/00-INDEX.md
  • admin/pipeline/body/fixtures/units-hard.jsonl
  • docs/v2/body-review/07-italic-lettered-markers.md
  • docs/v2/body-review/04-label-quarantines.md
  • admin/pipeline/body/README.md
  • admin/pipeline/body/cite.test.ts
  • admin/pipeline/body/fixtures/broken-sequences.jsonl
  • docs/v2/body-review/03-quotes-stragglers.md
  • admin/pipeline/body/units.ts
  • admin/pipeline/body/form-sections.test.ts
  • admin/pipeline/body/labels.test.ts
  • admin/pipeline/body/census.test.ts
  • admin/pipeline/body/source.ts
  • docs/v2/body-review/06-empty-binyan-forms.md
  • admin/pipeline/body/fixtures/plural.jsonl
  • docs/v2/body-review/05-unit-segmentation-sample.md
  • docs/v2/body-census.md
  • admin/pipeline/body/lettered.ts
  • admin/pipeline/body/fixtures/extract.ts
  • admin/pipeline/body/labels.ts
  • admin/pipeline/body/migrate-dry.ts
  • admin/pipeline/body/source.test.ts
  • admin/pipeline/schema/entry.schema.json
  • admin/pipeline/body/grammar.ts
  • admin/pipeline/body/dry-run.test.ts
  • admin/pipeline/body/units.test.ts
  • admin/pipeline/body/dry-run-verify.ts
  • admin/pipeline/schema/entry.schema.test.ts
  • admin/pipeline/body/cite.ts
  • docs/superpowers/plans/2026-07-11-entry-body-model.md.tasks.json
  • admin/pipeline/body/census.ts
  • admin/pipeline/body/repairs.test.ts
  • admin/pipeline/body/form-sections.ts
  • docs/v2/body-migration.md
  • admin/pipeline/body/dry-run-report.ts
  • admin/pipeline/body/review.ts
  • admin/pipeline/body/dry-run.ts
  • docs/specs/2026-07-11-entry-body-model-design.md
  • docs/v2/sefaria-report.md
  • admin/pipeline/body/repairs.ts
  • docs/superpowers/plans/2026-07-11-entry-body-model.md
admin/**

⚙️ CodeRabbit configuration file

admin/**: Maintainer tooling that runs on Bun (not deployed). Includes:

  • admin/pipeline/ — data pipeline from the Sefaria source (fetch, transform, validate, emit)
  • Admin tool v2 (Phase 3) will live here too
  • console and sequential awaits over streams are expected here

Files:

  • admin/pipeline/body/fixtures/stems.jsonl
  • admin/pipeline/body/review.test.ts
  • admin/pipeline/body/fixtures/baseline.jsonl
  • admin/pipeline/body/fixtures/numbering-extras.jsonl
  • admin/pipeline/body/fixtures/README.md
  • admin/pipeline/body/fixtures/orphans.jsonl
  • admin/pipeline/body/fixtures/label-quarantines.jsonl
  • admin/pipeline/body/fixtures/lettered.jsonl
  • admin/pipeline/body/fixtures/form-sections.jsonl
  • admin/pipeline/body/rejoin.test.ts
  • admin/pipeline/body/grammar.test.ts
  • admin/pipeline/body/types.ts
  • admin/pipeline/body/rejoin.ts
  • admin/pipeline/body/fixtures/origin-splits.jsonl
  • admin/pipeline/body/fixtures/quotes-stragglers.jsonl
  • admin/pipeline/body/lettered.test.ts
  • admin/pipeline/body/fixtures/units-hard.jsonl
  • admin/pipeline/body/README.md
  • admin/pipeline/body/cite.test.ts
  • admin/pipeline/body/fixtures/broken-sequences.jsonl
  • admin/pipeline/body/units.ts
  • admin/pipeline/body/form-sections.test.ts
  • admin/pipeline/body/labels.test.ts
  • admin/pipeline/body/census.test.ts
  • admin/pipeline/body/source.ts
  • admin/pipeline/body/fixtures/plural.jsonl
  • admin/pipeline/body/lettered.ts
  • admin/pipeline/body/fixtures/extract.ts
  • admin/pipeline/body/labels.ts
  • admin/pipeline/body/migrate-dry.ts
  • admin/pipeline/body/source.test.ts
  • admin/pipeline/schema/entry.schema.json
  • admin/pipeline/body/grammar.ts
  • admin/pipeline/body/dry-run.test.ts
  • admin/pipeline/body/units.test.ts
  • admin/pipeline/body/dry-run-verify.ts
  • admin/pipeline/schema/entry.schema.test.ts
  • admin/pipeline/body/cite.ts
  • admin/pipeline/body/census.ts
  • admin/pipeline/body/repairs.test.ts
  • admin/pipeline/body/form-sections.ts
  • admin/pipeline/body/dry-run-report.ts
  • admin/pipeline/body/review.ts
  • admin/pipeline/body/dry-run.ts
  • admin/pipeline/body/repairs.ts
🧠 Learnings (1)
📚 Learning: 2026-07-05T16:14:54.518Z
Learnt from: UniquePixels
Repo: UniquePixels/jastrow PR: 25
File: admin/pipeline/fetch.ts:48-75
Timestamp: 2026-07-05T16:14:54.518Z
Learning: For maintainer-run pipeline scripts under admin/pipeline (including admin/pipeline/fetch.ts), avoid adding or recommending a whole-transfer AbortSignal.timeout() for large downloads (e.g., multi-GB dumps). A fixed end-to-end timeout can abort valid successful runs. If cancellation/robustness is needed, prefer an inter-chunk idle timeout (no progress for N seconds) with appropriate retry behavior rather than timing out the entire transfer. Until the admin tool provides UI-driven cancellation/progress, the accepted recovery path for manual reruns is ctrl-C and rerunning the script.

Applied to files:

  • admin/pipeline/body/review.test.ts
  • admin/pipeline/body/rejoin.test.ts
  • admin/pipeline/body/grammar.test.ts
  • admin/pipeline/body/types.ts
  • admin/pipeline/body/rejoin.ts
  • admin/pipeline/body/lettered.test.ts
  • admin/pipeline/body/cite.test.ts
  • admin/pipeline/body/units.ts
  • admin/pipeline/body/form-sections.test.ts
  • admin/pipeline/body/labels.test.ts
  • admin/pipeline/body/census.test.ts
  • admin/pipeline/body/source.ts
  • admin/pipeline/body/lettered.ts
  • admin/pipeline/body/fixtures/extract.ts
  • admin/pipeline/body/labels.ts
  • admin/pipeline/body/migrate-dry.ts
  • admin/pipeline/body/source.test.ts
  • admin/pipeline/body/grammar.ts
  • admin/pipeline/body/dry-run.test.ts
  • admin/pipeline/body/units.test.ts
  • admin/pipeline/body/dry-run-verify.ts
  • admin/pipeline/schema/entry.schema.test.ts
  • admin/pipeline/body/cite.ts
  • admin/pipeline/body/census.ts
  • admin/pipeline/body/repairs.test.ts
  • admin/pipeline/body/form-sections.ts
  • admin/pipeline/body/dry-run-report.ts
  • admin/pipeline/body/review.ts
  • admin/pipeline/body/dry-run.ts
  • admin/pipeline/body/repairs.ts
🪛 ast-grep (0.45.0)
admin/pipeline/body/census.ts

[warning] 237-243: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(
// Escape every regex special (not just .) even though MARKERS
// is a closed literal vocabulary — CodeQL js/incomplete-
// sanitization, and future markers stay safe by construction.
${marker.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&')}.{0,120}?(?<![(\\w])1\\)\\s,
'su',
)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)


[warning] 237-243: Do not use variable for regular expressions
Context: new RegExp(
// Escape every regex special (not just .) even though MARKERS
// is a closed literal vocabulary — CodeQL js/incomplete-
// sanitization, and future markers stay safe by construction.
${marker.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&')}.{0,120}?(?<![(\\w])1\\)\\s,
'su',
)
Note: [CWE-1333] Inefficient Regular Expression Complexity. Security best practice.

(regexp-non-literal-typescript)

admin/pipeline/body/form-sections.ts

[warning] 179-179: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(—?${pattern}, 'gu')
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)

admin/pipeline/body/review.ts

[warning] 318-321: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(
<a\\b[^>]*data-ref="${escapeRegExp(item)}"[^>]*>([^<]*)</a>,
'u',
)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)

🪛 Biome (2.5.6)
admin/pipeline/body/migrate-dry.ts

[error] 11-11: The import specifier ajv cannot be resolved: module not found

(lint/correctness/noUnresolvedImports)


[error] 12-12: The import specifier ajv/dist/2020 cannot be resolved: module not found

(lint/correctness/noUnresolvedImports)

admin/pipeline/body/dry-run-report.ts

[error] 10-10: The import specifier ajv cannot be resolved: module not found

(lint/correctness/noUnresolvedImports)

admin/pipeline/body/dry-run.ts

[error] 14-14: The import specifier ajv cannot be resolved: module not found

(lint/correctness/noUnresolvedImports)


[error] 15-15: The import specifier ajv/dist/2020 cannot be resolved: module not found

(lint/correctness/noUnresolvedImports)

🪛 GitHub Check: Lint
admin/pipeline/body/fixtures/extract.ts

[notice] 10-382: lint/style/noExcessiveLinesPerFile
This file has too many lines (363). Maximum allowed is 300.

admin/pipeline/body/dry-run.test.ts

[notice] 191-191: lint/complexity/noExcessiveCognitiveComplexity
Excessive complexity of 19 detected (max: 15).


[notice] 99-99: lint/style/useDestructuring
Use array destructuring instead of accessing array elements by index.


[notice] 96-96: lint/style/useDestructuring
Use array destructuring instead of accessing array elements by index.


[notice] 1-328: lint/style/noExcessiveLinesPerFile
This file has too many lines (328). Maximum allowed is 300.

admin/pipeline/body/dry-run-verify.ts

[notice] 166-166: lint/style/useExplicitLengthCheck
Use .length > 0 when checking .length is not zero.

admin/pipeline/body/census.ts

[notice] 63-63: lint/nursery/useNamedCaptureGroup
Capture group is not named.


[notice] 444-444: lint/complexity/noExcessiveCognitiveComplexity
Excessive complexity of 20 detected (max: 15).


[notice] 88-88: lint/correctness/useSingleJsDocAsterisk
JSDoc comment line should start with a single asterisk.


[notice] 9-609: lint/style/noExcessiveLinesPerFile
This file has too many lines (562). Maximum allowed is 300.

🪛 GitHub Check: SonarCloud Code Analysis
admin/pipeline/body/lettered.test.ts

[warning] 202-202: Prefer "expect(entries).toHaveLength(9)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy02QmNwicMDYzT8&open=AZ_XPy02QmNwicMDYzT8&pullRequest=36

admin/pipeline/body/form-sections.test.ts

[warning] 262-262: Prefer "expect(entries).toHaveLength(9)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy2BQmNwicMDYzUT&open=AZ_XPy2BQmNwicMDYzUT&pullRequest=36


[warning] 236-236: Prefer "expect(entries).toHaveLength(25)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy2BQmNwicMDYzUS&open=AZ_XPy2BQmNwicMDYzUS&pullRequest=36

admin/pipeline/body/lettered.ts

[warning] 106-106: Prefer String.fromCodePoint() over String.fromCharCode().

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy0tQmNwicMDYzT7&open=AZ_XPy0tQmNwicMDYzT7&pullRequest=36

admin/pipeline/body/migrate-dry.ts

[warning] 106-106: Prefer String#replaceAll() over String#split().join().

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1SQmNwicMDYzUH&open=AZ_XPy1SQmNwicMDYzUH&pullRequest=36


[warning] 79-79: The non-empty check is useless as Array#some() returns false for an empty array.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1SQmNwicMDYzUG&open=AZ_XPy1SQmNwicMDYzUG&pullRequest=36

admin/pipeline/body/dry-run.test.ts

[warning] 122-122: Prefer "expect(body.senses).toHaveLength(e.content.senses.length)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPyxnQmNwicMDYzT6&open=AZ_XPyxnQmNwicMDYzT6&pullRequest=36


[warning] 29-29: Prefer "expect(entries).toHaveLength(3)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPyxnQmNwicMDYzT5&open=AZ_XPyxnQmNwicMDYzT5&pullRequest=36

admin/pipeline/body/census.ts

[warning] 242-242: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XRJafhxIv6rpONflD&open=AZ_XRJafhxIv6rpONflD&pullRequest=36


[warning] 406-406: Replace this character class by the character itself.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1yQmNwicMDYzUQ&open=AZ_XPy1yQmNwicMDYzUQ&pullRequest=36


[warning] 367-367: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1yQmNwicMDYzUP&open=AZ_XPy1yQmNwicMDYzUP&pullRequest=36


[failure] 444-444: Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1yQmNwicMDYzUR&open=AZ_XPy1yQmNwicMDYzUR&pullRequest=36


[warning] 25-25: Simplify this regular expression to reduce its runtime, as it has super-linear performance due to backtracking.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1yQmNwicMDYzUL&open=AZ_XPy1yQmNwicMDYzUL&pullRequest=36


[warning] 242-242: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XRJafhxIv6rpONflE&open=AZ_XRJafhxIv6rpONflE&pullRequest=36

admin/pipeline/body/repairs.test.ts

[warning] 66-66: Prefer "expect(entry.content.senses).toHaveLength(source.content.senses.length - 1)" over this generic assertion for better reporting; it works on any object with a numeric length property.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1aQmNwicMDYzUI&open=AZ_XPy1aQmNwicMDYzUI&pullRequest=36

admin/pipeline/body/form-sections.ts

[warning] 178-178: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy0_QmNwicMDYzT_&open=AZ_XPy0_QmNwicMDYzT_&pullRequest=36


[warning] 179-179: Prefer String#replaceAll() over String#replace().

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy0_QmNwicMDYzUA&open=AZ_XPy0_QmNwicMDYzUA&pullRequest=36


[warning] 178-178: Prefer String#replaceAll() over String#replace().

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy0_QmNwicMDYzT-&open=AZ_XPy0_QmNwicMDYzT-&pullRequest=36


[warning] 176-176: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy0_QmNwicMDYzT9&open=AZ_XPy0_QmNwicMDYzT9&pullRequest=36


[warning] 179-179: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy0_QmNwicMDYzUB&open=AZ_XPy0_QmNwicMDYzUB&pullRequest=36

admin/pipeline/body/review.ts

[warning] 107-107: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1KQmNwicMDYzUE&open=AZ_XPy1KQmNwicMDYzUE&pullRequest=36


[warning] 320-320: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1KQmNwicMDYzUF&open=AZ_XPy1KQmNwicMDYzUF&pullRequest=36


[warning] 85-85: Simplify this regular expression to reduce its runtime, as it has super-linear performance due to backtracking.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1KQmNwicMDYzUC&open=AZ_XPy1KQmNwicMDYzUC&pullRequest=36


[warning] 105-105: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1KQmNwicMDYzUD&open=AZ_XPy1KQmNwicMDYzUD&pullRequest=36

admin/pipeline/body/repairs.ts

[warning] 17-17: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1mQmNwicMDYzUJ&open=AZ_XPy1mQmNwicMDYzUJ&pullRequest=36


[warning] 484-484: Prefer String#replaceAll() over String#split().join().

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1mQmNwicMDYzUK&open=AZ_XPy1mQmNwicMDYzUK&pullRequest=36

🪛 LanguageTool
docs/v2/body-review/01-broken-sequences.md

[grammar] ~80-~80: Ensure spelling is correct
Context: ... --- | | A00675 | אוּלָם II | 2 | …eub. Géogr. p. 18; 261) Ulam (Porta) a place in Gi...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~80-~80: Ensure spelling is correct
Context: ...place in Gilead, and one in Galilee. Y. Snh. X, 28ᵈ —2) | ```p. 18; 261) Ula...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~81-~81: Ensure spelling is correct
Context: ... CXXXIII, 2. Targ. Y. Ex. XXVI, 4 (Var. אֶימְרָא). V. next w. —4) | ```(Sarah) not eve...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~83-~83: Ensure spelling is correct
Context: ...i>, 1) homiletic``` (Verified via print endition) | | B01321 | בַּרְקַאי II | 2 | , v. ב...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~89-~89: Ensure spelling is correct
Context: ...s), v. אֶחָד. Cant. R. l. c.; a. fr. V. דָּבָר. —2) | I believe the existing 2) se...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~89-~89: Ensure spelling is correct
Context: ...he existing 2) sense in source data, is actualy a second sense of the plural with an im...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~90-~90: Ensure spelling is correct
Context: ...7ᵇ, v. אֲרָם; a. fr.—M. Kat. III, 3, v. גָּזָר. —4) | ```precipice.—2) decree, edi...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~95-~95: Ensure spelling is correct
Context: ...—7)**
… R. to VII, 7 [read:] הרי הוא כּוֹבְשֵׁנִי וכ׳ behold, he is attacking me in thy p...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~95-~95: Ensure spelling is correct
Context: ...is entry ruins my theory about Pl being a seperatley numberd section | | M00252 | מִדָּה | 1, 2, 4 |...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~100-~100: Ensure spelling is correct
Context: ...scratching a sore. Sabb. V, 4 (54ᵇ), v. לוֹעָא. —3) | kings; a. fr.—2) a yoke | | ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~106-~106: Ensure spelling is correct
Context: ...4; Y. ib. 36ᵃ top צִילְעוֹת constr., v. פּוּאָה. —3) | es; a. fr.—2) side | | Q0197...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~109-~109: Ensure spelling is correct
Context: ...h. text מוֹט). Targ. Y. II ib. XIII, 23 קוֹפָה. —2)
…old trunk.—Pl. קוֹפָאֵי. B...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~111-~111: Consider a more concise word here.
Context: ...r. IX, 14ᵇ —2)
…res only rinsing in order to be restored to Levitical cleanness. Ḥul...

(IN_ORDER_TO_PREMIUM)


[style] ~113-~113: To form a complete sentence, be sure to include a subject.
Context: ...ext - s. 85; a. fr.— Absalom’s sister. should be... s. 85; a. fr.—2) Absalom’s sister...

(MISSING_IT_THERE)


[style] ~115-~115: To make your text as clear as possible to all readers, do not use this foreign term. Possible alternatives are “above”, “above-mentioned”, “aforementioned”, or “as previously mentioned” (in the document).
Context: ... | Hifil missing sense 4 v. supra.—4) to produce | | A01194 | אֵיזֶה ...

(SUPRA)


[style] ~121-~121: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...to the location in the text they go, so maybe a markup tag as well? These would not ...

(REP_MAYBE)


[style] ~121-~121: In American English, abbreviations like “etc.” require a period.
Context: ...o the source data due to import errors, etc, only deviations from the printed text....

(ETC_PERIOD)


[grammar] ~132-~132: Ensure spelling is correct
Context: ...on as note 1. The fact that sense 2 is labled *2 says to me there is a specific somet...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

docs/v2/body-review/02-orphan-refs.md

[grammar] ~25-~25: Ensure spelling is correct
Context: ..."ת** . Sabb. 104ᵃ גוֹפו טימא אר̇חם עליו thoug… | | | C01225 | גֵּר | Jastrow, ג"ר 1 |...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~32-~32: Ensure spelling is correct
Context: ... …s of three letters each (Dan. V, 25). Snh. 22ᵃ; Cant. R. to III, 4; v. אאלר"ן...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~50-~50: Ensure spelling is correct
Context: ...ef. ib. IX (VI), 18. Mikv. VI, 1 עוּקַת המערה… | ALL Approved | | P00331 | עוּקָה | Er...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~51-~51: Ensure spelling is correct
Context: ...ef. ib. IX (VI), 18. Mikv. VI, 1 עוּקַת המערה… | | | P00331 | עוּקָה | Eruvin 88b:22 ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~52-~52: Ensure spelling is correct
Context: ...ef. ib. IX (VI), 18. Mikv. VI, 1 עוּקַת המערה… | | | P01404 | עֶרֶס | Targum Jerusale...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~54-~54: Ensure spelling is correct
Context: ...the minor transgressions: omission of a positi… | | ## Class 3 — unexplained, eyes-on...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~65-~65: ‘The situation of’ might be wordy. Consider a shorter alternative.
Context: ...ikhvar, Makhvar, a district of Peraea. [The situation of Machaerus forbids its identification wi...

(EN_WORDINESS_PREMIUM_THE_SITUATION_OF)


[grammar] ~68-~68: Ensure spelling is correct
Context: ...e idea linkage, but for us, we are only concered with showing what Jastow linked.

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

docs/v2/body-review/07-italic-lettered-markers.md

[style] ~22-~22: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...…s. סָמוּי; f. סְמוּיָה, סְמוּיָיה; pl. סְמוּיִים, סְמוּיִין; סְמוּיוֹת `a...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~27-~27: Ensure spelling is correct
Context: ...man body, sensuality. Lev. R. s. 13, v. נָשַׁף. Ber. 17ᵃ גלוי … … | | | P00680 | עֵיר...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~28-~28: Ensure spelling is correct
Context: ... 17ᵃ גלוי … … | | | P00680 | עֵירוּב | …hich the legal fiction of community or conti...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~31-~31: To make your text as clear as possible to all readers, do not use this foreign term. Possible alternatives are “above”, “above-mentioned”, “aforementioned”, or “as previously mentioned” (in the document).
Context: ...ז. Bekh. 43ᵇ bot.; Sifra Emor l. c., v. supra.—Part. pass. מוּפְלָג <i>a</i>) remov...

(SUPRA)


[style] ~32-~32: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... …art. pass. פְּלִיג; f. פְּלִיגָא; pl. פְּלִיגִין, פְּלִיגֵי; פְּלִיגָן `a</i...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~33-~33: Ensure spelling is correct
Context: ...ה <i>a</i>) free, disengaged, single. Yeb. III, 5 שלשה אחין … ואחד מ׳ three broth...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~36-~36: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... | …t. pass. פָּסוּל; f. פְּסוּלָה; pl. פְּסוּלִים, פְּסוּלִין; פְּסוּלוֹת `a<...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~40-~40: Ensure spelling is correct
Context: ....—b) wings.… | | | P00856 | עָמַך II | …hat from him should rise priests and kings;...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~41-~41: Ensure spelling is correct
Context: ... trnsf. <i>a</i>) to be undecided. Y. Snh. V, end, 23ᵃ שלא ייראה דין זה יוצא מעמע...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~43-~43: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...….—Part. pass. עָקוּר; f. עֲקוּרָה; pl. עֲקוּרִים, עְקוּרִין; עֲקוּרוֹת `a...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~46-~46: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...s. Part. pass. צָמִיד; f. צְמִידָא; pl. צְמִידִין, <i>a</i>) attached, harnesse...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~52-~52: Ensure spelling is correct
Context: ...btful, v. צָרִיךְ. Y. Gitt. IV, 46ᵃ, v. אפרכוריס. Y. … | | | S00057 | קָבַל I | …. fr.—...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~54-~54: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ח | … pass. פְּתִיחַ; f. פְּתִיחָא; pl. פְּתִיחִין, פְּתִיחַיָּא; פְּתִיחָן `a...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~57-~57: Ensure spelling is correct
Context: ... Ex. IX, … | | | S00123 | קְדוּשָּׁה | …hould be performed with less than ten persons...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~63-~63: Ensure spelling is correct
Context: ...Targ. Is. VII, 18 (?).—b) restrictions. Yeb. 107ᵇ תר… | | | S01725 | קָפַח | …ot a...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~68-~68: Ensure spelling is correct
Context: ...at one time. Ḥag. 13ᵃ רָאשֵׁי פרקים, v. פֶּרֶק; a. fr.—Trnsf. <i>a</i>) chief, magistrate, leader, ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~72-~72: Ensure spelling is correct
Context: ...X, 16) to have connection with a beast. Snh. I, 4 … | | | T00137 | רָבַץ | … a loa...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~80-~80: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...art. pass. מוּתְאָם; f. מוּתְאֶמֶת; pl. מוּתְאָמִים; מוּתְאָמוֹת <i>a</i>) place...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~83-~83: Ensure spelling is correct
Context: ...rbal communication, oral study, opp. to מִשְׁנ… | | | U01137 | שָׁכַח | …ose it served...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~88-~88: Consider a more concise word here.
Context: ...| | | U01525 | שָׁמַר | …s been closed in order to preserve the flavor).—Part. pass. מְשׁו...

(IN_ORDER_TO_PREMIUM)


[grammar] ~89-~89: Ensure spelling is correct
Context: ...ובא מן המזיקי… | | | U01589 | שֵׁנִי | …irect from the fire.—Maas. Sh. I, 1, a. fr. מ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~93-~93: Ensure spelling is correct
Context: ...שָׂה &c. <i>a</i>) (cmp. אָחוּז s. v. אָחַז) holding. Y. Taan. l. c. היה משה ת׳ בטפחיים M… | ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~94-~94: Consider an alternative adverb to strengthen your wording.
Context: ... מְתוּקָּנִין; מְתוּקָּנוֹת <i>a</i>) properly prepared, proper, good, right. Bets. 34...

(PROPERLY_THOROUGHLY)


[style] ~94-~94: To make your text as clear as possible to all readers, do not use this foreign term. Possible alternatives are “above”, “above-mentioned”, “aforementioned”, or “as previously mentioned” (in the document).
Context: ...red, proper, good, right. Bets. 34ᵇ, v. supra. Erub. 32ᵃ… | | | V00905 | תָּקַע | … ...

(SUPRA)

docs/v2/body-review/04-label-quarantines.md

[grammar] ~16-~16: Ensure spelling is correct
Context: ...his implies. Likely should move to the begining of the sense text to keep the notation…...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~20-~20: To make your text as clear as possible to all readers, do not use this foreign term. Possible alternatives are “above”, “above-mentioned”, “aforementioned”, or “as previously mentioned” (in the document).
Context: ... | | | U00745 | שטי | -2) | same, v. supra. -2) (with ב) to fool, jest. Yeb. 1...

(SUPRA)


[grammar] ~20-~20: Ensure spelling is correct
Context: ... supra. -2) (with ב) to fool, jest. Yeb. 106ᵃ; B. Kam. 116ᵃ אמר ליה משטה אני בך...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~21-~21: Ensure spelling is correct
Context: ... מִשְׁלַחַת) letting loose, visitation. Yeb. 114ᵇ ש׳ נחשים וכ׳ a plague of serpents...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

docs/v2/body-review/03-quotes-stragglers.md

[grammar] ~16-~16: Ensure spelling is correct
Context: ... with many cases, trader’s chest. Tanḥ. B’midb. 20 לאדם פרגמטיוטיס שהיה לו א׳ של זכוכי...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~19-~19: Ensure spelling is correct
Context: ...׳ נוגהא Venus. Targ. II Esth. II, 7 (v. אִיסְתִּירָא); Yalk. Esth. 1053 (hebr.), v. אִסְתְּהַר.—Sabb...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~19-~19: Ensure spelling is correct
Context: ... 7 (v. אִיסְתִּירָא); Yalk. Esth. 1053 (hebr.), v. אִסְתְּהַר.—Sabb. l. c.; a. e.—כ׳...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~23-~23: Ensure spelling is correct
Context: ..., it was never validated by them so not supprised has these.

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

docs/v2/body-review/05-unit-segmentation-sample.md

[grammar] ~87-~87: Ensure spelling is correct
Context: ... בִּצְעִים, בִּצְעִין, בִּי׳. - Tosef. Snh. III, 4 שתי בצעין ed. Zuck. (Var. ביצוע...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~89-~89: Ensure spelling is correct
Context: ...המים between the dykes (of the Nile). - Snh. 96ᵃ בִּיצְעֵי וכ׳. - Ib. 5ᵇ, v. בִּצָּ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~99-~99: Ensure spelling is correct
Context: ...ing than when open). - Ab. Zar. 60ᵃ, v. כּוּבָּא II. - Sabb. 157ᵇ, v. אוּדְנָא II. **Decisi...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~100-~100: Ensure spelling is correct
Context: .... 60ᵃ, v. כּוּבָּא II. - Sabb. 157ᵇ, v. אוּדְנָא II. Decision: ### C00432 — גּוֹנֶבֶת **G...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~160-~160: Ensure spelling is correct
Context: ... וכ׳ a bale filled with fruit stones. - Ukts. II, 2, v. חוֹתָם.—[Y. Keth. VIII, 32ᵇ ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~210-~210: Ensure spelling is correct
Context: ... ומ׳ ידעינן וכ׳ and how do we know &c.? Snh. 61ᵇ מ׳ אמינא לה whence (on what eviden...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~244-~244: Ensure spelling is correct
Context: ... and he who presses him (the stranger), contrad. to אִנָּה.—Part. pass. לָחוּץ, pl. לְח...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~330-~330: Ensure spelling is correct
Context: ... estimate yield five S’ah of coal. - Y. Snh. IX, 27ᵃ bot. ע׳ של טעות an erroneous p...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~331-~331: Ensure spelling is correct
Context: ...s. - Y. Naz. IX, end, 58ᵃ ע׳ האמצעי, v. אוּמָד. - Ib. עֶמֶד, a. עֲמָדָה.—Pl. עוּמָדִין...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~356-~356: Ensure spelling is correct
Context: ...k. VII, beg. 51ᵃ, a. e. לוקח מן הפ׳, v. סִידְקִי. - Y. Shebi. VII, 37ᶜ top ובלבד שלא יעש...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~375-~375: Ensure spelling is correct
Context: ...grieved. - Targ. Lam. IV, 1 (ed. Amst. עַמָּא). - Targ. O. Lev. XIII, 6; 56 עָמָא ed. B...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~378-~378: Ensure spelling is correct
Context: .... (ed. Lag. ותעימי, read ותִיעֲמֵי; Ar. ויִתְעֲמֵי, Ithpe.).— - Targ. Is. LIX, 11 עָמֵינָא (ed. Lag. עמנא; ed...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~410-~410: Ensure spelling is correct
Context: .... - B. Mets. V, 10 הקור (corr. acc.). - Snh. 20ᵇ קוּדּוֹ Ms. M. his bowl (was all t...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~418-~418: Ensure spelling is correct
Context: ...assacre. - Targ. Is. XXII, 5 (ed. Wil. קְטוֹל). - Ib. XXX, 25 (ed. Wil. קְטוֹל). **Dec...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~436-~436: ‘on account of’ might be wordy. Consider a shorter alternative.
Context: ... once שאובה) (the bath is disqualified) on account of the drawn water which is distinguishabl...

(EN_WORDINESS_PREMIUM_ON_ACCOUNT_OF)


[grammar] ~445-~445: Ensure spelling is correct
Context: ...M. (ed. דרא, transp.), v. אָסָא III.—V. רָדַיָּא. Decision: ### S02160 — קַרְקוּזָאָה ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~453-~453: Ensure spelling is correct
Context: ...1ᵃ (expl. דלעת הרמוצ׳) קרי ק׳ (not קרא) Ḳarḳuz pumpkins. Decision: ### U00704 — שָׁחַר I **Gl...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~481-~481: Ensure spelling is correct
Context: ...B. Bath. 37ᵇ האי מאן … בשִׁיפּוּדֵיה עד וכ׳ Ar. (ed. משיפוליה) if one sells a palm tree...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

docs/v2/body-census.md

[style] ~49-~49: ‘within reach of’ might be wordy. Consider a shorter alternative.
Context: ...er vocabulary is small and closed, well within reach of an exhaustive parse table rather than a...

(EN_WORDINESS_PREMIUM_WITHIN_REACH_OF)

docs/specs/2026-07-11-entry-body-model-design.md

[locale-violation] ~105-~105: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ...ong boundaries are per-entry hand fixes afterwards | | stems | Binyan sections (upstream...

(AFTERWARDS_US)

docs/v2/sefaria-report.md

[style] ~211-~211: To make your writing flow more naturally, try moving ‘also’ before the verb.
Context: ...לָּא"], "verbal_stem": "Ithpa." } ``` (Note also the leading space on the second form — ...

(ALSO_PLACEMENT)

docs/superpowers/plans/2026-07-11-entry-body-model.md

[uncategorized] ~1250-~1250: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...y-run reports and the source, emits the markdown tables listed in the AC (same streaming...

(MARKDOWN_NNP)

🪛 markdownlint-cli2 (0.23.2)
docs/v2/body-review/01-broken-sequences.md

[warning] 81-81: Spaces inside code span elements

(MD038, no-space-in-code)


[warning] 88-88: Spaces inside code span elements

(MD038, no-space-in-code)


[warning] 88-88: Spaces inside code span elements

(MD038, no-space-in-code)


[warning] 91-91: Spaces inside code span elements

(MD038, no-space-in-code)


[warning] 132-132: Spaces inside emphasis markers

(MD037, no-space-in-emphasis)

docs/v2/body-review/02-orphan-refs.md

[warning] 68-68: Files should end with a single newline character

(MD047, single-trailing-newline)

docs/v2/body-review/06-empty-binyan-forms.md

[warning] 37-37: Files should end with a single newline character

(MD047, single-trailing-newline)

docs/v2/body-review/05-unit-segmentation-sample.md

[warning] 17-17: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

docs/v2/sefaria-report.md

[warning] 292-292: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 300-300: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

docs/superpowers/plans/2026-07-11-entry-body-model.md

[warning] 28-28: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 OpenGrep (1.26.0)
admin/pipeline/body/labels.ts

[ERROR] 55-55: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

admin/pipeline/body/migrate-dry.ts

[ERROR] 74-74: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

admin/pipeline/body/cite.ts

[ERROR] 47-47: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)


[ERROR] 55-55: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)


[ERROR] 66-66: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)


[ERROR] 81-81: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)


[ERROR] 96-96: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)


[ERROR] 110-110: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)


[ERROR] 123-123: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)


[ERROR] 134-134: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

admin/pipeline/body/census.ts

[ERROR] 70-70: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

admin/pipeline/body/review.ts

[ERROR] 323-323: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)


[ERROR] 710-710: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

admin/pipeline/body/repairs.ts

[ERROR] 475-475: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

Comment thread admin/pipeline/body/census.ts Outdated
Comment thread admin/pipeline/body/census.ts
Comment on lines +444 to +506
function censusEntry(entry: SourceEntry, acc: Accumulator): void {
acc.entries++;
const marker = entry.content.morphology;
if (marker !== undefined) {
acc.markers.set(marker, (acc.markers.get(marker) ?? 0) + 1);
}

let hasLettered = false;
let hasPluralSection = false;
const hitMarkers = new Set<string>();
for (const sense of walkSenses(entry.content.senses)) {
if (sense.definition !== undefined) {
acc.definitions++;
}
const definition = sense.definition ?? '';
if (letteredRun(definition)) {
hasLettered = true;
}
if (pluralSection(definition)) {
hasPluralSection = true;
}
for (const formMarker of formSectionCandidates(definition)) {
hitMarkers.add(formMarker);
}
const hits = findCitations(definition);
tallyCitations(hits, acc.citations);
tallyBoundaries(definition, hits, acc.boundaries);
tallyIbid(definition, hits, acc.ibid);
}
if (hasLettered) {
acc.lettered.add(entry.rid);
}
if (hasPluralSection) {
acc.pluralSections.add(entry.rid);
}
for (const formMarker of hitMarkers) {
acc.formSections.get(formMarker)?.add(entry.rid);
}

// Sequence numbering is only checked at the top level: nested
// sub-senses (e.g. under a grammar node) commonly restart their own
// numbering, so folding them into one flat sequence manufactures
// false breaks that don't exist in the source.
tallySequence(
entry.rid,
entry.content.senses,
{
...(entry.language_code !== undefined && {
languageCode: entry.language_code,
}),
...(entry.language_reference !== undefined && {
languageReference: entry.language_reference,
}),
...(entry.content.morphology !== undefined && {
morphology: entry.content.morphology,
}),
},
acc.brokenSequences,
);

const opener = classifyOpener(entry.content.senses[0]?.definition ?? '');
acc.preambleOpeners.set(opener, (acc.preambleOpeners.get(opener) ?? 0) + 1);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Reduce the complexity of censusEntry to clear the quality gate.

SonarQube reports a gate failure at this function (cognitive complexity 16 vs 15 allowed), and Biome reports lint/complexity/noExcessiveCognitiveComplexity with a measured complexity of 20. Extract the per-sense loop into a helper. The helper returns the per-entry flags, and censusEntry keeps only the accumulator updates.

♻️ Proposed refactor sketch
+function censusSenses(
+	entry: SourceEntry,
+	acc: Accumulator,
+): { hasLettered: boolean; hasPluralSection: boolean; hitMarkers: Set<string> } {
+	let hasLettered = false;
+	let hasPluralSection = false;
+	const hitMarkers = new Set<string>();
+	for (const sense of walkSenses(entry.content.senses)) {
+		if (sense.definition !== undefined) {
+			acc.definitions++;
+		}
+		const definition = sense.definition ?? '';
+		hasLettered = hasLettered || letteredRun(definition);
+		hasPluralSection = hasPluralSection || pluralSection(definition);
+		for (const formMarker of formSectionCandidates(definition)) {
+			hitMarkers.add(formMarker);
+		}
+		const hits = findCitations(definition);
+		tallyCitations(hits, acc.citations);
+		tallyBoundaries(definition, hits, acc.boundaries);
+		tallyIbid(definition, hits, acc.ibid);
+	}
+	return { hasLettered, hasPluralSection, hitMarkers };
+}
+
 function censusEntry(entry: SourceEntry, acc: Accumulator): void {
 	acc.entries++;
 	const marker = entry.content.morphology;
 	if (marker !== undefined) {
 		acc.markers.set(marker, (acc.markers.get(marker) ?? 0) + 1);
 	}
-
-	let hasLettered = false;
-	let hasPluralSection = false;
-	const hitMarkers = new Set<string>();
-	for (const sense of walkSenses(entry.content.senses)) {
-		if (sense.definition !== undefined) {
-			acc.definitions++;
-		}
-		const definition = sense.definition ?? '';
-		if (letteredRun(definition)) {
-			hasLettered = true;
-		}
-		if (pluralSection(definition)) {
-			hasPluralSection = true;
-		}
-		for (const formMarker of formSectionCandidates(definition)) {
-			hitMarkers.add(formMarker);
-		}
-		const hits = findCitations(definition);
-		tallyCitations(hits, acc.citations);
-		tallyBoundaries(definition, hits, acc.boundaries);
-		tallyIbid(definition, hits, acc.ibid);
-	}
+	const { hasLettered, hasPluralSection, hitMarkers } = censusSenses(entry, acc);
 	if (hasLettered) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function censusEntry(entry: SourceEntry, acc: Accumulator): void {
acc.entries++;
const marker = entry.content.morphology;
if (marker !== undefined) {
acc.markers.set(marker, (acc.markers.get(marker) ?? 0) + 1);
}
let hasLettered = false;
let hasPluralSection = false;
const hitMarkers = new Set<string>();
for (const sense of walkSenses(entry.content.senses)) {
if (sense.definition !== undefined) {
acc.definitions++;
}
const definition = sense.definition ?? '';
if (letteredRun(definition)) {
hasLettered = true;
}
if (pluralSection(definition)) {
hasPluralSection = true;
}
for (const formMarker of formSectionCandidates(definition)) {
hitMarkers.add(formMarker);
}
const hits = findCitations(definition);
tallyCitations(hits, acc.citations);
tallyBoundaries(definition, hits, acc.boundaries);
tallyIbid(definition, hits, acc.ibid);
}
if (hasLettered) {
acc.lettered.add(entry.rid);
}
if (hasPluralSection) {
acc.pluralSections.add(entry.rid);
}
for (const formMarker of hitMarkers) {
acc.formSections.get(formMarker)?.add(entry.rid);
}
// Sequence numbering is only checked at the top level: nested
// sub-senses (e.g. under a grammar node) commonly restart their own
// numbering, so folding them into one flat sequence manufactures
// false breaks that don't exist in the source.
tallySequence(
entry.rid,
entry.content.senses,
{
...(entry.language_code !== undefined && {
languageCode: entry.language_code,
}),
...(entry.language_reference !== undefined && {
languageReference: entry.language_reference,
}),
...(entry.content.morphology !== undefined && {
morphology: entry.content.morphology,
}),
},
acc.brokenSequences,
);
const opener = classifyOpener(entry.content.senses[0]?.definition ?? '');
acc.preambleOpeners.set(opener, (acc.preambleOpeners.get(opener) ?? 0) + 1);
}
function censusSenses(
entry: SourceEntry,
acc: Accumulator,
): { hasLettered: boolean; hasPluralSection: boolean; hitMarkers: Set<string> } {
let hasLettered = false;
let hasPluralSection = false;
const hitMarkers = new Set<string>();
for (const sense of walkSenses(entry.content.senses)) {
if (sense.definition !== undefined) {
acc.definitions++;
}
const definition = sense.definition ?? '';
hasLettered = hasLettered || letteredRun(definition);
hasPluralSection = hasPluralSection || pluralSection(definition);
for (const formMarker of formSectionCandidates(definition)) {
hitMarkers.add(formMarker);
}
const hits = findCitations(definition);
tallyCitations(hits, acc.citations);
tallyBoundaries(definition, hits, acc.boundaries);
tallyIbid(definition, hits, acc.ibid);
}
return { hasLettered, hasPluralSection, hitMarkers };
}
function censusEntry(entry: SourceEntry, acc: Accumulator): void {
acc.entries++;
const marker = entry.content.morphology;
if (marker !== undefined) {
acc.markers.set(marker, (acc.markers.get(marker) ?? 0) + 1);
}
const { hasLettered, hasPluralSection, hitMarkers } = censusSenses(entry, acc);
if (hasLettered) {
acc.lettered.add(entry.rid);
}
if (hasPluralSection) {
acc.pluralSections.add(entry.rid);
}
for (const formMarker of hitMarkers) {
acc.formSections.get(formMarker)?.add(entry.rid);
}
// Sequence numbering is only checked at the top level: nested
// sub-senses (e.g. under a grammar node) commonly restart their own
// numbering, so folding them into one flat sequence manufactures
// false breaks that don't exist in the source.
tallySequence(
entry.rid,
entry.content.senses,
{
...(entry.language_code !== undefined && {
languageCode: entry.language_code,
}),
...(entry.language_reference !== undefined && {
languageReference: entry.language_reference,
}),
...(entry.content.morphology !== undefined && {
morphology: entry.content.morphology,
}),
},
acc.brokenSequences,
);
const opener = classifyOpener(entry.content.senses[0]?.definition ?? '');
acc.preambleOpeners.set(opener, (acc.preambleOpeners.get(opener) ?? 0) + 1);
}
🧰 Tools
🪛 GitHub Check: Lint

[notice] 444-444: lint/complexity/noExcessiveCognitiveComplexity
Excessive complexity of 20 detected (max: 15).

🪛 GitHub Check: SonarCloud Code Analysis

[failure] 444-444: Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=UniquePixels_jastrow&issues=AZ_XPy1yQmNwicMDYzUR&open=AZ_XPy1yQmNwicMDYzUR&pullRequest=36

🤖 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 `@admin/pipeline/body/census.ts` around lines 444 - 506, Reduce cognitive
complexity in censusEntry by extracting the walkSenses per-sense
processing—including definition counting, lettered and plural detection,
form-marker collection, and citation/boundary/ibid tallying—into a helper. Have
the helper return the per-entry flags and collected form markers, then leave
censusEntry responsible only for applying those results to the accumulator and
retaining the existing sequence and opener handling.

Sources: Coding guidelines, Linters/SAST tools

Comment on lines +89 to +92
function findCitations(text: string): CitationHit[] {
if (!text.includes('</a>')) {
return [];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Unterminated anchors are never emitted, which breaks the stated contract. The contract at Lines 6-9 promises one hit per refLink open tag, with malformed: true when no </a> follows. Two sites drop the hit instead: the fast path returns early when the text holds no </a> at all, and the boundary loop breaks when nothing follows the open tag. census.ts tallyCitations therefore undercounts the recoveredLoss damage class it measures.

  • admin/pipeline/body/cite.ts#L89-L92: gate the fast path on class="refLink" instead of </a>, so the scan still runs when no close tag exists.
  • admin/pipeline/body/cite.ts#L114-L118: push { ...hit, malformed: true } before the break, the same way the nested-open branch at Lines 132-134 does.
📍 Affects 1 file
  • admin/pipeline/body/cite.ts#L89-L92 (this comment)
  • admin/pipeline/body/cite.ts#L114-L118
🤖 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 `@admin/pipeline/body/cite.ts` around lines 89 - 92, Update findCitations in
admin/pipeline/body/cite.ts at lines 89-92 to gate the fast path on the presence
of class="refLink" rather than </a>, so open tags are scanned without closing
tags; at lines 114-118, push the current hit with malformed: true before
breaking when no closing content follows the open tag, matching the nested-open
handling.

Comment thread admin/pipeline/body/dry-run-verify.ts Outdated
| S00252 | קוֹדַשׁ | `[[null,"קודש קוֹדַשׁ",null]]` | ch. same holiness, sanctuary &c. Targ. Ex. XXIX, 29. Targ. Ps. LI, 13. Targ. Ex. XXVIII, 29; a. fr.—Pl. קוּדְשִׁין, קוּדְשַׁיָּא. Targ. Lev. XXI, 22. Ib. XXII, 2; a. fr.—קודש ק׳ the Holy of Holies. Targ. Ex. XXVI, 33; a. fr. the Holiness, the Lord, usu. with בריך הוא (abbrev. קב"ה), v. קָדוֹשׁ. Targ. Y. Num. XXI, 34. Targ. Y. Gen. XXV, 21; a. fr.—Ber. 7ᵃ ומי… | |
| S01101 | *קיפוסולין | `[[null,"בקיפוסולין של מצרים וכ׳","Joseph was buried in (the necropolis of) Thebes"]]` | , prob. to be read: קְיוֹסְפּוֹלִין (a perversion of דְּיוֹסְפּוֹלִין; cmp. קאניסין) Diospolis; ק׳ של מצרים Diospolis in Egypt = Thebes. Mekh. B’shall., s. 1 בק׳ של מצרים וכ׳ Joseph was buried in (the necropolis of) Thebes; (Tosef. Sot. IV, 7 בקברי מלכים; Ex. R. s. 20 בתוך הפלטורין וכ׳ in the palaces (tomb chambers) in the manner as kings were buried; v. קְב… | |

I confirmed with Sefaria Devs that the quotes field is a leftover from a previous design choice, it was never validated by them so not supprised has these.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the provenance note.

Change supprised to surprised. Prefer Sefaria developers over Sefaria Devs in this maintainer document.

🧰 Tools
🪛 LanguageTool

[grammar] ~23-~23: Ensure spelling is correct
Context: ..., it was never validated by them so not supprised has these.

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 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 `@docs/v2/body-review/03-quotes-stragglers.md` at line 23, Update the
provenance note to use “Sefaria developers” instead of “Sefaria Devs” and
correct the typo “supprised” to “surprised,” preserving the rest of the note.

Source: Linters/SAST tools

Comment thread docs/v2/body-review/04-label-quarantines.md Outdated
Comment thread docs/v2/sefaria-report.md Outdated
Comment on lines +156 to +167
## 6. Duplicated nested anchors (475 anchors)

Identical anchors nested one inside the other.

**Example — `A00085`:**

```html
<a … href="/Jastrow,_אבהנוס.1" data-ref="Jastrow, אבהנוס 1"><a … href="/Jastrow,_אבהנוס.1" data-ref="Jastrow, אבהנוס 1">אבהנוס</a></a>
```

**Fix:** drop the outer duplicate. **Detection:** `<a` immediately
followed by another `<a` with identical `href`/`data-ref`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use one scoped duplicate-anchor metric.

The files report 475 and 1,230 anchors. The complete register value is 475 definition anchors plus 755 language_reference anchors. Make the scope explicit or update both documents to the same total.

  • docs/v2/sefaria-report.md#L156-L167: label 475 as definitions-only or report 1,230.
  • docs/v2/upstream-issues.md#L21-L21: retain the 1,230 total only with the all-field scope stated.
📍 Affects 2 files
  • docs/v2/sefaria-report.md#L156-L167 (this comment)
  • docs/v2/upstream-issues.md#L21-L21
🤖 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 `@docs/v2/sefaria-report.md` around lines 156 - 167, The duplicated
nested-anchor metric must use an explicit scope consistently: in
docs/v2/sefaria-report.md lines 156-167, either label 475 as definition anchors
only or change it to the all-field total of 1,230; in docs/v2/upstream-issues.md
line 21, retain 1,230 only if the all-field scope, including 475 definition and
755 language_reference anchors, is stated.

Comment thread docs/v2/sefaria-report.md
Comment on lines +292 to +303
```
…from the mouth of the Lord.—Pl. גְּבוּרוֹת 1) manifestations of
Divine power, wonders. … —2) mighty deeds…
```

The `1)` and `2)` here are not sub-points of sense 3 — they are the
plural lemma's own senses. A faithful structure would be, in outline:

```
senses: 1) strength… 2) … 3) might of God…
plural (גְּבוּרוֹת): 1) manifestations of Divine power… 2) mighty deeds…
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add languages to both fenced code blocks.

Use text for the two examples. This fixes the MD040 warnings and keeps the report lint-clean.

🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 292-292: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 300-300: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 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 `@docs/v2/sefaria-report.md` around lines 292 - 303, Add the text language
identifier to both fenced code blocks in the documented examples, including the
block showing the current structure and the block showing the faithful
structure, while leaving their contents unchanged.

Source: Linters/SAST tools

Comment thread docs/v2/upstream-issues.md Outdated
27 comments triaged, each verified against code before acting.

Code:
- source: flush TextDecoder after the last chunk so a stream
  ending mid-multi-byte-sequence fails visibly instead of
  silently shortening the tail line
- migrate-dry: contain repair drift per entry, list every
  failure in the report, rethrow after the walk (stays loud,
  one run reports all drifts); repairFailures in summary
- repairs/migrate-dry: single walkSensesDeep (exported)
- repairs.test: fixture paths via import.meta.dir (CWD-free)
- labels.test: corpus sweep tallies while streaming
- lettered.test: stale 5-entry docstring -> 9
- lint infos: named capture group, JSDoc asterisk, explicit
  length check, array destructuring

Docs:
- 00-INDEX: statuses awaiting review -> reviewed 2026-08-05
- 01: section-level decision paragraph (per design changelog);
  no-change rows noted as superseded by the split follow-up
- 02/03/04: typo + grammar fixes in maintainer notes (meaning
  unchanged), final newline
- body-migration: 129/3-sample -> 133/4; body-dryrun 60.8%;
- body-census: lettered fixture is a reviewed 9-rid sample
- sefaria-report: duplicate-anchor scope 475 vs 1,230 stated,
  fenced block language; upstream-issues #1 lists served AND
  print headword forms
- tasks.json lastUpdated matches final revision

Skipped with reasons (PR comment): cite.ts no-close fast path
(pinned test, zero corpus incidence), buildStem loud-fail
(dry-run reports via schemaFailures by contract), excessive-
lines/complexity infos (accepted budget), bun version pin
(CI concern), notes mechanism (tracked as issue #38).

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
@UniquePixels

Copy link
Copy Markdown
Owner Author

CodeRabbit round-2 disposition (27 comments)

Fixed in fb08458 (22): decoder flush in source.ts; migrate-dry per-entry repair-drift containment with post-walk rethrow; walkSensesDeep deduped; repairs.test fixture paths via import.meta.dir; labels corpus sweep streams; lettered docstring count; four lint-info cleanups (named capture group, JSDoc asterisk, explicit length check, destructuring); all doc corrections (00-INDEX statuses, 01 section-level decisions, 02/03/04 note typos, 133/4 schema-sample propagation, 60.8% share, lettered-fixture wording, duplicate-anchor scope, served headword forms, fence language, tasks.json lastUpdated).

Skipped, with reasons (5):

  • cite.ts no-close early return: deliberate, pinned by test, and measured zero occurrences over all 32,512 corpus entries.
  • buildStem empty-stem fallback: the dry run's contract is report-not-throw; a missing verbal_stem surfaces as a schemaFailures rid, and the full-corpus recount shows zero.
  • Excessive-lines / cognitive-complexity infos: accepted budget, documented in the file headers; restructuring is out of scope for this PR.
  • Bun runtime pin: CI environment concern, not a test-file concern.
  • notes mechanism tracking: now registered as Notes mechanism for intentional print deviations #38.

The no-byte-change disposition class itself is superseded by the follow-up sense-structure-repair spec (maintainer ruling 2026-08-06); tracked on branch spec/sense-structure-repair.

🤖 Generated with Claude Code

@sonarqubecloud

sonarqubecloud Bot commented Aug 6, 2026

Copy link
Copy Markdown

@UniquePixels

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

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.

@UniquePixels

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 6, 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.

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 `@admin/pipeline/body/migrate-dry.ts`:
- Around line 235-239: Update the error message in the repairFailures handling
block to use “entry” when there is exactly one failure and “entries” when there
are multiple failures, instead of emitting the literal “entr(y/ies)” label.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9a6e4855-e57b-4b84-9124-873293c132a7

📥 Commits

Reviewing files that changed from the base of the PR and between 1cb7d8d and fb08458.

📒 Files selected for processing (20)
  • admin/pipeline/body/census.ts
  • admin/pipeline/body/dry-run-verify.ts
  • admin/pipeline/body/dry-run.test.ts
  • admin/pipeline/body/labels.test.ts
  • admin/pipeline/body/lettered.test.ts
  • admin/pipeline/body/migrate-dry.ts
  • admin/pipeline/body/repairs.test.ts
  • admin/pipeline/body/repairs.ts
  • admin/pipeline/body/source.ts
  • docs/superpowers/plans/2026-07-11-entry-body-model.md.tasks.json
  • docs/v2/body-census.md
  • docs/v2/body-dryrun.md
  • docs/v2/body-migration.md
  • docs/v2/body-review/00-INDEX.md
  • docs/v2/body-review/01-broken-sequences.md
  • docs/v2/body-review/02-orphan-refs.md
  • docs/v2/body-review/03-quotes-stragglers.md
  • docs/v2/body-review/04-label-quarantines.md
  • docs/v2/sefaria-report.md
  • docs/v2/upstream-issues.md
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Workers Builds: jastrow
⚠️ CI failures not shown inline (1)

GitHub Check: Workers Builds: jastrow: Workers Builds: jastrow

Conclusion: failure

View job details

Build ID: [c3edbe42-ee40-463f-ad83-ea05e7f32b19](https://dash.cloudflare.com/cf68e0017c53376defadebeecd91fda2/workers/services/view/jastrow/production/builds/c3edbe42-ee40-463f-ad83-ea05e7f32b19)
Script: [jastrow](https://dash.cloudflare.com/cf68e0017c53376defadebeecd91fda2/workers/services/view/jastrow/production)
🧰 Additional context used
📓 Path-based instructions (2)
**

⚙️ CodeRabbit configuration file

**: General project rules:

  • This is a vanilla JS static site PWA. No bundler, no framework, no npm packages at runtime.
  • All JS runs in the browser unless under admin/ (maintainer tooling, which uses Bun).
  • Repo layout (v2): app/ public app, admin/ tooling (incl. admin/pipeline/), data/ data only.
  • Biome enforces lint and formatting.
  • DOMPurify is loaded via CDN with SRI for XSS sanitization.

Files:

  • docs/v2/body-dryrun.md
  • docs/v2/upstream-issues.md
  • admin/pipeline/body/lettered.test.ts
  • docs/v2/body-review/00-INDEX.md
  • docs/v2/body-review/04-label-quarantines.md
  • docs/v2/body-review/03-quotes-stragglers.md
  • docs/v2/body-review/02-orphan-refs.md
  • admin/pipeline/body/labels.test.ts
  • docs/v2/body-review/01-broken-sequences.md
  • docs/v2/sefaria-report.md
  • admin/pipeline/body/repairs.test.ts
  • admin/pipeline/body/source.ts
  • admin/pipeline/body/dry-run.test.ts
  • docs/v2/body-migration.md
  • admin/pipeline/body/census.ts
  • docs/superpowers/plans/2026-07-11-entry-body-model.md.tasks.json
  • docs/v2/body-census.md
  • admin/pipeline/body/dry-run-verify.ts
  • admin/pipeline/body/migrate-dry.ts
  • admin/pipeline/body/repairs.ts
admin/**

⚙️ CodeRabbit configuration file

admin/**: Maintainer tooling that runs on Bun (not deployed). Includes:

  • admin/pipeline/ — data pipeline from the Sefaria source (fetch, transform, validate, emit)
  • Admin tool v2 (Phase 3) will live here too
  • console and sequential awaits over streams are expected here

Files:

  • admin/pipeline/body/lettered.test.ts
  • admin/pipeline/body/labels.test.ts
  • admin/pipeline/body/repairs.test.ts
  • admin/pipeline/body/source.ts
  • admin/pipeline/body/dry-run.test.ts
  • admin/pipeline/body/census.ts
  • admin/pipeline/body/dry-run-verify.ts
  • admin/pipeline/body/migrate-dry.ts
  • admin/pipeline/body/repairs.ts
🧠 Learnings (1)
📚 Learning: 2026-07-05T16:14:54.518Z
Learnt from: UniquePixels
Repo: UniquePixels/jastrow PR: 25
File: admin/pipeline/fetch.ts:48-75
Timestamp: 2026-07-05T16:14:54.518Z
Learning: For maintainer-run pipeline scripts under admin/pipeline (including admin/pipeline/fetch.ts), avoid adding or recommending a whole-transfer AbortSignal.timeout() for large downloads (e.g., multi-GB dumps). A fixed end-to-end timeout can abort valid successful runs. If cancellation/robustness is needed, prefer an inter-chunk idle timeout (no progress for N seconds) with appropriate retry behavior rather than timing out the entire transfer. Until the admin tool provides UI-driven cancellation/progress, the accepted recovery path for manual reruns is ctrl-C and rerunning the script.

Applied to files:

  • admin/pipeline/body/lettered.test.ts
  • admin/pipeline/body/labels.test.ts
  • admin/pipeline/body/repairs.test.ts
  • admin/pipeline/body/source.ts
  • admin/pipeline/body/dry-run.test.ts
  • admin/pipeline/body/census.ts
  • admin/pipeline/body/dry-run-verify.ts
  • admin/pipeline/body/migrate-dry.ts
  • admin/pipeline/body/repairs.ts
🪛 OpenGrep (1.26.0)
admin/pipeline/body/census.ts

[ERROR] 70-70: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

🔇 Additional comments (20)
admin/pipeline/body/source.ts (1)

31-34: LGTM!

admin/pipeline/body/labels.test.ts (1)

134-140: LGTM!

admin/pipeline/body/lettered.test.ts (1)

10-10: LGTM!

admin/pipeline/body/census.ts (1)

63-72: LGTM!

Also applies to: 88-88

docs/v2/body-review/03-quotes-stragglers.md (1)

23-23: Apply the previous spelling and provenance correction.

Line 23 still uses Sefaria Devs and supprised. Use Sefaria developers and surprised.

admin/pipeline/body/dry-run-verify.ts (1)

166-166: LGTM!

admin/pipeline/body/dry-run.test.ts (1)

96-96: LGTM!

docs/superpowers/plans/2026-07-11-entry-body-model.md.tasks.json (1)

151-151: LGTM!

admin/pipeline/body/migrate-dry.ts (1)

25-28: LGTM!

Also applies to: 59-59, 132-132, 164-175, 218-218

docs/v2/body-review/04-label-quarantines.md (1)

16-16: LGTM!

docs/v2/sefaria-report.md (1)

156-161: LGTM!

Also applies to: 303-303

docs/v2/upstream-issues.md (1)

16-16: LGTM!

admin/pipeline/body/repairs.ts (1)

627-633: LGTM!

admin/pipeline/body/repairs.test.ts (1)

7-12: LGTM!

docs/v2/body-census.md (1)

178-180: LGTM!

docs/v2/body-dryrun.md (1)

178-178: LGTM!

docs/v2/body-migration.md (1)

28-28: LGTM!

docs/v2/body-review/00-INDEX.md (1)

21-27: LGTM!

docs/v2/body-review/01-broken-sequences.md (1)

18-26: 🗄️ Data Integrity & Integration

Track the superseded structural repair as an explicit limitation.

These lines state that the no-byte-change rows require a structural split on a follow-up branch. Add the issue or branch reference and confirm that PR #36 intentionally leaves this repair out of scope. Otherwise, docs/v2/body-migration.md can be read as final while 34 sequence issues remain.

docs/v2/body-review/02-orphan-refs.md (1)

68-68: LGTM!

Comment on lines +235 to +239
if (report.repairFailures.length > 0) {
throw new Error(
`repair drift on ${report.repairFailures.length} entr(y/ies):\n${report.repairFailures.join('\n')}`,
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use a valid singular or plural label.

Line 237 emits entr(y/ies) literally. This makes the aggregate error unclear. Select entry for one failure and entries for multiple failures.

Proposed change
 	if (report.repairFailures.length > 0) {
+		const noun = report.repairFailures.length === 1 ? 'entry' : 'entries';
 		throw new Error(
-			`repair drift on ${report.repairFailures.length} entr(y/ies):\n${report.repairFailures.join('\n')}`,
+			`repair drift on ${report.repairFailures.length} ${noun}:\n${report.repairFailures.join('\n')}`,
 		);
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (report.repairFailures.length > 0) {
throw new Error(
`repair drift on ${report.repairFailures.length} entr(y/ies):\n${report.repairFailures.join('\n')}`,
);
}
if (report.repairFailures.length > 0) {
const noun = report.repairFailures.length === 1 ? 'entry' : 'entries';
throw new Error(
`repair drift on ${report.repairFailures.length} ${noun}:\n${report.repairFailures.join('\n')}`,
);
}
🤖 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 `@admin/pipeline/body/migrate-dry.ts` around lines 235 - 239, Update the error
message in the repairFailures handling block to use “entry” when there is
exactly one failure and “entries” when there are multiple failures, instead of
emitting the literal “entr(y/ies)” label.

@UniquePixels
UniquePixels merged commit 27dc2e2 into v2 Aug 6, 2026
13 of 14 checks passed
@UniquePixels
UniquePixels deleted the spec/entry-body-model branch August 6, 2026 18:22
UniquePixels added a commit that referenced this pull request Aug 6, 2026
Docstring-coverage pass over admin/pipeline (maintainer request,
PR #36 follow-up): every function and functional const in the
body, provenance, fetch, and lib modules now carries a JSDoc
stating its contract — 193/194 documented (the remainder is a
script-body constant). No behavior change: bun qa green, review
regen guard verified intact.

Also: migrate-dry's repair-drift error now pluralizes entry/
entries properly (CodeRabbit nit).

Signed-off-by: Brian L. <brian@uniquepixels.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bulk-data-ok Large data-file changes are intentional; skip line-by-line data review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants