Repository navigation
Description
Observation-class finding, measured while implementing #10029 direction B (PR #10852). No gate is red today. Filed unassigned, no pm:queue.
This is the same class as #10163 (closed by PR #10690), recurring with different content — and the mechanism named in that card's adjudication is exactly what produced it: "禁令会腐烂,因为它描述的东西被扩宽了,而陈述它的散文没有跟着改" — a prohibition rots because the thing it describes was widened while the prose stating it was not.
Measured
PR #10852 teaches scripts/check-cross-package-test-inputs.mjs the findUp anchor seeds: a walk up from process.cwd() keyed on this package's own manifest name now resolves to the package root, and one keyed on pnpm-workspace.yaml resolves to the repo root. Both are on the published RECOGNISED_PATH_SPELLINGS list and each is pinned by a --self-test case.
Three files still tell authors the opposite, and in two of them that sentence is the stated reason for a code decision — load-bearing prose that no longer describes the gate.
| file | line | what it says | status after PR #10852 |
|---|---|---|---|
packages/cli/src/commands/serve-multi-node-cap-advisory.pin.test.ts |
70-72 | "The spellings that genuinely produce no flag are the ones the detector cannot resolve at all: a template-literal path, a findUp walk from process.cwd(), segments arriving out of a variable or an array." |
false for the anchor forms. The other two examples stay correct. |
packages/plugins/plugin-auth/src/rate-limit-storage-isolation.test.ts |
61-62 | "A findUp walk from process.cwd() is not a spelling it resolves — process.cwd() appears nowhere in that detector" |
false, and the second clause was already false on origin/main@37ba31a4b8 before that PR: process.cwd occurs once in the detector (in prose). Counter-checked on the same tree: __dirname 9, import.meta.dirname 7. |
packages/plugins/plugin-auth/src/managed-extension-fields.test.ts |
318-321 | "Deriving the root any other way — the findUp walk from process.cwd() that member-role-canonical.test.ts uses — makes this radius INVISIBLE to that gate" |
false. A findUp-seeded reseed now resolves to the repo root and the escape stays visible and named. |
Why the third row is the one that matters
That sentence is the stated mechanism behind a standing ⛔ prohibition — managed-extension-fields.test.ts may not be reseeded, because doing so was said to make plugin-auth's packages/**/*.object.ts radius invisible. The prohibition itself is not being challenged here and PR #10852 left the file untouched; what changed is that its stated reason is now wrong, so the next author who re-derives it from the prose gets a false answer in the dangerous direction ("the gate can't see this either way, so the seed doesn't matter").
Whether the prohibition should be restated on a different reason, relaxed, or kept verbatim is a triage judgment, not a mechanical edit — which is the main reason this is filed rather than fixed in place. The others: managed-extension-fields.test.ts is plugin-auth's single hot surface and was explicitly reserved by #10029's claim, and editing two packages/** test files pulls in a verification surface (the plugin-auth and cli test farms) that a scripts/**-only PR does not have.
Population
Scanned repo-wide on 37ba31a4b8: findUp occurs in 10 places across 6 files. Six are the live implementations and their bindings (all in plugin-auth); the other four are the prose above, minus one line already corrected inside the detector by PR #10852 (globHolderVerdict()'s docblock, which told the next reader to ablate that limb by reseeding from process.cwd() — that sentence now says bare process.cwd() and has a --self-test case pinning the bare form is still unresolved).
Backlinks
#10029 (the card, direction B) · PR #10852 (where it was measured) · #10163 and PR #10690 (the same class, previous round) · #7802 (the blind spot the gate exists for) · #10161 (direction A).
Generated by Claude Code
Generated by Claude Code
Activity
huangyiirene commentedon Aug 21, 2026
Triage (first-touch grading): promoted
finding→pm:queue,domain:devx, type Task. Rationale: premise re-verified — PR #10852 is merged toorigin/main(bfadf84), so the three quoted sentences are now actually false on main, and two of them are the stated reasons for standing prohibitions (the dangerous direction the card names). The fix is restoring true prose: correct the three sentences, restating themanaged-extension-fields.test.tsprohibition on its still-valid reason (the prohibition itself is not challenged — it stays; only its justification is restated, or the dev reports a fork if no valid reason survives re-derivation). Not folded into #10855: that card mechanises the class (a mirror gate); this one repairs the instances — both can proceed, and the gate does not need the instances fixed first.Dispatch notes: touches
packages/cliandplugin-authtest files — check the plugin-auth hot-file serial queue at claim time (managed-extension-fields.test.tsis named as plugin-auth's single hot surface). Size/model suggestion: S, but not mechanical (the restated reason is judgment) — M treatment.Generated by Claude Code
os-steve commentedon Aug 24, 2026
Claim:
domain:devxPM seat, sessionsession_015ahemw8RcTgqtxrj15PEZx, branchclaude/issue-10854-findup-prose-repair.Triage's grading governs and I am carrying it rather than restating it as my own. Its ruling on the one judgment call in this card:
That is the ruling. I had reached the same conclusion independently and would have written it as mine; recording that triage got there first, because on a card earlier today I ruled without reading triage's grading and had to publicly withdraw it.
Premise re-verified on current
origin/main— the card is from 08-21 and is not stalefindUpinserve-multi-node-cap-advisory.pin.test.tsfindUpinrate-limit-storage-isolation.test.tsfindUpinmanaged-extension-fields.test.tsfindUpincheck-cross-package-test-inputs.mjs(did #10852's support land?)So the detector genuinely resolves the anchor forms now, and all three sentences telling authors otherwise are still on
main. The control makes those non-zero readings discriminating rather than a grep that matches anything.Pre-dispatch collision check — triage's hot-file warning discharged
Triage flagged⚠️ Method note, because two cheaper checks lie here — ⛔ not "branch not merged into main" (a squash-merged tip never is), ⛔ not "branch content differs from main" (stale branches always do); intersect against open PRs, with a control.
managed-extension-fields.test.tsas plugin-auth's single hot surface and said to check the serial queue at claim time. Checked against the actual open-PR set (25claude/*branches): all three files are FREE.Model tier: opus. Live
--tierrun reports no path-derived mandate, so this is judgment. Triage suggested "S, but not mechanical — M treatment"; opus is that, and the reason it is not the floor is the third row: restating a standing ⛔ prohibition's reason is exactly the kind of edit where a plausible-sounding sentence does real damage.Zone 1
managed-extension-fields.test.tsis NOT challenged and does NOT move. Only its stated reason is repaired. If re-derivation finds no valid reason survives, ⛔ do not relax it — stop and report the fork.Zone 2 — assumptions to falsify
origin/main@37ba31a4b8,process.cwdoccurred once in the detector and only in prose, with__dirname9 andimport.meta.dirname7. That tree is days old and the detector now carries 22findUpmentions — re-derive all four counts before writing any sentence that quotes them.packages/**/*.object.tsradius visible, rather than reasoning from what the old sentence claimed.Zone 3 — suggested route
Repair the prose in place, each corrected sentence carrying the measurement that makes it true, so the next reader can re-derive rather than trust it. That is what let this rot in the first place: the prohibition's reason was prose nobody could check.
Generated by Claude Code
claude commentedon Aug 24, 2026
{ "issue": 10854, "status": "done", "branch": "claude/issue-10854-findup-prose-repair", "pr": "https://github.com/objectstack-ai/objectstack/pull/11891", "premise_still_valid": true, "summary": "All three stale sentences were live on origin/main@b706af987 and are repaired in place, comments only, no executable line moved. Rows 1 and 2 got the mechanical half (the unresolvable-spelling list now says BARE process.cwd(); the 'process.cwd() appears nowhere in that detector' clause is replaced by the fact it was reaching for, that the detector reads the anchor predicate as text and calls nothing) with row 1's other two examples left untouched per Zone 1. Row 3's prohibition did NOT move and no fork arose: a valid reason survives re-derivation, but it is not the one the file gave, so it is restated on measurement. 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 old sentence was stale in a SECOND way the card did not name, since #10566's unheld-glob limb an unresolvable seed now reds the gate by name instead of the silent green the prose described, which moves the remaining danger to deleting the glob under that red. The surviving reason for keeping __dirname is the part that did not move: import.meta is a TS1470 here, and __dirname is the only remaining spelling that both type-checks under this package's config and resolves from the file alone. One nuance measured but deliberately NOT edited and NOT filed, because Zone 1 ruled those examples correct and the reading holds: rewriting the cli file's read as a template literal today leaves the file escaping and reds the gate on a lost NAME, which is consistent with the standing sentence read as describing a read written that way from the start, in a package with no declaration yet.", "tests": "Union run at final commit d520e353a. pnpm lint (repo-wide eslint . --no-inline-config) exit 0, no findings, via os-verify-lock (VERDICT command-exit 0, held 76s). pnpm --filter @objectstack/cli --filter @objectstack/plugin-auth typecheck: both echoed 'typecheck: Done', VERDICT command-exit 0. Gate family derived by scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed; 14 families, identical before and after the commit), all exit 0 with exit codes captured before any pipe: check:cross-package-test-inputs printed 'OK: 16 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.' and '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 printed 'OK (12 config(s), 657 baselined untranslated string(s), none new).' after building the connector closure it needs (its first two runs said COULD NOT MEASURE on an unbuilt worktree, which is a build-state reading, not a verdict); check-plugin-teardown-shape.mjs and docs-audit/check-affected-docs.mjs exit 0. Tests: plugin-auth full suite 'Test Files 74 passed (74) / Tests 1519 passed (1519)'; cli full suite 'Test Files 1 failed | 172 passed (173) / Tests 1 failed | 1980 passed (1981)' where the single failure was serve-node-env-production-default.e2e.test.ts with 'Error: command serve not found' because only cli's dependency closure had been built, and after pnpm --filter @objectstack/cli build that file plus the touched pin test passed 8/8; the three touched files re-run at d520e353a passed 5/5 (cli pin) and 30/30 (the two plugin-auth files). Declared narrowing: check:type-check-debt --re-measure was not run because it refuses on an unbuilt workspace closure and this diff adds only block-comment text to existing test files, so no tsc program membership and no per-entry error count can move; CI runs it on a built tree. ABLATIONS (four legs, no rebuild leg applies because this detector is a dependency-free source scan reading files from disk, never from dist): each mutation was confirmed ON DISK before any reading by counting the removed anchor text down to 0 and an injected OS_ABLATION_MARKER up to 1, with git diff --stat alongside, and every leg including the restore ran under a trap ... EXIT INT TERM; after the restore leg git hash-object matched the original and git status --porcelain was empty, with --verify back at exit 0. On b706af987: (A) reseeding managed-extension-fields.test.ts from a bare process.cwd() dropped it from --list-escapes and --verify exited 1 naming packages/**/*.object.ts annotated 'witness no longer escaping' plus packages/core/src/security/**; (B) reseeding it through the pnpm-workspace.yaml anchor kept it in --list-escapes and --verify exited 0; (C) the same reseed keyed on turbo.json behaved like (A); (D) on the cli file, rewriting its cross-package read as a template literal kept the file escaping while --verify exited 1 naming packages/services/service-cluster/src/** as unheld. Zone 2 figures re-derived on b706af987 in the detector with grep -o piped to wc -l, against a control string absent by construction reading 0: findUp 23 occurrences / 22 lines (the card's 22 is the line count), process.cwd 10 (card said 1), __dirname 12 (card said 9), import.meta.dirname 8 (card said 7) -- every one of the 10 process.cwd hits is in a comment or a --self-test fixture string, and the detector seeds its own root from import.meta.url. 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.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
feat(gates): ratchet AGENTS.md's published spellings list to the cons…
Ratchet AGENTS.md's published spellings list to the detector's consta…