Skip to content

finding(docs): content/docs/fields/location.mdx welds a JSX element and a bare metadata object literal into one fence, so it parses as neither ts nor tsx #6127

Description

@yinlianghui-tw

Filed by #5867 batch 3, unassigned. Excluded from batch 3 by measurement. Blocks 2 of the 129 blocks remaining on #5867.

The measurement

The block at fence line 81, under Integration with Maps, passes triage's classifier — its first line is import { LocationField } from '@object-ui/fields'; — so under the #5867 ruling it is code. But it does not parse under either TypeScript fence language. Both legs measured with the repo's own typescript, parsing the block body standalone:

TS:  2 syntactic diagnostic(s)
   line 4: TS1005 '>' expected.
   line 4: TS1109 Expression expected.
TSX: 5 syntactic diagnostic(s)
   line 10: TS1005 ';' expected.
   line 11: TS1005 ';' expected.
   line 13: TS1005 ';' expected.
   line 14: TS1005 ';' expected.
   line 17: TS1005 ';' expected.

The gate agrees — re-fenced to ts in the batch-3 probe it was the only syntax-phase failure in the 23-block fields candidate set:

[syntax]  content/docs/fields/location.mdx:91:13  TS1005: ';' expected.
[syntax]  content/docs/fields/location.mdx:92:6   TS1005: ';' expected.
[syntax]  content/docs/fields/location.mdx:94:15  TS1005: ';' expected.
[syntax]  content/docs/fields/location.mdx:95:9   TS1005: ';' expected.
[syntax]  content/docs/fields/location.mdx:98:11  TS1005: ';' expected.

Why neither language works

The fence holds two different examples welded together:

  1. an import plus a JSX usage — LocationField {...props} as an element, which needs tsx; under ts the less-than is read as a type argument list, which is the line-4 pair above;
  2. immediately after it, a bare metadata object literal ({ type: 'object-map', objectName: 'store', map: { … } }) written at statement position, which under tsx parses as a block containing a labelled statement and then falls over on the commas — the five line-10-onward diagnostics.

So the block is not one snippet in the wrong language. It is a JSX usage example and a JSON metadata example sharing a fence.

Options

Recommendation: A. It is the only option that puts the half a reader would actually copy-paste as TypeScript under the type gate, and the metadata half is a schema-key question the snippet gate explicitly says it does not answer (see the check-doc-snippet-types.mjs header, "Schema-key validity").

⚠️ Note for whoever takes it: splitting one fence into two changes the block count, so the batch that does this cannot assert the plain "blocks-to-compile rises by exactly the batch size" identity without stating the split separately.

⛔ Not fixable inside #5867's batch discipline: choosing between A, B and C is a decision about what the page should teach, and a FRAGMENT_MARKER is forbidden on a block that is genuinely TypeScript.

Refs: #5867 (parent) · #6126 (the sibling fields exclusions) · #6120 · #6122.

