Repository navigation
Commit 6fc22b7
docs(merge-driver): the system-context row's prose says the line-anchors comparator is the identity on that page today (#21075)
Fixes #16612
Clause-②: no
Ruling-ref: 5748968327
Executes ruling A (`5748968327`): `mixed: 'line-anchors'` stays on the
`system-context.mdx` row, and the three prose blocks that still describe
the line-anchor page as current are rewritten so history reads as
history and today reads as today. Prose only.
`scripts/git-merge-regen.mjs` is untouched, and the `endToEndMixed()`
self-test still has its row to exercise.
## What changed
- **`scripts/regen-artifacts.mjs`, the row comment.** Every original
argument is kept, now in the past tense and marked as true "while the
page carried `file:line` anchors": the #13646 routing argument, the
#13625 `4408/5771/6019/6382/6575` measurement, #14064's correction with
its three measurements, the "keep the routing, not NOT_DRIVER_MANAGED"
argument and the 24-of-25 census. Two paragraphs are new:
- **Today (since #15921).** Every citation on the page is a
`path#symbol` anchor, so `blankAnchorLineNumbers` has nothing to blank
and the `'line-anchors'` comparator is the identity on this page. A
deferral is proven lossless only when THEIRS equals the ancestor, or
equals OURS, byte for byte. So every real edit takes the text-merge
branch or conflicts loudly, and that is by design.
- **Keep the field.** `mixed` is what routes the row through the
lossless check in the first place. Without it, the row takes the
unconditional deferral, which is the silent deletion #14064 closed. The
reproduction below shows this.
- **`scripts/regen-artifacts.mjs`, the `why:` string of the
`content/docs/permissions/**` `NOT_DRIVER_MANAGED` entry.** It no longer
calls the page "a generated anchor table". It was one when it was
routed; today its anchors are `path#symbol` and only its declared counts
are generated. This is the one executable line in the diff, and no code
reads it: in `git-merge-regen.mjs` every `.why` read is `verdict.why`,
never an entry's `why`.
- **`.gitattributes`, the paragraph above the row.** The history is now
in the past tense ("caught the stale anchors a merge left behind", "the
cheap case stayed cheap"), and a "Today (since #15921)" paragraph is
added with the same facts and a pointer to the row comment. One clause
inside the rewritten paragraph was inverted and is now corrected. It
said "hand-written paragraphs the gate is constitutionally unable to
miss"; it now says "…whose loss the gate is constitutionally unable to
notice". The measured point is that ten gates did NOT notice a deleted
paragraph.
- **`scripts/doc-line-anchors.mjs`, the module header.**
- Kept as the record of why the module exists: the 101-of-111
measurement and the "ONE reader" origin.
- A new "Today, since #15921" section states:
- the page cites by `path#symbol`;
- the grammar is `scripts/symbol-anchors.mjs`, which reads a line-number
spelling only to report it;
- the census gate reads its anchors through that module, not this one;
- the module's one in-tree importer is `scripts/git-merge-regen.mjs`
(`git grep doc-line-anchors` outside the module itself has that one
hit);
- the comparator is the identity on the page by design;
- the census `--fix` no longer touches anchors.
**Proof that only comment lines changed** (base `6073bb96b8`, head
`7270d9c5ed`). Every changed line in the two `.mjs` files is a `//` or `
*` comment line, except the three lines of that `why:` string. Every
changed line in `.gitattributes` starts with `#`. The negative control
below backs this up: both exported tables are deep-equal to base, and
the `.gitattributes` non-comment lines are identical.
## 验收备注
**1. Direct reading.** Hypothesis 1 held. Measured at `7270d9c5ed`, with
a pre-#15921 control taken from the page at `f2f6684cd5`, the base the
card itself measured. The script imports `scripts/doc-line-anchors.mjs`
and prints `extractLineAnchors(page).length` and
`blankAnchorLineNumbers(page) === page` for each page:
```
control: page at f2f6684 (pre-#15921) | extractLineAnchors(page).length = 141 | blankAnchorLineNumbers(page) === page : false
page at HEAD | extractLineAnchors(page).length = 0 | blankAnchorLineNumbers(page) === page : true
```
The control reproduces the card's own `141 / false`, so the parser is
live and the zero reflects the page.
**2. Control leg: field present ⇒ prose survives.** Hypothesis 2 held.
Setup: a throwaway repo whose `merge.os-regen.driver` is this worktree's
`scripts/git-merge-regen.mjs %O %A %B %P`, with `.gitattributes` routing
the page `merge=os-regen`. The ancestor is the real page at HEAD
(anchor-free). THEIRS appends one hand-written paragraph carrying
`NEEDLE-16612`. OURS edits only the frontmatter `title:` line. The edits
do not overlap.
Run at `7270d9c5ed` (excerpt of the script's output; the full log is the
dev report's evidence):
```
--- [control-head] row field lines ` mixed: 'line-anchors',` in that driver's table: 1
⟳ content/docs/permissions/system-context.mdx
NOT deferred: the incoming side carries hand-written changes that no regeneration can restore.
This file is MIXED, so it was TEXT-MERGED (cleanly — both sides' prose is in the
result) rather than resolved to one side. The generated half still needs:
pnpm gen:system-context-census
Auto-merging content/docs/permissions/system-context.mdx
Merge made by the 'ort' strategy.
--- [control-head] git merge exit: 0
--- [control-head] conflict markers in merged file: 0
--- [control-head] ours title edit present: 1
--- [control-head] NEEDLE present in merged file? === true
```
**Mutation leg (optional; re-run here).** Field deleted ⇒ prose silently
lost. The worktree was never mutated. The mutation ran on a scratch copy
of `scripts/`, committed in its own throwaway repo. Its
`regen-artifacts.mjs` blob was `5ae1ba8bef`, identical to the PR head.
The field line was deleted through `scripts/ablation-replace.mjs`, which
reported `ok mutation landed: anchor 1 -> 0, blob 5ae1ba8 ->
f7365b0f98b9`. Excerpt of the output:
```
--- [mutation-head] row field lines ` mixed: 'line-anchors',` in that driver's table: 0
⟳ content/docs/permissions/system-context.mdx
not text-merged — it is generated. Regenerate from the merged tree:
Auto-merging content/docs/permissions/system-context.mdx
Merge made by the 'ort' strategy.
--- [mutation-head] git merge exit: 0
--- [mutation-head] conflict markers in merged file: 0
--- [mutation-head] ours title edit present: 1
--- [mutation-head] NEEDLE present in merged file? === false
```
After both legs: worktree `git diff HEAD` is empty and `git status
--porcelain` is clean.
**3. `pnpm check:merge-driver`: green, which is necessary but not
sufficient.** At `7270d9c5ed` it printed:
- `✓ 1 mixed row(s) name a comparator that exists and discriminates
(line-anchors)`
- `✓ end-to-end (mixed): anchors-only deferred to OURS; incoming prose
survived instead of being dropped`
- `✓ merge driver wiring is consistent (34 path(s) deliberately
excluded).`
It was green before this change as well, so its green is not the
evidence. Items 1 and 2 are.
**4. Negative control: no routing or field changes.** Base modules
imported against head:
- `REGEN_ARTIFACTS`: 18 rows at base and at head, deep-equal.
- `NOT_DRIVER_MANAGED`: 34 entries at base and at head, equal ignoring
`why`. The only `why` that changed is `content/docs/permissions/**`.
- `DEFAULT_OWNER` / `ROOT_OWNER` and the export set: unchanged.
- `.gitattributes`: non-comment lines identical, `merge=os-regen` rows
19 / 19.
**5.** Nothing under `content/docs/releases/`, `docs/adr/**`,
`.claude/**`, `skills/**`, `AGENTS.md` or `CLAUDE.md` is touched.
## Gates (all at `7270d9c5ed`, the final commit)
- `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack
--commands` derived 28 commands for these three paths. All 28 exited 0.
`--ran` reconciliation: `✓ dispatch-gates --ran: 28 derived famil(ies)
accounted for — 28 run, 0 NOT-MEASURED (a DERIVED zero — all 28 recorded
an exit code and none of them is 3).`
- Named: `pnpm check:merge-driver` exit 0 (above). `pnpm
check:nul-bytes` exit 0 (`no raw ASCII control bytes`). `node
scripts/check-scripts-symbol-anchors.mjs` exit 0 (`3718 anchors across
282 scripts resolve … 0 line anchors on tracked targets survive`); its
`--self-test` also exit 0. The edited scripts carry no `--self-test` of
their own. `regen-artifacts.mjs` is exercised by `git-merge-regen.mjs
--self-test`, which is inside `check:merge-driver`.
- Roster gates flagged as sharing `scripts/`:
- Exit 0: `check-published-list-mirrors`, `check:console-injection`,
`check:engine-double-contract`, `check:i18n-stale-fill`.
- NOT MEASURED: `check:dts-closure` and
`check:published-readme-exports`. Both exited 3 (PREREQUISITE NOT MET:
no package `dist/` in this worktree). This diff touches no workspace
package.
- Lint, as a proven narrowing (the repo-wide `pnpm lint` is CI's run).
`eslint --no-inline-config --format json` over both edited `.mjs` files
exited 0 with 0 errors and 0 warnings.
- (1) Both files are in eslint's own population: `--print-config`
resolves a config for each, and the JSON carries no ignored-file
message.
- (2) The JSON reports 2 files.
- (3) Type-aware linting is not enabled: `parserOptions.project` and
`projectService` are both null in the resolved config, so this diff
cannot move the verdict on any untouched file.
- `.gitattributes` is not lintable.
- Changeset: none. The root package `@objectstack/spec-monorepo` is
`private: true` and owns `scripts/` and `.gitattributes`, so nothing
published changes ⇒ `skip-changeset` label.
## Acceptance notes
These were noticed while doing the work. They are not fixed here, and
none is filed (none has a public door or a named real producer):
- **Outside the claimed file surface, same staleness, left untouched.**
The claim admitted the module header only, and this PR does not widen
it:
- `scripts/doc-line-anchors.mjs`, the `blankAnchorLineNumbers` docblock,
still says the census `--fix` "rewrites exactly these numbers and
nothing else". The new header names that account as the pre-#15921 one.
- `scripts/regen-artifacts.mjs`, the `mixed` section of the
`REGEN_ARTIFACTS` docblock, still cites the page as "the measured case"
of a generated half "unreachable by any text merge". That was true of
the line-anchor half.
- **`scripts/git-merge-regen.mjs` (fenced off by the ruling).**
- The `MIXED_COMPARATORS['line-anchors']` docblock says the page's
generated half "is exactly those numbers:
`check-system-context-census.mjs --fix` rewrites them and touches
nothing else".
- The `deferralIsLossless` docblock cites "24 of the last 25 main
commits" as the common case.
- The `drive()` conflict message tells the human "the anchor numbers do
not matter here — take either side and then run … which re-derives them
from the merged tree". On today's page there are no anchor numbers, and
`--fix` re-derives only declared counts.
- **Dormant parser over-read in `extractLineAnchors`.** A bare number
after a dash is taken as a RANGE_END anchor when the span to its left is
any code span, not necessarily an anchor, provided an earlier path-only
citation set the current file. Measured over the 408 `content/docs`
md/mdx files: one hit, `content/docs/protocol/objectui/layout-dsl.mdx`
doc line 577, where `` `1`–`4` `` is read as an anchor into
`packages/spec/src/ui/view.zod.ts`. No consumer reads that page through
this parser, and `system-context.mdx` has 0 hits.
- **Population counts in this routing prose disagree with each other.**
The `why:` string says "22 of its 23 pages are hand-written", while the
row comment says "22 hand-written prose pages with ONE generated page"
and "21 prose files". Measured at HEAD: 22 `.mdx` files plus `meta.json`
(21 prose and `system-context.mdx`). These are untouched here, because
the ruling scoped the anchor-table facts.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JAhu8u8QfBvRjVZDox7CP9)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent e0c768f commit 6fc22b7
3 files changed
Lines changed: 137 additions & 63 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
86 | 86 | | |
87 | 87 | | |
88 | 88 | | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
97 | 98 | | |
98 | 99 | | |
99 | 100 | | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
104 | 106 | | |
105 | 107 | | |
106 | | - | |
| 108 | + | |
107 | 109 | | |
108 | 110 | | |
109 | 111 | | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
121 | 136 | | |
122 | 137 | | |
123 | 138 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
6 | 9 | | |
7 | 10 | | |
8 | 11 | | |
9 | 12 | | |
10 | | - | |
11 | | - | |
12 | | - | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
13 | 16 | | |
14 | | - | |
15 | | - | |
| 17 | + | |
| 18 | + | |
16 | 19 | | |
17 | 20 | | |
18 | 21 | | |
19 | | - | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
20 | 44 | | |
21 | 45 | | |
22 | 46 | | |
| |||
54 | 78 | | |
55 | 79 | | |
56 | 80 | | |
57 | | - | |
58 | | - | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
59 | 84 | | |
60 | 85 | | |
61 | 86 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
234 | 234 | | |
235 | 235 | | |
236 | 236 | | |
237 | | - | |
238 | | - | |
239 | | - | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
240 | 243 | | |
241 | 244 | | |
242 | 245 | | |
| |||
246 | 249 | | |
247 | 250 | | |
248 | 251 | | |
249 | | - | |
250 | | - | |
251 | | - | |
252 | | - | |
253 | | - | |
254 | | - | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
255 | 259 | | |
256 | 260 | | |
257 | 261 | | |
258 | 262 | | |
259 | | - | |
260 | | - | |
| 263 | + | |
| 264 | + | |
261 | 265 | | |
262 | | - | |
| 266 | + | |
| 267 | + | |
263 | 268 | | |
264 | 269 | | |
265 | 270 | | |
| |||
271 | 276 | | |
272 | 277 | | |
273 | 278 | | |
274 | | - | |
275 | | - | |
| 279 | + | |
| 280 | + | |
276 | 281 | | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | | - | |
281 | | - | |
282 | | - | |
283 | | - | |
284 | | - | |
285 | | - | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
286 | 292 | | |
287 | | - | |
| 293 | + | |
288 | 294 | | |
289 | | - | |
290 | | - | |
291 | | - | |
292 | | - | |
293 | | - | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
294 | 300 | | |
295 | 301 | | |
296 | 302 | | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
297 | 329 | | |
298 | 330 | | |
299 | 331 | | |
| |||
474 | 506 | | |
475 | 507 | | |
476 | 508 | | |
477 | | - | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
478 | 512 | | |
479 | 513 | | |
480 | 514 | | |
| |||
0 commit comments