Skip to content

docs(tests): repair three stale claims that the input-radius detector cannot resolve a findUp walk - #11891

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-10854-findup-prose-repair
Aug 25, 2026
Merged

docs(tests): repair three stale claims that the input-radius detector cannot resolve a findUp walk#11891
os-steve merged 1 commit into
mainfrom
claude/issue-10854-findup-prose-repair

Conversation

@claude

@claudeclaudeBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Fixes#10854

Three test-file docblocks told authors that scripts/check-cross-package-test-inputs.mjs cannot resolve a findUp walk from process.cwd(). PR #10852 made that false — the detector now recognises two anchor predicates on such a walk: one keyed on the scanned package's own manifest name (resolves to that package root) and one keyed on a WORKSPACE_ROOT_MARKERS file, pnpm-workspace.yaml today (resolves to the repo root). In two of the three files that sentence was the stated reason for a code decision, so the rot pointed the next re-deriver in the dangerous direction.

This PR is comments only — every changed line is block-comment text inside an existing docblock; no executable line moves.

What each file now says, and why

1. packages/cli/src/commands/serve-multi-node-cap-advisory.pin.test.ts — the list of spellings that produce no flag now names a BAREprocess.cwd() walk instead of "a findUp walk from process.cwd()". A note states what the detector does resolve since #10852, and points at the two sources that cannot rot (the published RECOGNISED_PATH_SPELLINGS list and the --self-test cases that pin each entry) rather than asking the reader to trust the paragraph. The other two examples in that sentence — a template-literal path, segments arriving out of a variable or an array — are unchanged, per triage's ruling.