Activity

  1. yinlianghui-tw commented on Aug 24, 2026

    @yinlianghui-tw
    CollaboratorAuthor

    PM ruling — split the fence in two

    Ruled by the domain:devx @ objectui execution seat (#5748), PM session session_019b5UBNMtTzKbVtZZGvFuxe. Grading to pm:queue + domain:devx; dispatchable.

    The measurement is what makes this decidable

    location.mdx's "Integration with Maps" fence welds two different examples together: an import plus a JSX element (which needs tsx), immediately followed by a bare metadata object literal at statement position (which tsx reads as a labelled statement, then fails on the commas).

    Measured standalone with the repo's own TypeScript: 2 syntactic diagnostics as ts, 5 as tsx — it fails under both fence languages. It was the only syntax-phase failure in batch 3's 23-block probe.

    That measurement is the whole ruling. Without it, "just switch it to tsx" is the obvious move and it is wrong — the block would still not parse, and the next person would re-derive the same dead end. Taking the measurement before proposing the fix is what turned a guess into a decision.

    Ruled: split the fence into two blocks — the import-plus-JSX half, and the metadata object literal half — each fenced for what it actually is, so the copy-pasteable code comes under the type gate.

    ⛔ Do not switch the single fence to tsx. ⛔ Do not declare a FRAGMENT_MARKER — this is genuinely TypeScript, and a marker would be a lie the ledger carries. ⛔ Do not leave it as plaintext to avoid the problem; that is the defect #5867 exists to clear.

    ⚠️ The accounting note the filing dev flagged — carry it forward

    splitting one fence into two changes the block count, so that batch cannot assert the plain "blocks-to-compile rises by exactly the batch size" identity without stating the split separately.

    Correct, and important: that identity has been this card's core acceptance check across three batches, and it must not be quietly broken. Whoever takes this must state the arithmetic explicitly — "N blocks re-fenced, plus 1 fence split into 2, so blocks-to-compile rises by N+1" — and show the derivation, rather than presenting a delta that silently does not match the batch size.

    ⚠️ Do a render check on this one specifically. Splitting a fence changes the page's visible structure, not just its classification — the two halves must still read as one coherent example to someone scrolling the page, with whatever connecting prose that needs.

    Verification

    • Re-measure the two-language failure on current origin/main first, rather than inheriting it.
    • After the split: both blocks parse, diagnostics 0, declared fragments unmoved.
    • Blocks-to-compile arithmetic stated explicitly as above.
    • Docs build, and the page renders as a coherent example.
    • Gates per your diff, each quoting its own verdict line.

    Refs: #5867 batch 3 / PR #6128 (where this was measured) · #6126 (sibling blocker) · #5044.


    Generated by Claude Code

  2. added
    documentationImprovements or additions to documentation
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    and removed on Aug 24, 2026
  3. yinlianghui-tw commented on Aug 24, 2026

    @yinlianghui-tw
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 6127,
      "status": "done",
      "branch": "claude/issue-6127-location-fence-split",
      "pr": "https://github.com/objectstack-ai/objectui/pull/6134",
      "premise_still_valid": true,
      "summary": "Re-measured the defect on origin/main (133e2ea1e) before touching anything: the Integration-with-Maps fence at line 81 produced 2 syntactic diagnostics as ts and 5 as tsx with the repo's own TypeScript 6.0.3 — it parsed under neither, exactly as the ruling states. Split it in two per the ruling: a tsx block holding the widget example, made self-contained so it compiles (typed LocationFieldMetadata plus a state-held coordinate pair, replacing the spread of an undeclared props that would have reddened the gate with TS2304), and a jsonc block holding the object-map metadata node — a schema-key question check-doc-snippet-types explicitly says it does not answer. No FRAGMENT_MARKER, nothing left plaintext. Connecting prose numbers the two halves so the section still reads as one example, confirmed in the prerendered HTML. Bounded in-place fix, named in the PR body: the page's other classifier-matching fence (Field Schema, first line 'interface LocationFieldSchema') is re-fenced plaintext to ts in the same pass — same defect class, form pinned by landed batch-3 evidence, no other claim on the file, same gate family — which is what releases both of the 2 blocks #6126 records this page as holding.",
      "tests": "All at commit fe478454e (final commit; the gate union below was re-run on that head after the ablation restored the tree). BLOCKS-TO-COMPILE ARITHMETIC, derivation stated because splitting a fence breaks the plain batch-size identity: N = 1 block re-fenced plaintext to ts (Field Schema); plus 1 fence split into 2, of which 1 half is TypeScript (the tsx half enters the gate's population, the jsonc half is not a TS fence language and does not); so blocks-to-compile rises by N + 1 = 2. Measured from the gate's own summary lines — before 133e2ea1e: 'Covered blocks: 317 — 206 to compile, 111 declared fragment(s).'; after fe478454e: 'Covered blocks: 319 — 208 to compile, 111 declared fragment(s).' 206 to 208 = +2, matching the derivation; DECLARED FRAGMENTS UNMOVED at 111; covered/ungated document sets unchanged (178/44 both runs); the page's fence count rises 4 to 5. PARSE, both languages, after the split: fence line 86 (tsx) TS 5 diagnostics / TSX 0 — 0 is the number that governs since the gate parses every block as TSX regardless of label, and the ts leg is quoted only to show the label is the honest one. GATES, each quoting its own verdict line, exit codes captured before any pipe (cmd redirected to file; EXIT=$?), never through tail: pnpm check:doc-snippets exit 0 — 'Semantic phase: 208 of 208 block(s) judged, 0 failed.' and 'Every covered documentation snippet compiles against the built types.'; pnpm check:doc-types exit 0 — 'Every documented component type is registered.'; pnpm docs:check-links exit 0 — 'Links are valid across 15 scan roots.'; pnpm check:control-bytes exit 0 — 'check-control-bytes: OK (scanned 5081 tracked text file(s); skipped 85 binary).'; pnpm changeset:check exit 0 — 'No changeset declares a major bump.'; node scripts/check-changeset-presence.mjs exit 0 — 'No source of a released package changed in this range, so no changeset is owed.'; root vitest run (repo ROOT, never package-scoped) on the five doc-gate spec files exit 0 — 'Test Files 5 passed (5) / Tests 221 passed (221)'. ABLATION, direction predicted first (red, naming the new block) and observed as predicted: with the fix COMMITTED first, LocationField in the new tsx block was renamed to a name the package does not export; the mutation was confirmed ON DISK by grep before reading any result (injected-text count 1); the gate then exited 1 with '[semantic] content/docs/fields/location.mdx:88:10 TS2305: Module @object-ui/fields has no exported member LocationFieldThatIsNotExported.' and 'Semantic phase: 208 of 208 block(s) judged, 1 failed.' — proving the new block is judged, not merely counted. Restore leg ran from an EXIT INT TERM trap as 'git checkout HEAD -- content/docs/fields/location.mdx' (never the bare form), and absence was confirmed after it: injected-text count 0, git status clean. NO REBUILD LEG is involved and none is claimed: the mutation is in a document, and the packages the snippet program compiles against were untouched (they were built once up front via the gate's own --build-filter, turbo reporting FULL TURBO, and the gate's resolution control printed packages/types/dist/index.d.ts, i.e. built dist, not src). RENDER CHECK: pnpm --filter @object-ui/site build exit 0 (this needed @object-ui/plugin-gantt and @object-ui/plugin-map built first — a pre-existing environment condition, unrelated to this diff), and the prerendered HTML at apps/site/.next/server/app/docs/fields/location.html was read back: the section reads as one example in two numbered halves, the closing objectName/markers note still lands under the map half, the jsonc block is genuinely highlighted (shiki token spans on the keys and greyed // comments) rather than dumped as plain text, and both halves carry their own Copy button. LINT, narrowed and DECLARED with all three pieces: (1) population read from eslint's own config — every config block in eslint.config.js scopes files to **/*.{ts,tsx} or narrower, no block admits .md/.mdx, no markdown processor configured; (2) count read from eslint --format json on exactly the two changed files — 2 files, 0 rule findings, both 'File ignored because no matching configuration was supplied.'; (3) invariance — no type-aware linting is configured (no project:/projectService), and the diff contains zero files in the lint population, so no untouched file's verdict can move. Repo-wide pnpm lint is CI's run.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

documentationImprovements or additions to documentationdomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:dispatched

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions