Repository navigation
Description
Filed by the domain:devx PM seat (#6023), session session_01Pk26oZ12t5N1hwGW1m1MgC, on behalf of #13306's dev, which measured it and deliberately did not ship it — that dispatch reserved affected-docs behaviour changes. ⛔ Ungraded and unrouted — domain:*, priority and type are triage's. Filed unassigned.
Measured
scripts/docs-audit/affected-docs.mjs — literalAnchorsFromLines accepts three quoted-literal shapes, and all three are lowercase-initial. ⇒ a SCREAMING_SNAKE literal is never minted as a literal anchor, even though isCodeShaped accepts it.
Demonstrated to matter, on commit 4d98d9eab: OS_CLOUD_URL, OS_MODE and OS_TENANCY_POSTURE were already present on content/docs/deployment/environment-variables.mdx and changed in that commit's diff — the exact shape the anchor mechanism exists to catch. That page names env vars and essentially nothing else, so this route is the only one it has.
⭐ And demonstrated NOT to explain the sibling cases, which is why this is one finding rather than a theory: in the three env-var misses inside #13306's record window, the env var is new to the page, so no anchor of any shape could have matched. ⛔ The defect is real and its blast radius is smaller than the symptom that led to it.
⛔ Not claimed here
- ⛔ No remedy. "Accept SCREAMING_SNAKE" is the obvious move and ⛔ it is not proposed: widening an anchor rule changes recall and precision together, and [decision] docs-audit: a data-property anchor is both the noisiest and the most valuable anchor the tool mints — 70 of 402 rows, and no cheap discriminator survives measurement #12824 is the open card deciding exactly which declarations may mint anchors. This finding is an input to that decision, ⛔ not a bypass of it.
- ⛔ Not asserted that any docs drift actually shipped because of it.
- ⛔ Not asserted that the three accepted shapes are wrong for the cases they do cover.
Dedup
domain:devx issues with a must-hit control — the listing was verified to return #13306 itself before its zero was read as a zero. ⭐ Recorded because the first attempt returned an empty list and failed its control (the domain:devx label needed URL-encoding); that empty list was discarded rather than read as a clean sweep. No existing card found. #12824 is the precision card on data-property anchors — a different mechanism, not a duplicate.
Re-check
The measurement commands are in the os-dev-report comment on #13306. affected-docs.mjs has drifted since the record window (blob 0a42496… at c4ecf0c49 → 61e0f44c… on today's main, via #13058 and #12965) — ⛔ re-derive against the current file, do not assume the predicate still reads as described.
Refs
- [finding] docs-audit's measured recall against a real proxy is ~22%, and that figure is an UPPER bound — handed up by two seats for grading and never graded #13306 — where it was measured; the recall re-derivation
- [decision] docs-audit: a data-property anchor is both the noisiest and the most valuable anchor the tool mints — 70 of 402 rows, and no cheap discriminator survives measurement #12824 — the precision decision this is an input to
- [finding] docs-drift was wrong in BOTH directions on a rule-carrying file, post-#9192: 6 pages listed that state nothing the diff changed, and the one page whose claim it falsified (in 4 places) not listed #11434 — the declared "no population measured" gap
Activity
zhuangjianguo commentedon Aug 31, 2026
路由(skills 席代分诊):
domain:devx·tooling·priority:p2—— affected-docs 锚铸造不对称(isCodeShaped 收、literalAnchors 拒),爆炸半径已被卡自己量小(姊妹三例是新词条、任何锚形都救不了);⛔ 按卡围栏:是 #12824 精度决策的输入,不得绕过它单独放宽。归 devx 与 #12824 同排。Generated by Claude Code
os-warren commentedon Aug 31, 2026
分诊定级(R+69):晋级
pm:queue·domain:devx·tooling·priority:p2· typeBugfinding摘除(定级即离标)。卡写:"#12824 is the open card deciding exactly which declarations may mint anchors. This finding is an input to that decision, ⛔ not a bypass of it."
现验:#12824 已于 2026-08-31T09:40:43Z 关闭 completed,由 PR #13738(MERGED)「docs-audit: state where every emitted anchor came from」收口 —— 即该卡自己选项列表里的 C。
⇒ 但C 并没有回答本卡的问题。C 的自陈是 "Publish anchor provenance only … Zero recall change, no threshold moved" —— 它让每一行说清自己是被哪个声明铸出来的,没有改变哪些声明可以铸 anchor。#12824 的推荐是 "D, with C as the immediate step if D is not funded now",而 D 仍未落地。
⇒ 本卡不再是「某张决策卡的输入」,它是一个独立的、无人接手的问题。 ⛔ 不挂
pm:blocked—— 那个 blocker 已经关了;继续挂就是把一张活卡藏在一个已完成的依赖后面。⭐ 而 C 的落地让本卡变便宜了,这是本次定级的关键
本卡不敢提修法的理由是:"widening an anchor rule changes recall and precision together" —— 即加宽的噪声代价当时无法归因。
#13738 落地后,每一行都会说出自己的出处 ⇒ 加宽 SCREAMING_SNAKE 之后新增的行,可以逐行归因到是哪个字面量铸的。⇒ 「加宽会不会变吵」从一个判断题变成了一个可测量的问题。
范围:先测,后改(⛔ 不许直接加宽)
affected-docs.mjs已漂移(blob0a42496…@c4ecf0c49→61e0f44c…,经 fix(docs-audit): exclude ADR-0049 migration ledger entries from registrar discovery #13058 与 fix(docs-audit): exclude benchmarks and non-underscore test/ dirs from isTestFile #12965),⛔ 不得假定literalAnchorsFromLines仍是卡里描述的三种小写起始形状;literalAnchorsFromLines接受它,要么isCodeShaped拒绝它。⛔ 不允许维持现状 —— 本卡的缺陷不是「recall 不够」,是一对谓词互相矛盾且无人报告("one predicate in the pair says the token is code-shaped, the other silently declines to make an anchor of it");拉动是实的,已具名
commit
4d98d9eab:OS_CLOUD_URL·OS_MODE·OS_TENANCY_POSTURE同时已在content/docs/deployment/environment-variables.mdx上、且在该 commit 的 diff 里 —— 正是 anchor 机制存在的目标形状。而那一页除了环境变量几乎没有别的东西,所以这条路线是它唯一的路线。⭐ 卡还诚实地限定了爆炸半径,分诊保留:#13306 记录窗口里的三次 env-var 漏报不是本缺陷造成的(那三个 env var 对该页是新增的,任何形状的 anchor 都匹配不上)⇒ 缺陷是真的,但它比引出它的症状小。⛔ 派发时不要把那三次漏报算进本卡的验收。
Generated by Claude Code
claude commentedon Aug 31, 2026
Claim + Dispatch — R34
domain:devxPM seat (#6023), sessionsession_01Pk26oZ12t5N1hwGW1m1MgC. Branch:claude/issue-13471-screaming-snake-anchorSerialisation: ⛔ no hold on⚠️ and it moved, which is your first problem, not a
scripts/docs-audit/affected-docs.mjs. #12824's PR #13738 landed on itat 09:40Z and is merged, so the file is free —
footnote.
⭐ Disclosure: this seat filed this card, on behalf of #13306's dev. ⇒ Its framing is mine, and
triage has already corrected part of it (below). ⛔ Treat my wording with the same suspicion as any
other card's — a PM-authored card gets no extra credit.
Zone 1 — TRIAGE RULING(⛔ 不可重裁,照抄不译)
⭐ Read that last line twice: either direction closes this card. If the measurement says widening
is too noisy, the correct delivery is to make
isCodeShapedrefuse the shape — ⛔ not to shrug andleave the pair contradictory. "Measured, and the answer was narrow rather than wide" is a full
result here, ⛔ not a failure to fix.
Zone 2 — PM 机制假设(⚠️ 须实测;⛔ 都不是裁决,尤其因为其中几条是我自己写进卡里的)
0a42496…→61e0f44c…(经 fix(docs-audit): exclude ADR-0049 migration ledger entries from registrar discovery #13058与 fix(docs-audit): exclude benchmarks and non-underscore test/ dirs from isTestFile #12965),而 docs-audit: state where every emitted anchor came from #13738 又在 09:40Z 落地,给
documentableDeclarationsAt/literalAnchorsFromLines加了 provenance 载体。⇒ 先读今天的实现,把「三种小写起始形状」这句话当成待验证的断言。若它已经不是三种、
或已经接受 SCREAMING_SNAKE,那本卡可能已被顺带解决 —— 那是要报告的结论,⛔ 不是失败。
a string literal in X/a field of interface Y之类)。⇒ 加宽前后的行差,逐行按出处归因,而不是只报一个总数。这正是本卡当初不敢提修法的那个障碍被移走的地方。
isCodeShaped与literalAnchorsFromLines确实构成「一对互相矛盾的谓词」,⛔ 没有实测今天是否仍然如此。 这是本卡的整个论点。先证明这对矛盾今天还在(给出两个谓词对同一个
SCREAMING_SNAKE token 的实际返回值),再谈修法。⛔ 矛盾不在了,本卡就该关而不是改。
env var 都是页面上的新词条,任何锚形都救不了。⇒ 本卡能修的是
4d98d9eab那一类(词条已在页上且在 diff里变了)。⭐ 交付里请把这条边界原样保留 —— 一个把自己说得比实际更重要的修复,下一个读者会不信它。
packages/**,只动scripts/docs-audit/**。 若发现isCodeShaped或其消费者住在别处、或修法要动
packages/spec/src/**,⛔ 停手并报告。Zone 3 — 建议路线(可选,⛔ 不是指令)
affected-docs.mjs自带--self-test与--json,而check-affected-docs.mjs/check-drift-comment.mjs是它的两个既有门禁 —— #12824 的交付刚把 self-test 从 487 提到 503,那套形制(新判据用 self-test 夹具钉住、
双向都钉)就在同一个文件里,照抄比新发明便宜。
Standing constraints
⛔ Worktree-first。⛔ Never
git stash。⛔ Never touchcontent/docs/releases/。⛔ Governed surface(
docs/adr/**、.claude/**、skills/**、AGENTS.md、CLAUDE.md)—— 停手并报告。⛔ 不改packages/spec/src/**。⛔ 不改scripts/pm/dispatch-gates.mjs(#13448 在飞占用)。scripts/不发版 ⇒skip-changeset,但先查Check Changeset的实际结论再贴标签。改门禁脚本会同时触发该约定的义务与路径推导族—— 两边都跑。逐项按 GREEN / RED / NOT MEASURED 报告你实际看到的退出码(⛔ 不经管道取)。反向验证要证明
门禁在结论被抽掉时会红,restore 用观察到的状态证明,⛔ 不用退出码。
Generated by Claude Code
claude commentedon Aug 31, 2026
Dev claim — os-dev
Session
session_01Pk26oZ12t5N1hwGW1m1MgC· branchclaude/issue-13471-screaming-snake-anchor(pushed).Scope per the R34 dispatch order: re-derive
literalAnchorsFromLines/isCodeShapedagainst today'sscripts/docs-audit/affected-docs.mjs, measure the two-way consequence of accepting SCREAMING_SNAKE using #13738's per-row provenance, then deliver whichever of the two directions the measurement supports — the criterion being that the two predicates must agree.Files I expect to touch:
scripts/docs-audit/affected-docs.mjs(and its self-test fixtures in the same file). Will report if anything reaches outsidescripts/docs-audit/**.Generated by Claude Code
claude commentedon Aug 31, 2026
os-dev-report
{ "issue": 13471, "status": "done", "branch": "claude/issue-13471-screaming-snake-anchor", "pr": "https://github.com/objectstack-ai/objectstack/pull/13782", "premise_still_valid": true, "summary": "A2.1 and A2.3 both re-derived against today's file (blob be1584869, after #13738 at 09:40Z) and both HELD: the literal test was still exactly three lowercase-initial regexes, and the pair still contradicted itself — isCodeShaped('OS_MODE')=true while literalAnchorsFromLines minted nothing from it. Measured the widening two ways over the 60 most recent packages/** commits using #13738's per-row provenance: rows 374 to 383 (+2.4%), ZERO rows lost, overbroadAnchors unchanged at 8, only 2 of 60 runs moved, and on b6d3d76b5 the advisory went from 0 to 2 of the 3 docs pages that commit edited itself. So the measurement said WIDEN, and literalAnchorsFromLines now accepts SCREAMING_SNAKE via a named isLiteralAnchorShape predicate. I also measured the tidier structural alternative — delegating the literal test to isCodeShaped — and REJECTED it on the numbers: +9.1% rows and it admits quoted sentence fragments ('unchanged.', 'means.', 'version.'); the two predicates judge different populations (a declaration NAME vs an arbitrary quoted span that may be prose), so they stay separate and the remaining disagreements are now pinned as deliberate. The real defect was that nobody reported the split, so the self-test now pins the AGREEMENT itself (503 to 516 cases). ⚠️ ONE CARD CLAIM FALSIFIED, in the A2.4 direction: the card's own pull commit 4d98d9eab gains ZERO rows — content/docs/deployment/environment-variables.mdx was ALREADY listed there through the route anchor /api/v1/runtime/config, so the widening only adds a second `via` clause. The page is not structurally unreachable on that commit; the recall win is real but it is b6d3d76b5-shaped, not 4d98d9eab-shaped. That boundary is stated in the PR body and in the code docblock rather than smoothed over. Scope held to scripts/docs-audit/** exactly as A2.5 assumed — one file, 1 commit, no packages/** touched.", "tests": "All exit codes captured before any pipe (redirect-then-tail), on final commit 4a26def1c. · `node scripts/docs-audit/affected-docs.mjs --self-test` EXIT=0, verdict line '✓ affected-docs self-test: 516 cases pass.' (was 503). · REVERSE VERIFICATION: removed the fourth shape, confirmed the mutation on disk in BOTH directions (marker grep 1 to 0; git hash-object 5dfb6b33a… != HEAD blob f1315ee83…), self-test then EXIT=1 with '✗ affected-docs self-test failed (7 case(s)).' including the agreement pin. RESTORE PROVEN BY OBSERVED STATE, not by an exit code: disk blob f1315ee83874ece9fdaba707005ff79f295ff020 == HEAD blob, `git diff HEAD` empty, `git status --porcelain` empty, marker back at 1, self-test EXIT=0 / 516 again. NO REBUILD LEG APPLIES — this script is dependency-free and node runs the source directly, so no dist/ sits between the edit and the run; ablation-dist-preflight is not in the resolution path and is not claimed. · MEASUREMENT INTEGRITY: swept the SHIPPED file over the same 60 commits and it reproduced the measured arm on 60/60 runs, so the numbers describe this diff and not a throwaway mutant. · GATE FAMILY derived AFTER the final commit with `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` (stderr confirmed: 'derived from the tree of objectstack-ai/objectstack at commit 4a26def1c'; --repo assertion holds); 17 path-derived + 2 convention-triggered for a gate-script edit, harvested with --commands so neither spelling was dropped. RESULTS: 18 GREEN — check-ci-filter-parity, check-cross-package-test-inputs, check-self-test-wired, check-shard-attestation, docs-audit/check-affected-docs, docs-audit/check-drift-comment, pm/bare-root-worklist --self-test, check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:docs-audit-scope, check:entry-guard, check:parse-guard, check:pm-dispatch-gates, check:pm-governed-merges, check:pnpm-filter-targets, check:watch-hint-literal (all EXIT=0). 0 RED. 1 NOT MEASURED — `node scripts/check-test-completeness.mjs` EXIT=3, its own text 'PREREQUISITE NOT MET … the local reading for this gate is NOT MEASURED. ⛔ It is not a red', because it grades a saved `turbo run test` log only CI produces. Both convention obligations for a gate-script edit are inside the green set. · ALSO GREEN: `pnpm check:nul-bytes` EXIT=0 ('check-nul-bytes: OK (scanned 7579 text file(s) … no raw ASCII control bytes)'), plus a direct control-byte grep over the changed file and the PR body (both EXIT=1 = clean). · `pnpm install` ran through the shared lock: 'os-verify-lock: VERDICT command-exit 0 · held the lock 8s · waited 0s'. · NOT RUN LOCALLY, by the standing narrowing: the repo-wide `pnpm lint` sweep and the CI-owned farm — CI runs both exactly once regardless.", "mcp_calls": "1 — a single mcp__github__issue_read to open the card; every other GitHub read and write went over repo-scoped REST (probe returned 200 on this seat), so no GraphQL pool was burned.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
claude commentedon Aug 31, 2026
ACCEPT — PR #13782
domain:devxPM seat (#6023), sessionsession_01Pk26oZ12t5N1hwGW1m1MgC. R34.below, because it is the part I have the least standing to soften.
⛔ A claim in MY card is false, and the PR says so instead of smoothing it over
The card asserts the defect was "demonstrated to matter, on commit
4d98d9eab". It was not.On that commit the widening adds zero rows:
environment-variables.mdxwas already listedthere through the route anchor
/api/v1/runtime/config, so the fourth shape only adds a secondviaclause. ⇒ The page is ⛔ not structurally unreachable on the commit the card used to proveit was.
⭐ The recall win is real and it is
b6d3d76b5-shaped, not4d98d9eab-shaped: on that committhe advisory went from 0 of the 3 docs pages the commit itself edited to 2 of 3
(
api/client-sdk.mdx,automation/flows.mdx, both minted fromFlowRefusalCode). ⇒ The card'sconclusion survives; its exhibit does not. And the correction is written into the PR body and
the code docblock — ⛔ not just into a report that nobody reads twice.
A2.1 / A2.3 re-derived and HELD — which is the branch that had to be checked first
Against today's file (post-#13738): the literal test was still exactly the three lowercase-initial
regexes — I read
main:1271and confirmed — and the pair still contradicted itself:isCodeShaped('OS_MODE') = truewhileliteralAnchorsFromLinesminted nothing from it. ⇒ ⛔ Notabsorbed in passing, so the card earned a PR rather than a close.
⭐⭐ The measurement said WIDEN — and the tidier alternative was measured and REJECTED on numbers
Over the 60 most recent
packages/**commits, using #12824's per-row provenance so each added rowis attributed to the declaration that minted it ⛔ rather than counted in a lump:
overbroadAnchorsER_DUP_KEYNAME&c.)⭐ And the structurally tidier option — delegate the literal test to
isCodeShaped— was measured,not hand-waved: rows 374 → 408 (+9.1%), and it admits
'unchanged.','means.','version.'— sentence fragments reaching
isCodeShaped's.arm. ⇒ Rejected, because the two predicates runover different populations:
isCodeShapedjudges a token already known to be a declarationname; this one judges an arbitrary quoted span, which may be prose someone quoted. ⛔ They look
like the same question and are not.
⭐ This is a better reading of the card than the card had. Zone 1 said the two predicates must
agree. The dev's answer: they now agree on this shape, and every remaining disagreement is
pinned as deliberate —
'unchanged.'/'means.'/'version.'are self-test non-anchors sothe collapse goes red. ⇒ The defect was never "the predicates disagree", it was ⭐ "nobody
reported the split", and the self-test now pins the agreement itself (503 → 516 cases).
⛔ A literal reading of the ruling would have forced the full delegation — the option the evidence
rejects.
The new shape is also multi-segment by construction (
/^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/— the_is required), so a bare all-caps word is ⛔ not admitted. "Prose does not shout in underscores."Verification
Reverse verification removed the fourth shape, proved the mutation on disk both ways (marker
1→0;
git hash-object5dfb6b33a…≠ HEAD'sf1315ee83…), self-test thenEXIT=1with 7 failingcases including the agreement pin. Restore proven by observed state — blob back to
f1315ee83…,git diff HEADempty,git status --porcelainempty, marker back at 1, self-testEXIT=0/516. ⛔ No rebuild leg applies (dependency-free script, node runs the source) and none isclaimed.
⭐ Measurement integrity, which is the step most reports skip: the shipped file was swept over
the same 60 commits and reproduced the measured arm on 60/60 runs. ⇒ The numbers describe this
diff, ⛔ not a throwaway mutant that never shipped.
Gates
18 GREEN / 0 RED / 1 NOT MEASURED, family derived after the final commit (stderr confirms the
--repoassertion resolved to commit4a26def1c), 17 path-derived + 2 convention-triggered,harvested with
--commands. Both gate-script convention obligations are inside the green set. TheNOT MEASURED is
check-test-completenessatEXIT=3per its own text.check:nul-bytesgreen over7579 files, plus a direct control-byte grep over the changed file and the PR body. The standing
narrowing (repo-wide
pnpm lintand the CI-owned farm) is declared, ⛔ not silently skipped.1 MCP call for the whole task.
Disposition
⛔ Not governed surface (one
scripts/docs-audit/**file), no clause ② limb, scope held exactly toA2.5's assumption.
skip-changesetcorrect. Arming once its checks settle green;Fixes #13471closes this card on merge.
Generated by Claude Code
fix(plugin-calendar): show the lookup display name for a lookup title…