Skip to content

check:keyed-text-bounds: skip tmp/, move scaffold test's temp root under node_modules - #17421

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-16195-keyed-text-bounds-ignored-trees
Sep 10, 2026
Merged

baozhoutao merged 1 commit into
mainfrom
claude/issue-16195-keyed-text-bounds-ignored-trees

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Closes #16195

What changed

Shape 1 — check:keyed-text-bounds's walk (scripts/check-keyed-text-bounds.mjs) now skips tmp/ directories, the same way it already skips node_modules, dist, build, etc. I added 'tmp' to the existing SKIP_DIRS set rather than reading .gitignore: SKIP_DIRS is already the walk's one filter point and already carries this exact family of "build/tooling litter, not source" directories (node_modules, dist, build, coverage, .turbo, .next, .cache, .changeset) — tmp/ is the same kind of entry, not a new mechanism. Reading .gitignore would add a second, more powerful exclusion mechanism (glob/negation semantics) for one directory name, and risks silently widening the walk's exclusions to patterns nobody has reviewed against this gate's population.

:376 design note check — the walk is deliberately "the whole repository minus SKIP_DIRS", specifically so a boundary-scoped sweep (narrowing the walk to ROOT_DIR_WATCH_HINTS) can't reopen the hole this gate exists to close. Adding one more literal to SKIP_DIRS keeps that sentence true: the walk is still repo-wide minus SKIP_DIRS, just with one more skip entry — nothing about the population's boundary-scoping changed.

Shape 3 — packages/cli/test/init-scaffold-authoring-rules.test.ts's scaffold temp root moved from this package's git-ignored tmp/ to under this package's own node_modules/ (node_modules/.init-scaffold-authoring-rules/), matching the placement generate-scaffold-validates.test.ts already documents and uses for the same reason (@objectstack/spec resolution needs the temp project under packages/cli so Node can walk up into its node_modules). node_modules is already in SKIP_DIRS regardless of this PR, so this closes the leftover-after-a-killed-run failure mode more robustly than shape 1 alone would for this one test. The afterAll cleanup logic (roots array, unchanged) already targets whatever TMP_ROOT resolves to, so no separate cleanup-path edit was needed beyond the constant itself.

