Skip to content

fix(devx): declare the objectui-pin-citations population so a .objectui-sha change set derives it - #15698

Merged
baozhoutao merged 3 commits into
mainfrom
claude/issue-15604-objectui-sha-derives-pin-citations
Sep 5, 2026
Merged

fix(devx): declare the objectui-pin-citations population so a .objectui-sha change set derives it#15698
baozhoutao merged 3 commits into
mainfrom
claude/issue-15604-objectui-sha-derives-pin-citations

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #15604

packages/spec/scripts/check-objectui-pin-citations.ts reads the repo-root pin file
.objectui-sha and walks packages/spec/src, but every path it opens is computed
(PIN_FILE from REPO, SRC from SPEC). extractWatchHints is a pure string
function over a gate's own source text, so it found no path literal here and this gate
had no population at all — a change set consisting only of the pin file, exactly the
class this gate exists for, derived zero commands naming it.

This declares the population on the gate, in the root-file idiom, and pins it with
the self-consistency assertion shape from scripts/check-doc-anchors.mjs.

const ROOT_FILE_WATCH_HINTS = ['.objectui-sha/**'];
const ROOT_DIR_WATCH_HINTS  = ['packages/spec/src/**'];

No hand list of citing files: they stay discovered by regex (sourceFiles(SRC) +
scanFile), so today's citer list cannot go stale. .objectui-sha itself and every spec
citation are untouched.

The three traps, measured

1. hintCovers admits the spelling. A bare .objectui-sha carries no separator and
reaches the predicate as a bare word; the /** suffix is the sanctioned root-file
escape. Measured against the live module:

hintCovers('.objectui-sha/**', '.objectui-sha')        -> true
collapseHint('.objectui-sha/**')                       -> '.objectui-sha'
hintCovers('.objectui-sha/**', 'other/.objectui-sha')  -> false
hintCovers('packages/spec/src/**', 'packages/spec/src/data/field.ts') -> true
extractWatchHints(this gate's source) -> [".objectui-sha/**","packages/spec/src/**"]

2. check:watch-hint-literal rosters both names. scripts/check-watch-hint-literal.mjs
lists ROOT_DIR_WATCH_HINTS and ROOT_FILE_WATCH_HINTS at :274-:276, and documents
AGENTS.md/** at :46 as the root-FILE spelling. Verdict line after this change:

check-watch-hint-literal: 60 declaration(s) across 4 rostered name(s) --
ROOT_DIR_WATCH_HINTS 38, ROOT_FILE_WATCH_HINTS 11, ROOT_WATCH_HINTS 3,
DECLARED_WATCH_HINTS 8 -- every one an array of quoted literals inside its own
statement, every rostered name non-empty, and no unrostered spelling of the idiom.

3. dispatch-gates does derive a pnpm-filter-invoked package-scoped gate from a
root-file change set.
It does — no change to scripts/pm/dispatch-gates.mjs was needed.
The sibling packages/spec/scripts/check-llms-txt.ts already declares
DECLARED_WATCH_HINTS and is reached the same way.

Before / after, the card's own specimen

node scripts/pm/dispatch-gates.mjs --commands .objectui-sha --repo objectstack-ai/objectstack

commands matched by path names check:objectui-pin-citations
BEFORE — origin/main 7bf96cfd0, detached worktree 12 5 no (absent from the output entirely)
AFTER — this branch 13 6 yespnpm --filter @objectstack/spec run check:objectui-pin-citations

Ablation

Trap-guarded (trap ... EXIT INT TERM), absolute paths throughout, mutation proved on
disk by anchor counts before reading anything, restore proved by blob hash and
git diff HEAD. No rebuild leg is owed or possible here: the gate is executed as source
by tsx, and extractWatchHints reads that same source text — no dist/ participates
in either direction, which stages A and B confirm empirically (the mutation took effect
with no build step).

HEAD_BLOB=f3608f84986d0d415185840d395fc1e1e184c1b7

A. ROOT_FILE_WATCH_HINTS emptied (docblock literals left in place)
   ON-DISK PROOF A: removed-text count 1 -> 0 ; injected-text count = 1
   derivation -> 12 command(s), 5 matched by path, gate named 0 times
   gate self-test EXIT=1
     the declared root file is the pin file this gate opens:  vs .objectui-sha

B. the two docblock occurrences stripped as well
   ON-DISK PROOF B: remaining '.objectui-sha/**' occurrences = 0
   derivation -> 12 command(s), 5 matched by path, gate named 0 times

   Finding: A and B are identical, so extraction is comment-masked — the CONST is the
   load-bearing declaration and the prose around it derives nothing on its own.

RESTORE
   RESTORE OK: hash f3608f84986d0d415185840d395fc1e1e184c1b7 == HEAD blob,
               git diff HEAD empty
   derivation -> 13 command(s), 6 matched by path, gate named 1 time
   gate self-test EXIT=0

Verification

Every command node scripts/pm/dispatch-gates.mjs --changed --commands --repo objectstack-ai/objectstack
emits was run on the final head 89541345c; that derivation is byte-identical to the one
these runs came from. 49 derived commands, 48 exit 0, 1 NOT MEASURED. Heavy runs went
through scripts/pm/os-verify-lock.sh (slot issue-15604); VERDICT lines
command-exit 0 · held the lock 431s / 48s / 182s / 191s.

check:objectui-pin-citations   EXIT=0
  8 asserting objectui pin citation(s) match .objectui-sha (a472b0716), 16 historical
  citation(s) recorded and not checked, across 1178 spec source(s).
  self-test line now names the declaration.
check:pm-dispatch-gates        EXIT=0   dispatch-gates self-test: 1445 cases pass.
check:watch-hint-literal       EXIT=0   57 self-test cases pass; 60 live declarations.
check:nul-bytes                EXIT=0   scanned 7583 text file(s); no raw control bytes.
26 direct-node derived gates   EXIT=0 each (0 non-zero)
18 further pnpm derived gates  EXIT=0 each

The gate has no separate *.test.ts; its suite is the inline --self-test, which runs
first in the check: script and is green above with the new battery in its success line.

NOT MEASURED, by name:

  • pnpm check:dual-build-cjs-loads — exit 3, PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/ (103 packages). Its own self-test passed
    (93 cases). Not a red and not a pass; it is unreachable by this diff, which touches one
    tsx script that is never built and never published.
  • The 6 families whose argv takes a value from the workflow ($RUNNER_TEMP,
    matrix.shard) — dispatch-gates prints them as NOT MEASURED itself.

No changeset. packages/spec/scripts is not in packages/spec/package.json's files
array (verified: ["dist","json-schema","liveness","prompts","llms.txt","README.md","src/**/*.zod.ts","CHANGELOG.md","api-surface","spec-changes.json"]),
so nothing here is published. skip-changeset applied.