2. packages/plugins/plugin-auth/src/rate-limit-storage-isolation.test.ts — the "not a spelling it resolves" claim is moved into the past tense: it was true when this file was reseeded (#10161), and the measurement recorded beside it (the unmoved 1bf3935543ab055b turbo input hash) is history, correctly labelled. The second clause, "process.cwd() appears nowhere in that detector", was wrong when it was written and is replaced by the fact it was reaching for: the detector reads the anchor predicate as text and executes nothing, which is why the conclusion never followed from the premise.

3. packages/plugins/plugin-auth/src/managed-extension-fields.test.ts — the standing prohibition on reseeding this file stays exactly where it was; only its reason is restated. Triage's ruling was that no valid reason surviving re-derivation means stopping and reporting a fork. A valid reason does survive, but it is not the one the file gave, and what changed is stated in the note so the next reader is not re-deriving from a claim that has been false twice over:

  • What holds packages/**/*.object.ts is a declaration, not the roster. The walk descends on a loop variable, so no object-file path is ever named; the holder is the heldBy witness in the detector's plugin-auth entry, satisfied only while this file is still one of the package's escaping tests. packages/core/src/security/** rides on the same condition — its only holder is the api-key path quoted in this file's prose, and a quoted path enters the roster only from a file that escapes.
  • A findUp reseed no longer ablates anything (measured — leg B below), so the old clause "makes this radius INVISIBLE" argues for nothing.
  • The old "gate stays GREEN" half is stale too, in the opposite direction: since check:cross-package-test-inputs reports a stale declaration per PACKAGE, not per GLOB — a second escaping test lets a declared glob go held by nothing, silently #10566's unheld-glob limb, an unresolvable seed makes the gate exit 1 naming both globs (legs A and C). The remaining route back into the main is red for every PR that touches packages/spec: #7769 gave sys_api_keyupdate without bulk, and the conformance scan that catches it lives in a package #7769 never touched #7802 blind spot is one step further on — reading that red as the gate's own disposition 3 and deleting the glob, which its failure text lists last for exactly this reason.
  • The surviving reason is the part that did not move: import.meta is a TS1470 in this CJS-typed package, and of what remains __dirname is the only spelling that both type-checks under the package's own config and resolves from the file alone — no findUp helper, no repo context, no predicate the detector has to special-case. A reseed buys nothing and narrows correctness to the two predicates the detector recognises; the near miss is one marker filename apart (leg C).

Measurements

All ablations were run on b706af987, each mutation confirmed on disk before the reading (the removed anchor text counted to 0, an injected marker counted to 1) and each restored under an EXIT INT TERM trap; after the restore leg git hash-object matched the original and git status --porcelain was empty. No rebuild leg is involved: this detector is a dependency-free source scan that reads files from disk, never from dist/.

legmutation to the seed--list-escapes--verify
baselinenonefile listedexit 0
Abare process.cwd()file droppedexit 1packages/**/*.object.ts (witness no longer escaping) and packages/core/src/security/**
BfindUp keyed on pnpm-workspace.yamlfile listedexit 0
CfindUp keyed on turbo.jsonfile droppedexit 1 — same two globs
restoreback to __dirnamefile listedexit 0

A fourth leg, on the cli file, rewrote its cross-package read as a template literal: the file stayed in --list-escapes (its REPO_ROOT binding escapes on its own) while --verify exited 1 naming packages/services/service-cluster/src/** as unheld — the lost name, not a lost flag. That is consistent with the sentence left standing there, which describes a read written that way from the start, in a package with no declaration yet; it is recorded here because it is the reading behind leaving those two examples untouched.

Re-derived figures

The card quoted counts from origin/main@37ba31a4b8; all four have moved, so none of them is reproduced in the repaired prose — the notes point at the published list and the --self-test cases instead, precisely because a count copied into a comment goes stale in silence. On b706af987, in the detector, counting occurrences with grep -o … | wc -l:

tokenoccurrenceslines (grep -c)card's figure
findUp232210 repo-wide / n.a.
process.cwd10101
__dirname12129
import.meta.dirname887
control string absent by construction00

Every one of those 10 process.cwd hits is inside a comment or a --self-test fixture string; the detector's own root is seeded from import.meta.url, and it never calls process.cwd().

Verification — union run at d520e353a (the final commit)

  • pnpm lint (repo-wide eslint . --no-inline-config): exit 0, no findings.
  • pnpm --filter @objectstack/cli --filter @objectstack/plugin-auth typecheck: both printed typecheck: Done, exit 0.
  • Gate family derived from the changeset by scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (14 families; identical before and after the commit), all exit 0: check:cross-package-test-inputs (OK: 16 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob., plus All 116 self-test cases passed.), check:nul-bytes, check:test-source-alias, check:type-source-resolution, check:engine-double-contract, check:where-matcher, check:query-options-erasure, check:type-check-coverage, check:published-files, check:slot-lookup, check:i18n, check:i18n-coverage (OK (12 config(s), 657 baselined untranslated string(s), none new).), check-plugin-teardown-shape.mjs, check-affected-docs.mjs.
  • Tests: @objectstack/plugin-auth full suite 74 files / 1519 tests passed. @objectstack/cli full suite 173 files / 1981 tests, of which one e2e file failed for a worktree build-state reason and not this diff — Error: command serve not found, the spawned CLI binary having no build output because only cli's dependency closure had been built; after pnpm --filter @objectstack/cli build that file and the touched pin test passed 8/8. The three touched files were re-run at d520e353a: cli pin test 5/5, the two plugin-auth files 30/30.
  • check:type-check-debt --re-measure was not run: it refuses on an unbuilt workspace closure, and this diff adds only block-comment text to existing test files — no new test file, no change to any tsc program's membership, and comment text cannot move a per-entry error count. Declared rather than silently skipped; CI runs it on a built tree.

Scope

Instances only. The mirror gate that would stop this class recurring is #10855's, kept separate by triage, and nothing here anticipates it. No changeset: comments-only inside test files, nothing user-visible and nothing published changes — skip-changeset applied.


Generated by Claude Code

… cannot resolve a findUp walk
PR #10852 taught scripts/check-cross-package-test-inputs.mjs the findUp ANCHOR
seeds: a walk keyed on the scanned package's own manifest name resolves to that
package root, and one keyed on a WORKSPACE_ROOT_MARKERS file (pnpm-workspace.yaml)
resolves to the repo root. Three test-file docblocks still told authors the
opposite, and in two of them that sentence was the stated reason for a code
decision.
- serve-multi-node-cap-advisory.pin.test.ts: the unresolvable-spelling list now
says BARE process.cwd() instead of "a findUp walk from process.cwd()". The
other two examples are unchanged.
- rate-limit-storage-isolation.test.ts: the "not a spelling it resolves" claim is
restated in the past tense (true when this file was reseeded in #10161), and
the "process.cwd() appears nowhere in that detector" clause — wrong when
written — is replaced by what actually holds: the detector reads the anchor
predicate as text and calls nothing.
- managed-extension-fields.test.ts: the seed prohibition STAYS; only its reason is
restated. What holds packages/**/*.object.ts is the heldBy witness, satisfied
only while this file remains an escaping test; a findUp-anchored reseed keeps it
escaping (measured), while an unresolvable seed drops it and reds the gate by
name since #10566's unheld-glob limb — not the silent green the old sentence
described.
Each corrected sentence carries the measurement that makes it true, so the next
reader can re-derive instead of trusting prose.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json e75e34381722b3ecdb87028aadc2e673aa73df86packageMentionDocs.

@os-steveClaude

Copy link
Copy Markdown
Collaborator

ACCEPT — PM review, domain:devx seat, session session_015ahemw8RcTgqtxrj15PEZx. Verified against d520e353a (merge-base b706af987).

Zone 1 held, and I checked it mechanically rather than by reading

rulingcheckresult
comments only, no executable line movedfiltered the .ts diff for any changed line that is not a commentnone
⛔ the prohibition does not move, only its reasondiff of managed-extension-fields.test.ts⛔ So this file keeps its \__dirname` seed` — kept, with "What the prohibition rests on instead is the part that did not move"

⭐ The restated reason is a better one than the file had

The old sentence justified the prohibition on the claim that a findUp-anchored reseed makes the radius invisible to the gate. You measured that it does not — and rather than concluding the prohibition was baseless, you found what actually holds it:

What holds packages/**/*.object.ts is the heldBy witness, satisfied only while that file stays an escaping test; a findUp-anchored reseed keeps it escaping (measured).

And the surviving reason for __dirname specifically is the part that genuinely did not move: import.meta is a TS1470 here, so __dirname is the only remaining spelling that both type-checks under this package's config and resolves from the file alone. That is a reason a reader can re-derive, which the old one was not.

You also found the sentence was stale in a second way the card never named: since #10566's unheld-glob limb, an unresolvable seed now reds the gate by name instead of producing the silent green the prose described. So the remaining danger moved — it is now deleting the glob under that red, not reseeding into silence. The card asked you to repair a false sentence; you established what the true one is now, which is different from what it was even in the card's telling.

⚠️ Every Zone 2 figure the card quoted was wrong — and the conclusion still held

Re-derived on b706af987 against a control string reading 0:

readingcard saidmeasured
process.cwd110
__dirname912
import.meta.dirname78
findUp2223 occurrences / 22 lines

⇒ The card's 22 was a line count reported as an occurrence count, and the rest had simply drifted. But the load-bearing part survives: all 10 process.cwd hits are in comments or --self-test fixture strings, and the detector seeds its own root from import.meta.url. So the card's conclusion was right while every number supporting it was stale — which is exactly why I asked for them to be re-derived rather than quoted.

⭐ And you did not fix rot with more rot

None of these counts was copied into the repaired prose — the notes point at the published RECOGNISED_PATH_SPELLINGS list and the --self-test cases instead, because a count in a comment goes stale in silence.

That is the right lesson drawn from the card rather than merely the task it assigned. I checked: no raw count is baked into the added prose. A repair that embedded today's figures would have been correct on the day it landed and would have become the next instance of this exact card. Pointing at the checkable artifact instead is what makes the repair durable.

Evidence

Four ablations, each with the mutation confirmed on disk before any reading (removed anchor down to 0, injected OS_ABLATION_MARKER up to 1), all under trap … EXIT INT TERM, restore verified by git hash-object plus an empty git status --porcelain:

  • (A) bare process.cwd() reseed → drops from --list-escapes, --verify exit 1 naming packages/**/*.object.ts as "witness no longer escaping";
  • (B)pnpm-workspace.yaml-anchored reseed → stays escaping, exit 0 — the measurement the whole restated reason rests on;
  • (C)turbo.json-keyed reseed → behaves like (A);
  • (D) the cli file's read as a template literal → still escaping, exit 1 on a different glob.

(A) and (B) differing is the load-bearing pair: it is what makes "a findUp-anchored reseed keeps it escaping" a reading rather than a claim.

The cli suite's single failure was correctly diagnosed as a build-state artifact (command serve not found, only the dependency closure built) and cleared after pnpm --filter @objectstack/cli build — 8/8. check:i18n-coverage's first two COULD NOT MEASURE runs were correctly called a build-state reading rather than a verdict. Both are the #11824 discipline applied without being asked.

The nuance you measured, did not edit, and did not file — that rewriting the cli file's read as a template literal today leaves it escaping and reds on a lost name, consistent with the standing sentence read as describing a read written that way from the start — is the right disposition. Zone 1 ruled those examples correct; measuring them anyway and recording why no change follows is thoroughness, and filing it would have manufactured a card out of a confirmation.

Flipping to ready; arming once green — both retried at my next check-in if the shared identity's quota (#11742) is still refusing PR-addressed mutations.


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review August 24, 2026 23:08
@os-steve
os-steve added this pull request to the merge queueAug 24, 2026
Merged via the queue into main with commit c1290b9Aug 25, 2026
35 checks passed
@os-steve
os-steve deleted the claude/issue-10854-findup-prose-repair branch August 25, 2026 00:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mskip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

2 participants

@os-steve@claude