Shape 2 is intentionally NOT done here (per triage/dispatch: out of this card's scope). See "Shape 2" below.

Acceptance legs (reproduced on origin/main d57611dfd3 before, and on this branch after, the fix)

Before fix (repro, not committed): an os init-shaped .object.ts written under packages/cli/tmp/…/src/objects/my_app_item.object.ts →

check:keyed-text-bounds: 1 declaration(s) this scan cannot classify
  packages/cli/tmp/full-plugin-repro/src/objects/my_app_item.object.ts:1
    no object declaration recognised in a `.object.ts` file.

exit 2.

Leg 1 — ignored tree ⇒ exit 0. Same file, same content, under packages/cli/tmp/ after the fix:

✓ check:keyed-text-bounds: 112 *.object.ts files under packages/** + apps/** + examples/** (walk is repo-wide; 0 outside), …

exit 0.

Leg 2 — anti-overfix control, tracked directory ⇒ still exit 2. The identical file copied into a tracked directory (packages/cli/src/tracked-repro-objects/my_app_item.object.ts) still produces:

check:keyed-text-bounds: 1 declaration(s) this scan cannot classify
  packages/cli/src/tracked-repro-objects/my_app_item.object.ts:1
    no object declaration recognised in a `.object.ts` file.

exit 2. The refusal is unchanged for tracked, unrecognised shapes — only the walked population moved.

Both repro trees were removed before committing; neither leg's files are part of this diff.

Shape 2 (out of scope here)

Per the card: the platform's gate (112/112 recognised files are the ObjectSchema.create({…}) factory shape) and os init's own emitter (a plain, annotated Data.ServiceObject object literal) disagree about how a .object.ts may be written, and that's a decision, not a side effect of this cleanup. I looked for a standing ruling on which shape is authorised and did not find one framed as such, but did find real evidence on both sides:

  • content/docs/data-modeling/schema-design.mdx states the factory shape as "the" pattern for every object definition; packages/create-objectstack's own bundled template also uses it — a second, independent official scaffolder agreeing with the gate.
  • content/docs/deployment/cli.mdx:1323 documents os init/os g emitting the Data.*-typed literal as current, undeprecated behaviour, and packages/cli/src/commands/init.ts's TEMPLATES is actively kept in sync for version policy (scripts/sync-scaffold-emission-policy.mjs), i.e. treated as maintained source of truth, not legacy.

Filed as #17418 (unlabelled, for triage), since I could read the disagreement clearly but not its resolution.

Changeset reading

Both changed files were measured against their package's published files[], not guessed:

  • scripts/check-keyed-text-bounds.mjs lives at the monorepo root, which is "private": true (@objectstack/spec-monorepo) and is never published; it isn't referenced from any workspace package's files[].
  • packages/cli/test/init-scaffold-authoring-rules.test.ts — packages/cli's package.json files is ["dist", "README.md", "CHANGELOG.md"]; test/** is not included.

Neither changed path ships in any published artifact ⇒ no changeset owed. The skip-changeset label has been applied to this PR.

Tests run

  • node scripts/check-keyed-text-bounds.mjs — exit 0 on the clean tree (112 files, 148/148 bounded, matches pre-change baseline).
  • node scripts/check-keyed-text-bounds.mjs --self-test — PASS (0 failures), 17 cases.
  • pnpm --filter @objectstack/cli exec vitest run --project unit test/init-scaffold-authoring-rules.test.ts — 6/6 passed (after building the package's dependency closure, pnpm --filter '@objectstack/cli^...' build, 58 workspace projects, exit 0).
  • Repro/anti-overfix legs above, run manually against the gate script; files removed before commit.
  • Gate union derived from node scripts/pm/dispatch-gates.mjs --commands for this diff's changed paths (67 commands): 63 passed cleanly on the first pass; check:query-options-erasure was only slow in the batch (90s cap) and passes cleanly (exit 0) standalone — 64/67 verified green. check:dual-build-cjs-loads and check:type-check-debt both refuse with PREREQUISITE NOT MET (exit 3) because they read built output across the whole monorepo, unrelated to either changed file — outside this diff's package-scoped local validation, left to CI. check:pm-dispatch-gates (the dispatch-gates tool's own self-test, unrelated to either changed file — scripts/pm/** is untouched here) ran every visible assertion green (no ✗ observed) but did not finish inside two long timeouts (90s then 580s); recorded as NOT MEASURED to completion rather than claimed as a pass.

Clause-②: no


Generated by Claude Code

…es under node_modules

check:keyed-text-bounds walked packages/cli/tmp/, a git-ignored directory,
so a scaffold test killed before its afterAll cleanup ran left behind an
os-init-shaped .object.ts the gate cannot parse, redding the gate for a
reason unrelated to the author's diff.

- Add 'tmp' to SKIP_DIRS, the walk's existing filter point, alongside the
  other build/tooling-litter directories it already skips. The walk stays
  repo-wide minus SKIP_DIRS; only the skip list grew by one entry.
- Move init-scaffold-authoring-rules.test.ts's scaffold temp root from this
  package's tmp/ to under its own node_modules/, matching the placement
  generate-scaffold-validates.test.ts already documents for the same
  @objectstack/spec resolution reason. node_modules is already skipped by
  the gate regardless of the SKIP_DIRS change above.

The gate's refusal for an unrecognised declaration shape on a keyed column
is unchanged -- this only narrows which files are walked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 10, 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 cefe06870260ba7a5a85251189d6e663e991d9b9 → packageMentionDocs.

@github-actions github-actions Bot added the tests label Sep 10, 2026
@baozhoutao
baozhoutao marked this pull request as ready for review September 10, 2026 13:29
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 10, 2026
Merged via the queue into main with commit 6fff5e5 Sep 10, 2026
39 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-16195-keyed-text-bounds-ignored-trees branch September 10, 2026 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

2 participants