🤖 Generated with Claude Code

https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk


Generated by Claude Code

…tui-sha` change set derives it

The gate reads the root pin file and walks `packages/spec/src`, but every path
it opens is computed from `REPO`/`SPEC`, so `extractWatchHints` found nothing
and dispatch-gates had no population for it at all. A change set consisting
only of the pin file — exactly the class this gate exists for — derived zero
commands naming it, and a pin bump ran 47 derived commands green before CI
redded here on 8 stale citations.

Declares both halves in the root-file idiom (`check-doc-anchors.mjs`,
`git-merge-regen.mjs`) and pins them against what the gate really reads with
the self-consistency assertion shape from `check-doc-anchors.mjs`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
…measured on

The declaration docblock quoted `53edffe09`, the branch's original base. The
before/after specimen was re-measured on `7bf96cfd0` (current origin/main) in a
detached worktree, so the docblock now cites that commit and records both legs
— 12 commands / 5 matched by path without the declaration, 13 / 6 with it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

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 95d5cbb31687558ac63dfdde90950d06f82820ebpackageMentionDocs.

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

ACCEPT — PM seat domain:devx @ objectstack (#6023), session session_012zGPuVVX3deAx9LdjK8jCk.

Reviewed against the three-dot diff at 89541345c (1 file, +111/−1), not the report. Closing keyword: Fixes #15604 only.

What the diff does: packages/spec/scripts/check-objectui-pin-citations.ts declares its population in the root-file idiom — ROOT_FILE_WATCH_HINTS = ['.objectui-sha/**'] and ROOT_DIR_WATCH_HINTS = ['packages/spec/src/**'] — with a docblock recording the measured BEFORE/AFTER and why the glob suffix is the sanctioned spelling for a root file. The --self-test gains five pins ported from check-doc-anchors.mjs:670's shape: the declared root file equals path.relative(REPO, PIN_FILE), the declared subtree equals path.relative(REPO, SRC), every entry carries a separator, the spellings are provenance (not paths that existsSync), and every scanned source lies under the declared subtree. No hand list; .objectui-sha and every citation untouched; dispatch-gates.mjs NOT edited (trap 3 held — the pnpm-filter-invoked gate derives from a root-file change set already, as check-llms-txt.ts shows).

Measured by this seat (dispatch-gates is plain node; PR head and origin/main in separate detached worktrees):

node scripts/pm/dispatch-gates.mjs --commands .objectui-sha --repo objectstack-ai/objectstack
  origin/main:  the gate is named 0 time(s)
  PR head:      the gate is named 1 time(s)  (pnpm --filter @objectstack/spec run check:objectui-pin-citations)

The gate's own self-test runs under tsx — NOT MEASURED on this seat; CI's Lint & Repo Gates is the arbiter (in progress at review time; flip waits for both required jobs).

Fences held: one file; check-governed-merges.mjs --test0 of 1 path(s) hit the register; no other open PR holds the file; git merge-tree origin/main clean; skip-changeset (the files array excludes packages/spec/scripts).

Observation recorded, not filed (dev handed it up): the artifact-roster families dispatch-gates scores "silent" for every card (~34) are the same disease class one rung along — a population declared as a roster rather than a scan surface. That is a triage question, not this card's scope; noted on the seat post.


Generated by Claude Code

@baozhoutao
baozhoutao marked this pull request as ready for review September 5, 2026 03:42
@baozhoutao
baozhoutao enabled auto-merge September 5, 2026 03:42
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 5, 2026
Merged via the queue into main with commit 53fe481 Sep 5, 2026
40 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-15604-objectui-sha-derives-pin-citations branch September 5, 2026 04:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tooling

Projects

None yet

2 participants