Repository navigation
Commit 5c0e4fd
<!-- claude-projects-attribution: {"github_login":"os-sales"} -->
_Requested by **Sales** · [project
thread](https://claude.ai/code/project/chan_01D5bWFY3rFzgJcytD5gD4Uu?thread=cmsg_01D5bWFY3rFzgJcytD5gD4UuAu38qzG6MovVEhL1F1uy7R)_
Part of #25522
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6348891160 + 6441032442
## 维护者速读
- **改了什么**:把 `engine.ts`「删除级联与引用遍历」区里 5 个方法体(级联删除集合的收集遍历
`collectCascadeDeleteSet`、级联内 `restrict` 判定
`refuseRestrictsInsideOwnCascade`、`409 DELETE_RESTRICTED` 拒绝的构造
`deleteRestrictedError`、引用探测过滤 `referenceProbeFilter`、引用检查提权记录
`recordReferenceCheckElevation`)原样搬进新文件
`engine-delete-cascade.ts`;类上的方法签名、注释、位置不变,方法体换成转交。只被搬走代码读的顶层 helper
`cascadeReachOf` 随之搬走;与留下代码共用的 4 个 helper 和 `CascadeDeleteSet` 类型原地加
`export`、由新文件导入(不复制)。`engine.ts` 22,110 → 21,874 行。
- **为什么改**:#25522 按缝拆分 `engine.ts` 的第 19 刀。此区此前因 #26930
在改而被排除,现已空出。重新测价:区内 24 个成员里,读私有静态成员的 10 个方法(含
`walkReferencingRelations`、`cascadeDeleteRelations`、`planCascadeAtomicity`)和
7 个私有静态本身按系列限制必须留下,`cascadeRelationBehavior` 因
`federated-injected-column-readers.test.ts` 按同文件读 `via` helper
也留下,所以实际可搬的是 5 个付得起转交成本的方法体,净 −236 行(不是派单估计的 18 个 / 约 1,069 行)。
- **风险与回滚**:纯搬移,无行为变化;公开 `.d.ts`
六个文件与基线逐字节相同(含阳性对照);运行期导出名单与函数名相同;构建产物只多出新文件一个区段,外部包首次加载顺序不变;一次性晚绑定探针在新旧两版构建产物上逐行一致。回滚
= revert 本 PR。
- **先看**:`packages/objectql/src/engine-delete-cascade.ts`(5 个函数与
`DeleteCascadeHost`)、`packages/objectql/src/engine.ts` 里 5 个转交桩、新导入行与 5
处原地 `export`、`content/docs/permissions/system-context.mdx` 第 29
行登记的锚点改指新文件。
- **两分钟验证**:`pnpm --filter @objectstack/objectql exec vitest run
--project local --maxWorkers=2 src/engine-cascade-delete.test.ts
src/engine-cascade-delete-sibling-restrict.test.ts
src/engine-cascade-delete-tree.test.ts`,应见三个文件全部通过(级联收集、同级 restrict
判定与拒绝信封各自走到的测试)。
- **需要你做的**:无,席位落地。
Cut 19 of the `packages/objectql/src/engine.ts` split (#24586 ruling A,
recorded in `6270097840`), under the claim `6487687348`. Five bodies of
the "Delete cascade and reference walking" section move unedited into a
new module, `packages/objectql/src/engine-delete-cascade.ts`, behind
`DeleteCascadeHost`. No behaviour changes. Every published declaration
file is byte-identical to the base. #25522 stays open for the later
cuts.
Branch `claude/project-thread-f9p63p` (the card thread's harness-pinned
branch), cut from `origin/main` at `c4c515ad3c`, with `origin/main`
`7e200b4a68` merged in before this PR was opened (that merge touched
none of this diff's paths).
## What changes
### Why this area, and why only five bodies
The claim names this section: it was excluded from cuts 17 and 18 while
#26930 was open in it, and #26930 and #27073 have since merged. Its old
price (−248) was stale, so it was re-priced member by member on
`c4c515ad3c` (`engine.ts` 22,110 lines, blob `50a504332d70`). The
section runs from `planCascadeAtomicity` to `organizationOwnedRowCounts`
(base lines 17,647 to 19,591) and holds 27 members.
| member | body lines | disposition |
|---|---|---|
| `planCascadeAtomicity` | 81 | stays: reads the private statics
`MAX_CASCADE_DEPTH`; also a liveness / reader-test site |
| `warnCascadeNotAtomic` | 12 | stays: a host of three members costs 10
lines, pays 2 |
| `referenceProbeFilter` | 13 | **moves** (reads no member; direct
call), −11 |
| `storedReferenceIncludes`, `remainderAfterMemberRemoval`,
`referenceCheckContext` | 7, 2, 1 | stay: private statics |
| `recordReferenceCheckElevation` | 24 | **moves**, −18 (its
system-context census row is re-keyed) |
| `dependentCountIsDisclosable` | 49 | stays: reads the private static
`storedReferenceIncludes` |
| `cascadeDeleteRelations` | 45 | stays: reads `MAX_CASCADE_DEPTH`;
`packages/spec/liveness/field.json` names
`engine.ts#cascadeDeleteRelations` |
| `REFERENCE_PROBE_BATCH` | - | stays: private static |
| `collectCascadeDeleteSet` | 64 | **moves**, −57 |
| `cascadeRelationBehavior` | 60 | stays:
`federated-injected-column-readers.test.ts` checks the
`organizationOwnedRowCounts` row's `via: 'cascadeRelationBehavior'` by
reading that helper in the SAME file as the site; moving it would mean
changing the test's logic, not re-keying a row |
| `fileReferenceCheckElevation` | 4 | stays: pays nothing (stub 5 lines)
|
| `probeReferencingRows` | 100 | stays: reads `referenceCheckContext`,
`storedReferenceIncludes` |
| `referenceProbeFilterOfSet` | 8 | stays: pays 3 |
| `probeReferencingRowsOfSet` | 38 | stays: reads
`REFERENCE_PROBE_BATCH` |
| `walkReferencingRelations` | 318 | stays: reads
`keepsOrganizationReference`, `remainderAfterMemberRemoval` |
| `refuseRestrictsInsideOwnCascade` | 74 | **moves**, −65 |
| `deleteRestrictedError` | 81 | **moves**, −74 |
| `isTenantColumnSetNull` | 5 | stays: pays 3, and a reader-test key
names it |
| `outlivesOrganization`, `keepsOrganizationReference`,
`organizationCountContext` | 2, 2, 5 | stay: private statics |
| `countReferencingRowsOutside` | 11 | stays: reads
`organizationCountContext` |
| `organizationCountIsDisclosable` | 9 | stays: pays 2 |
| `refuseOrganizationDeleteWhileOwned` | 38 | stays: reads
`outlivesOrganization` |
| `organizationOwnedRowCounts` | 23 | stays: reads
`outlivesOrganization`, `organizationCountContext`; public |
So the order's hypothesis ("~18 movable bodies, ~1,069 lines") does not
hold: the series limit on private statics keeps 17 members, the largest
body (`walkReferencingRelations`, 318 lines) among them, and the five
that move pay −225 in bodies, −236 in all. One PR, under 3,000 changed
lines (753), so no further split was needed.
### The shape
- The class keeps all five methods with name, modifiers, signature,
docblock and position. A body becomes one host literal of exactly the
`DeleteCascadeHost` members it reads, plus a `.call`, marked `[#25522
cut 19]`, as cuts 8 and 10 to 18 did. `referenceProbeFilter` reads no
member, so its stub calls the function directly. The one field read
(`logger`, by `recordReferenceCheckElevation`) goes as a getter over a
`readLogger` closure; the methods go as late-bound closures
(`cascadeRelationBehavior`, `fileReferenceCheckElevation`,
`probeReferencingRowsOfSet`, `deleteRestrictedError`,
`referenceProbeFilter`, `validationMessageContext`,
`dependentCountIsDisclosable`, `objectDisplayLabel`), so a double set on
the engine is still the one a call reaches. No moved body assigns a
field, so there is no setter (`6430872749` not needed).
- **Series limits.** All five are private with declared return types, so
each `.d.ts` line stays `private NAME;`. No moved body reads a private
static, has a `this.FIELD.delete/insert/update(` site, calls
`this.insert` / `this.update` / `this.delete`, or carries an
`engine.ts#NAME` liveness pointer.
- **Helpers, under the cut-14 seat ruling `6432376812`.** The bodies
read `cascadeMemberKey`, `cascadeSetAdd`, `cascadeSetHas`,
`declaredMultiValued` and the `CascadeDeleteSet` interface, all also
read by bodies that stay (`cascadeDeleteRelations`,
`walkReferencingRelations`, `countReferencingRowsOutside`,
`resolveOptionDefault` and `probeReferencingRows` for
`declaredMultiValued`). Each gains `export` in place, byte for byte
otherwise, and the module imports them from `./engine.js` (values; the
interface type-only). `cascadeReachOf` is read only by
`refuseRestrictsInsideOwnCascade`, so it moves with it, byte-identical.
Nothing re-exports any of them from the package entry.
- **Imports.** `renderOperationMessage` (`@objectstack/spec/system`) and
`resolveFieldLabel` (`./validation/record-validator.js`) were read in
`engine.ts` only by `deleteRestrictedError`, so they leave `engine.ts`'s
import lists (one specifier each; both modules are still imported there
for other names) and the module imports them. The module also imports
`ServiceObject` and `ExecutionContext` as types.
- **Load order (measured).** `engine.ts` imports the module right after
cut 16's type import, after every module the new one imports, so no
module is evaluated earlier than before. On the head bundles, with the
`// src/engine.ts` markers set aside, the `// src/...` region order
equals the base's with one line added, `// src/engine-delete-cascade.ts`
(`index.mjs` 101 to 102 regions, `core.mjs` 90 to 91, `index.js` 102 to
103, `core.js` 91 to 92). The external modules load in the same
first-occurrence order (`index.mjs` import specifiers, deduplicated in
order: md5 `853c7898…` both). The ESM bundle has one more `import`
statement (150 to 151 in `index.mjs`, 132 to 133 in `core.mjs`; CJS
`require(` 150 to 151 / 132 to 133): the module's own
`renderOperationMessage` import from `@objectstack/spec/system`, a
package `engine.ts` already loads first, so no load moves.
### Net lines
`engine.ts` goes from 22,110 to 21,874 lines, **net −236** (42 added,
278 removed). The module is 429 lines. The diff against `origin/main` is
753 changed lines over 4 files (+473 / −280).
### Readers of the moved lines
- **`content/docs/permissions/system-context.mdx`**:
`recordReferenceCheckElevation` holds row 29's elevation read
(`context?.isSystem`). The register row is re-keyed from
`engine.ts#recordReferenceCheckElevation` to
`engine-delete-cascade.ts#recordReferenceCheckElevation` (moved to its
sorted place); the row's own Symbol cell names the symbol only and is
unchanged. `node scripts/check-system-context-census.mjs`: OK (154 read
sites, register matches the tree).
- **`docs/qa/platform-checklist/areas/records-forms.json`**: one source
citation, `packages/objectql/src/engine.ts#required`, named the
`required` local of `deleteRestrictedError`; re-pointed to
`engine-delete-cascade.ts#required`, its text otherwise unchanged.
`check-platform-checklist --changed-from origin/main`: 13 judged, 0
lost; the full checklist gate: OK.
- `federated-injected-column-readers.test.ts` keys name
`cascadeRelationBehavior`, `planCascadeAtomicity`,
`organizationOwnedRowCounts` and `isTenantColumnSetNull`, all of which
stay; no moved body holds a seam use, and the test passes.
`packages/spec/liveness/field.json` names
`engine.ts#cascadeDeleteRelations`, which stays: nothing under
`packages/spec` changes.
- Prose mentions of moved names outside the package (`packages/spec`
CHANGELOG/comments, `engine-cascade-delete.test.ts` and
`delete-reference-cleanup-system-identity.test.ts` comments, a runtime
integration test docblock naming
`ObjectQL.refuseRestrictsInsideOwnCascade`) name the method by
behaviour, and the method still exists on the class.
- **Read-seam census.** `check-durability-degradation-log-level --list`
at base and head: identical once line numbers are masked (165 lines). No
moved body guards a storage read.
- **No ADR anchor paragraph describes a moved body** (the `engine.ts`
entry is the transaction-seam paragraph), so the module needs no anchor
entry of its own.
- **Decision-letter count:** `check-adr-anchors` at base `c4c515ad3c`
(clean checkout): **1,900** decision-letter citations on the anchored
surface, 60,466 resolving citations across 8,527 files. At head:
**1,900**, 60,466 across 8,528. The moved bodies carry no `[ADR-NNNN
Dn]` letter.
## Why
#25522 splits `engine.ts` one seam at a time so that a change to one
area reads, reviews and conflicts as that area alone. The delete-cascade
section is the largest section left and was free once #26930 merged.
Nothing about what the engine does changes.
## Tests
No test is added and none is edited: the move is proved by identity, not
by new behaviour.
<details><summary>Public <code>.d.ts</code>: byte-identical (ruling
<code>6348891160</code> item 1), with a positive control</summary>
Built `@objectstack/objectql` at the base (`c4c515ad3c`, `engine.ts`
blob `50a504332d70`, no module; `turbo run build
--filter=@objectstack/objectql...`, 14 of 14 tasks) and at head
(`engine.ts` blob `a5687d70a2f0`; `pnpm --filter @objectstack/objectql
build`). The builds are the moved code, not a stale cache:
`collectCascadeDeleteSet.call(host` and `//
src/engine-delete-cascade.ts` each occur 0 times in the base
`dist/index.mjs` and once in the head's.
| file | sha256 base = head | raw-diff lines |
|---|---|---|
| `core.d.ts` |
`bdc32f3004ee12903aba75d2f07929f8e8abdacc135f7ca65e6b66e625a16876` | 0 |
| `core.d.mts` |
`ae601360109a2117cbcac69f9a5d28c5334cdff8abed80b35057fe0dd41de73b` | 0 |
| `index.d.ts` |
`bcb31057f6f7e50f34792c621026e92bc95764160843924aa25c72c476073505` | 0 |
| `index.d.mts` |
`943aad8e39db6806e5585acd220b33be7219804cb27a225052b1feea873fb64e` | 0 |
| `util-6U6fCMd3.d.ts` |
`146d109c8c793af1dc26780171712da9570d87eef2e4fcadebfe32e62fb7fa37` | 0 |
| `util-6U6fCMd3.d.mts` |
`146d109c8c793af1dc26780171712da9570d87eef2e4fcadebfe32e62fb7fa37` | 0 |
- Every declaration file is **raw byte-identical**, and no chunk is
renamed (`util-6U6fCMd3` at both), so `6348891160` item 1 holds with no
normalisation and the `6441032442` reorder bar is not reached. The
`6441032442` normaliser (`dtsnorm.mjs`) lives in another project's files
and was not available in this thread's container; with a 0-line raw diff
on all six files there is nothing for it to normalise.
- The run-time export lists are equal too: `index` 182 names and `core`
54, ESM and CJS, and a sha256 over every export's name and function
`.name` is the same at base and head (`2aaa13a11288fd84…` /
`70d1bf1f346b2793…`), so no bundler same-name rename happened.
- (e) After the head build, the full `turbo run build` (115 of 115
tasks, the dependents' DTS builds included) and `pnpm --filter
@objectstack/core typecheck` ran: exit 0 each. (P2)
`packages/objectql/package.json` `exports` names `./dist/index.*` and
`./dist/core.*` only; (P3) `git grep -n -E
'objectql/dist|driver-sql/dist' -- scripts package.json`: 0 hits.
**Positive control.** On the head, `node scripts/ablation-replace.mjs`
dropped `private` from ` private async deleteRestrictedError(args: {` (a
moved member's stub; anchor 1 to 0, blob `a5687d70a2f0` to
`1850f07b29d3`) and rebuilt (exit 0). The chunk is renamed
`util-Dd_AzMXV` and now publishes `deleteRestrictedError(args: { object:
string; … context: ExecutionContext | undefined; }): Promise` of `Error`
(line 11117, where the head prints `private deleteRestrictedError;`);
every declaration file's sha256 changes (`core.d.ts` `68f57645…`,
`index.d.ts` `b9136807…`, chunk `519be62f…`). The restore leg put the
blob back to `a5687d70a2f0` (`git diff HEAD` empty), and the rebuild
that followed produced six declaration files and four bundles that
compare equal to the head build.
</details>
<details><summary>AST compare (move-only)</summary>
A one-off script (TypeScript compiler API; leaf tokens by recursive
`getChildren`) on base `engine.ts` against head `engine.ts` plus the
module:
- The five moved bodies are **SAME** (parameters, return type, `async`,
body tokens, and every body line equal after one level of indent):
`referenceProbeFilter` 97 tokens / 13 lines,
`recordReferenceCheckElevation` 107 / 24, `collectCascadeDeleteSet` 582
/ 64, `refuseRestrictsInsideOwnCascade` 810 / 74,
`deleteRestrictedError` 323 / 81. Negative control: one changed token in
the module copy (`slice(1, -1)` to `slice(1, -2)`) reads DIFF.
- `class ObjectQL`: 330 of 330 members kept, in the same order; 325
byte-identical including leading trivia, and the 5 stubs keep docblock,
modifiers and signature identical.
- Top level: 229 of 238 base statements byte-identical. The other 9: the
two import lists that lose one specifier; `declaredMultiValued`,
`CascadeDeleteSet`, `cascadeMemberKey`, `cascadeSetHas` and
`cascadeSetAdd`, each with `export` added and otherwise byte-identical;
`cascadeReachOf`, moved into the module byte-identical; and the class.
The head adds one statement: the module import.
</details>
<details><summary>Late-binding probe (base and head
<code>dist</code>)</summary>
`zz-probe-cut19.mjs` (a one-off, not committed) loads the built
`ObjectQL` from each `dist/` and drives the five bodies with doubles set
on the instance after construction: `referenceProbeFilter` on a
single-valued lookup, a multi-valued lookup, an id needing JSON escaping
(the `$or` arm) and a multiselect; `recordReferenceCheckElevation` with
`userId`, `actor`, `isSystem` and no context, the `logger` replaced
twice after construction; `collectCascadeDeleteSet` over a three-level
master-detail fixture with every host member replaced and each call
recorded in order, with and without `fileElevations`;
`refuseRestrictsInsideOwnCascade` on both sets after a second generation
of doubles is wired (it reaches the second generation, and refuses
through the replaced `deleteRestrictedError` with the replaced
`referenceProbeFilter`'s filter); and the class's own
`deleteRestrictedError` with its three host members replaced, for a
`restrict` and a `required` relation, with count disclosure off and on.
The 16 output lines are identical on base `c4c515ad3c` and head (the 5
construction log lines, which carry timestamps, set aside); stderr is
empty on both.
</details>
<details><summary>Suites</summary>
Under `scripts/pm/os-verify-lock.sh`:
- Full `turbo run build`: 115 of 115 tasks, exit 0.
- `typecheck` of `@objectstack/objectql` (tsc + `check:test-typecheck`)
and `@objectstack/core`: exit 0 each.
- `@objectstack/objectql` vitest `--project local`: 479 files, 8,942
tests passed, exit 0 (the `engine-cascade-delete*` files,
`engine-cascade-reference-carrier.test.ts`,
`engine-dangling-reference-audit.test.ts` and
`federated-injected-column-readers.test.ts` among them).
- Beyond the package, the real-driver cascade suites that run these
bodies end to end: `@objectstack/runtime`
`cascade-delete-multivalue-lookup-real-driver`,
`cascade-delete-restrict-same-parent-real-driver` and
`sandbox/referential-cascade-delete-signal` integration tests (3 files,
15 passed, 1 skipped), and `@objectstack/plugin-security`
`delete-reference-cleanup-system-identity.test.ts` (18 passed).
- `test:repo` projects were not run locally (the published surface is
byte-identical); `Test Core` runs them in CI.
</details>
## Verification
The gate list is `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` on this diff (merge base `c4c515ad3`), each
run with its exit code captured before any pipe, then reconciled with
`--ran` (each line carrying its `exit N`).
- **Derived gates: 80 of 80 run, exit 0 each; `--ran`: 80 derived, 80
run, 0 NOT-MEASURED, 0 UNRUN** ("a DERIVED zero — all 80 recorded an
exit code and none of them is 3"). `check:dual-build-cjs-loads` and
`check:dts-closure` ran after the full build;
`check-plugin-teardown-shape` and `check-engine-split-ratio --self-test`
after deepening the clone to 2026-07-22 and fetching `621a4876`.
- **Hand gates, exit 0 each:** `node scripts/check-adr-anchors.mjs`
(counts above), `node scripts/check-tenant-audit-census.mjs` (245 write
call sites), `node scripts/check-adr-symbol-anchors.mjs` (2,798
anchors), `node scripts/check-platform-checklist.mjs --changed-from
origin/main` and the full `check-platform-checklist.mjs`, `node
scripts/check-commit-card-trailers.mjs --range origin/main..HEAD`, `node
scripts/check-system-context-census.mjs`, `node
scripts/check-nul-bytes.mjs`, `node
scripts/check-durability-degradation-log-level.mjs --list` (base and
head identical, masked), and eslint as `pnpm lint` runs it
(`--no-inline-config`) on `packages/objectql`.
- After `origin/main` `7e200b4a68` was merged (15 files under `ui/` and
the Studio, none of this diff's paths), the change set against
`origin/main` is the same four files, so the derived list is unchanged.
## Acceptance notes
- **Serial order.** Nothing was edited before the claim `6487687348`
named this branch.
- **Overlap.** Open PRs touching `packages/objectql/**` or this diff's
docs, listed at start and again just before opening this (each head
fetched, `git diff --name-only origin/main...pr/N`): draft #27339 edits
`engine.ts` at its import block (right after cut 18's import), `insert`,
`update` and `aggregate`, none of this section, the five exported
helpers or the two edited import lists; `git merge-tree` of this head
with #27339's head is clean. #27344 adds rows to `system-context.mdx` in
other places and auto-merges with this head. The branch #27277's claim
named, `claude/project-thread-mlrxgx`, does not exist on the remote
(`git ls-remote`: 0 refs), so there was nothing to read there. Whichever
lands second merges `main`.
- **What stays, for the next cut.** Seventeen members of this section
stay for the private-static limit; the largest,
`walkReferencingRelations` (318 body lines), cannot move under the
current series limits. `cascadeRelationBehavior` (60) stays for the
reader test's same-file `via` rule.
- **Left as is.** `engine.ts`'s `CascadeDeleteSet` docblock and
`refuseRestrictsInsideOwnCascade`'s docblock still say `{@link
cascadeReachOf}`, which now lives in the module; they are left
byte-identical, as cut 14 left a `{@link}` to a helper that moved. The
moved bodies keep their indentation minus one level, as moved, not
re-formatted.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(Not touched.)
- [x] 2. Every name I added uses the casing for its kind
(`DeleteCascadeHost`, `engine-delete-cascade.ts`).
- [x] 3. No formatter ran; `pnpm lint` passes on the touched package.
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. No publish-visible change, so `skip-changeset`; both
declaration lines are filled in above.
- [x] 6. `packages/spec` not touched.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English, apart from the
maintainer quick-read block the project asks for.
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
`skip-changeset`: move-only inside `@objectstack/objectql`, with every
published declaration file byte-identical and no behaviour change, so
there is nothing for a release note to say.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01L6bhgXPvYEKGGY6sms31q2
---
_Generated by [Claude
Code](https://claude.ai/code/session_01L6bhgXPvYEKGGY6sms31q2)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9462d8a commit 5c0e4fd
4 files changed
Lines changed: 473 additions & 280 deletions
File tree
- content/docs/permissions
- docs/qa/platform-checklist/areas
- packages/objectql/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
523 | 523 | | |
524 | 524 | | |
525 | 525 | | |
| 526 | + | |
526 | 527 | | |
527 | 528 | | |
528 | 529 | | |
| |||
534 | 535 | | |
535 | 536 | | |
536 | 537 | | |
537 | | - | |
538 | 538 | | |
539 | 539 | | |
540 | 540 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5001 | 5001 | | |
5002 | 5002 | | |
5003 | 5003 | | |
5004 | | - | |
| 5004 | + | |
5005 | 5005 | | |
5006 | 5006 | | |
5007 | 5007 | | |
| |||
0 commit comments