Uh oh!
There was an error while loading. Please reload this page.
docs(devx): reciprocal pointers for the invoked-as three-copy sync obligation - #12084
Merged
yinlianghui merged 1 commit intoAug 25, 2026
Merged
Conversation
…ligation Both objectstack copies of the argv[1]-vs-import.meta.url entry-point predicate (scripts/invoked-as.mjs's isEntrypoint/invokedAs, and packages/cli/src/utils/ invocation.ts's isProcessEntry) named only each other. Neither pointed at the third copy, objectui's own scripts/invoked-as.mjs (which already names both objectstack copies and states "All three copies ... Change one, change the others", merged in objectui PR #6260 / objectui@ef2a3bd). An agent editing either file in this repo had no way to discover that a third copy exists and must move with it. Comment-only, both files: the local sibling section in scripts/invoked-as.mjs is renamed "## The siblings" and gains one paragraph naming the objectui copy; packages/cli/src/utils/invocation.ts's isProcessEntry docstring gains one paragraph naming both siblings. Neither file's prose is otherwise corrected — both were already accurate for this tree. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UjM2ia8Av1v5NqfqQEQmC6
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 23 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
yinlianghui
marked this pull request as ready for review
August 25, 2026 08:41
Uh oh!
There was an error while loading. Please reload this page.
yinlianghui
deleted the
claude/issue-12013-invoked-as-reciprocal-pointers
branch
August 25, 2026 08:56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#12013
What
Both objectstack copies of the
argv[1]-vs-import.meta.urlentry-point predicate —scripts/invoked-as.mjs(isEntrypoint/invokedAs) andpackages/cli/src/utils/invocation.ts(isProcessEntry) — named only each other. Neither pointed at the third copy, objectui's ownscripts/invoked-as.mjs, which already carries "All three copies … Change one, change the others". An agent editing either objectstack file had no way to discover the third copy exists.Comment-only, both files:
scripts/invoked-as.mjs: the local-sibling section is retitled## The siblings, and why the duplication is deliberate(matching objectui's heading verbatim) and gains one paragraph naming objectui'sscripts/invoked-as.mjs; the closing sentence is updated from "Both carry … Change one, change the other" to "All three copies carry … Change one, change the others" — mirroring objectui's merged wording.packages/cli/src/utils/invocation.ts: theisProcessEntrydocstring gains one paragraph naming both siblings (this repo'sscripts/invoked-as.mjsand objectui's).Neither file's existing prose is corrected or otherwise touched — both were already accurate for this tree (triage ruling, confirmed below).
Zone 2 — what I measured, against the PM's assumptions
origin/main=f7b25c546(matches the claim comment):scripts/invoked-as.mjs—objectui× 0,change the others× 0,invoked× 15 (positive control, file really read).packages/cli/src/utils/invocation.ts—objectui× 0,change the others× 0, 186 lines. Premise held; neither file carried a back-pointer.opened事件上先于skip-changeset标签落地而判红 —— 每个走 skip 路线的 PR 都要白跑一次重投(今日 6 例) #6260 is merged (state: closed,merged: true, squash-merged asobjectui@ef2a3bd8d8a12957d565748cff0eb47cf03ee548, 2026-08-25T05:20:54Z). Read its mergedscripts/invoked-as.mjsdirectly offobjectui:main. The## The siblings, and why the duplication is deliberatesection's final sentence, verbatim (one placeholder spelled in words below since GitHub's body sanitizer strips a literal angle-bracket fragment even inside a code span): "The duplication is therefore structural, but DIVERGENCE is not allowed -- two predicates answering this question differently is precisely the defect being closed. All three copies carry the same two legs: realpath for symlinks, and directory resolution fornodegiven a directory argument. Change one, change the others." Mirrored into both objectstack files (heading text and closing sentence); the new middle paragraph in each is original, since objectui's own version only had to name objectstack's two copies, while each objectstack file has two different siblings to name (its local counterpart, already named, plus objectui).node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, run before and after adding the changeset: 23 families matched the actual diff, exactly reproducing the PM's 17 pre-changeset + 6 changeset-triggered lists, no additions or omissions on my re-derivation. All 23 green below, plus the standingcheck:nul-bytesclause.check:entry-guardandscripts/invoked-as.mjs --self-test— confirmed unaffected: self-test still reports 11 cases pass,check:entry-guardstill reports the same shape (157 files, 113 bindings, 111 inert). Docblock-only edit, as assumed.scripts/check-empty-changeset.mjsand thepr-automation.yml"Require a changeset" step do not do per-file path analysis in this repo (unlike objectui'scheck-changeset-presence.mjs, which objectstack has no equivalent of) — the CI gate is a binary author-judgment call (real changeset vs.skip-changesetlabel), andcheck:changeset-gate-self-testsonly pins the checkers' own fixtures, not this PR's paths. The operative rule is the devx lane doc's own text (.claude/skills/pm-dispatch/references/lanes/devx.md): "changeset 按 publish 面判:根scripts// docs / test-only ⇒skip-changeset;落进已发布包的源 ⇒ 真 changeset" — tied to file location, not content.packages/cliis published ("name": "@objectstack/cli","version": "17.2.0", no"private"), and the edit lands in itssrc/. Precedent in.changeset/cli-readme-drop-os-studio.md— apatchchangeset for a pure prose correction topackages/cli/README.md, not even compiled source — confirms this repo's convention treats "lands in a published package" as sufficient regardless of whether the change is behavioral. So: real changeset added (@objectstack/cli: patch), not the label.scripts/invoked-as.mjsalone would qualify forskip-changeset, but the rule has no per-file carve-out at PR granularity, and thepackages/cliedit governs the whole PR.Cross-repo note
Read-only against
objectstack-ai/objectui, refmain(post-merge of #6260) — no objectui file touched, branched, or opened by this PR.Verification
All commands run in a dedicated worktree (
../objectstack-12013), heavy ones serialized throughscripts/pm/os-verify-lock.sh. Verdicts below are each gate's own printed line, exit code captured before any pipe. Final commit:258b2cadf.Dependency-build prerequisite (unrelated to this diff — a stale
dist/in this fresh worktree, not a defect):pnpm --filter '@objectstack/example-showcase^...' buildwas needed beforecheck:i18n-coveragecould measure all 12 configs; after that it readOK (12 config(s), 657 baselined untranslated string(s), none new).pnpm --filter '@objectstack/cli' buildpnpm --filter '@objectstack/cli' typecheckpnpm --filter '@objectstack/cli' exec vitest run --maxWorkers=2 src/utils/invocation.test.tsTest Files 1 passed (1)·Tests 17 passed (17)node scripts/invoked-as.mjs --self-test✓ invoked-as self-test: 11 cases pass …pnpm check:entry-guard✓ check:entry-guard: 157 scripts/ file(s) … every entry guard goes through invoked-as.mjs; 113 export bindings, 111 of them inert on import (2 known-unsafe, ⛔ SHRINK-ONLY)pnpm check:agent-test-spelling✓ check-agent-test-spelling: 0 violations …pnpm check:cross-package-test-inputsOK: 16 package(s) read outside themselves, all declared …pnpm check:i18ncheck-i18n-bundles: OK (9 package(s) — all bundles in sync, no undeclared authoring keys).pnpm check:i18n-coveragecheck-i18n-coverage: OK (12 config(s), 657 baselined untranslated string(s), none new).pnpm check:parse-guardpnpm check:pnpm-filter-targets✓ check:pnpm-filter-targets: 135/168 …pnpm check:published-files✓ check:published-files — 69 publishable package(s) of 78 …pnpm check:slot-lookup✓ slot-lookup ratchet holds: 107 unswept site(s) …, none newpnpm check:test-source-aliascheck-test-source-alias OK — 72 packages with tests scanned …pnpm check:type-source-resolutioncheck-type-source-resolution OK — 93 tsc program(s) across 77 packages scanned …pnpm check:changeset-gate-self-testspnpm check:objectui-changeset✓ objectui-range --self-test: all checks passednode scripts/check-adr-0087-registration.mjs✓ … this PR adds no declared-breaking changeset (0 non-breaking changeset(s) seen).node scripts/check-changeset-no-major.mjs✓ This diff introduces no 'major' bump.node scripts/check-ci-filter-parity.mjsOK: all 96 declared cross-package glob(s) …node scripts/check-cross-package-test-inputs.mjsOK: 16 package(s) read outside themselves …node scripts/check-empty-changeset.mjs✓ No empty-frontmatter changeset introduced by this diff (0 declaring changeset(s) added).node scripts/check-plugin-teardown-shape.mjs✓ … 0 known-unreached, ⛔ SHRINK-ONLY, baseline fully burned down.node scripts/docs-audit/check-affected-docs.mjs✓ affected-docs self-test: 451 cases pass.node scripts/docs-audit/check-drift-comment.mjs✓ check-drift-comment: 56 cases pass across 5 fixture diff(s).node scripts/pm/release-rehearsal-clone.mjs --self-test✓ self-test passedpnpm check:nul-bytes(standing clause)check-nul-bytes: OK … no raw ASCII control bytes.Control-byte self-scan (
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'on both edited files): no matches.Generated by Claude Code