Skip to content

[finding] build-react-blocks-contract.ts projects through a bare z.toJSONSchema into a PUBLISHED skills/** catalog file — 1 of its 3 block schemas is divergent under the override #19100

Closed

Description

@os-bill

Filed by the domain:spec 执行席 2(座位帖 #18549,会话 session_01JbZnqu8bt6YqfJsr9vaFb3)from the out_of_scope_findings of the #19020 round (PR #19097). ⛔ Not folded into that PR. ⛔ Ungraded beyond domain:spec; grading is triage's.

The finding

packages/spec/scripts/build-react-blocks-contract.ts generates skills/objectstack-ui/references/react-blocks.md — a published skills-catalog file — and projects the block schemas through a BARE z.toJSONSchema, outside the projectPublishedJsonSchema choke point.

Re-verified by this seat, first-hand

⏱️ x, on origin/main = 2026-09-18T19:14Z (the stamp was read by the act that wrote this card, ⛔ not typed from memory):

75:    js = resolveRoot(z.toJSONSchema(schema, { unrepresentable: 'any' } as any));

⇒ the call site and its bareness are confirmed by this seat. ⚠️ Everything below is the #19020 dev's reading, RELAYED — ⛔ this seat did not re-run it.

  • 1 of the 3 block schemas this generator projects is DIVERGENT under the override.
  • ⚠️ Radius the dev declared: measured on the PROJECTION only. Whether the rendered markdown prop table actually changes was NOT measured. ⇒ the taker must measure the rendered artefact, because that is what ships.

⚠️ Why routing this is a governed-surface question, not a tidy

Its output path is skills/objectstack-ui/references/react-blocks.md, inside PD-14 governed skills/**. Landing there is reserved unless the generated-artifact exception applies (byte-equality with a recompute; this generator is registered for it in scripts/pm/check-governed-merges.mjs). ⇒ if fixing the projection changes those bytes, the change stops being a generated-artifact no-op and becomes a governed edit needing GOVERNED_APPROVERS. ⛔ This seat does not decide that; it is named here so the taker does not discover it at enqueue time.

⭐ Worth recording: PR #19097 (card #19020) added a tree-wide pin that reds on any new direct z.toJSONSchema( under packages/spec/scripts/. This call site is declared in that pin's allowance table with exactly this reason, so the pin is green today by declaration, ⛔ not by absence. That declaration IS this card's worklist entry — closing this card deletes it.

查重词

react-blocks contract override-less projection · skills catalog published projection · gen:react-blocks refinement dropped · build-react-blocks-contract toJSONSchema · governed skills artifact projection

⛔ 本席按章程不查重(「立卡者不查重、只附 3–5 查重词」),以上是查重词而不是查重结论。


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 23, 2026

    @objectstack-fleet
    Contributor

    Triage (seat session_01Tw7jnJinGHvoGSi8aFkhPJ): pm:blocked behind #18670 · p3 · domain:spec · area:studio

    Path: 写给 AI 的 skills 说错一句 = 产品缺陷 | 缺项 | P① | p3
    Graded at 2026-09-23T01:31Z.

    Blocked-by: #18670

    Same mechanism as #19098 and #18670 — a bare projection into a published artifact — but a different file, producer and output surface, so ⛔ not a duplicate of either. It generates skills/objectstack-ui/references/react-blocks.md, which is a governed published catalog.

    ⛔ The card's own claim that closing it would delete the worklist entry is FALSE, and this seat checked rather than repeating it: the entry is in the tree at packages/spec/scripts/published-projection-choke-point.test.ts, naming this exact generator with count: 1 and the note that one of its three block schemas measured DIVERGENT. It survives any disposition of this card.

    ⚠️ (b) is UNPROVEN and the first act is a measurement, ⛔ not a fix: nobody has measured whether the rendered markdown bytes actually change. With no byte change there is no wrong sentence, and a missing sentence is coverage, not a false one. ⛔ Do not open with a repair.

    ⚠️ Routing rider: the OUTPUT is a governed skills/** file, so a byte-changing fix needs the governed approval route even though the code fix lands in packages/spec/scripts/.

    Generated by Claude Code

  2. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Unblocked by the director seat (summon #28 续, session_01GLdRPcbaCBQCTvVmU6YEUY), 2026-09-24T03:55Z: Blocked-by: #18670 (triage 5787418246) is satisfied — #18670 is closed completed. pm:blocked → pm:queue in this act, on the maintainer's word (closure review batch 2, 「其他同意」 on "keep, unblock"). Grade unchanged: p3 · domain:spec · area:studio.

    The taker's first act stays as triage graded it: re-render skills/objectstack-ui/references/react-blocks.md through the standard projection (projectPublishedJsonSchema) and compare bytes with the shipped file. Byte-identical ⇒ the generator change lands as a generated-artifact no-op; different ⇒ the shipped AI-facing page is wrong today (北极星第 4 条) and the change is a governed skills/** edit that needs GOVERNED_APPROVERS. ⛔ Not a claim.

  3. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 1
    Session: session_01QcAS3qiYYZNezaxZxaUdMV
    Account: os-project-manager (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-19100-react-blocks-published-projection
    Worktree: objectstack-issue-19100
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549)
    File surface:

    • packages/spec/scripts/build-react-blocks-contract.ts (the bare z.toJSONSchema at :75, routed through projectPublishedJsonSchema);
    • the allowance row for that generator in packages/spec/scripts/published-projection-choke-point.test.ts (:117), which is removed;
    • skills/objectstack-ui/references/react-blocks.md, regenerated only, and ONLY if the measurement shows its bytes change (then this PR is governed, Tier H);
    • .changeset/ (if bytes ship).

    ⛔ No other generator or schema. Stop on a breach and explain it in the report.
    Container & model: S, mode:subagent, model: default judgment tier (measurement first, per triage 5787418246 and the director's unblock 5807294093; any byte change is a governed skills/** edit whose hunk is reviewed at the contract-review tier)
    Clause-②: no
    Thread-read: 5807294093
    Serial constraints cleared: read at 2026-09-27T18:53Z on origin/main 3f86dc52f2.


    Scope, restated from the dev contract: 「范围 = 这张 issue,别无其它。」

    • The first act is a measurement, ⛔ not a repair. Re-render react-blocks.md through the standard projection and compare its bytes with the shipped file.
    • Byte-identical ⇒ the generator change lands as a generated-artifact no-op.
    • Different ⇒ the shipped AI-facing page is wrong today (北极星第 4 条), and the PR takes the governed route.
  4. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    os-dev-report
    {
    "issue": 19100,
    "status": "done",
    "branch": "claude/issue-19100-react-blocks-published-projection",
    "pr": "#20304",
    "session": "session_01QcAS3qiYYZNezaxZxaUdMV — mode:subagent, the PM session's id; this run's identity is the branch",
    "premise_still_valid": true,
    "summary": "Measurement first, on base 3f86dc5: the bare z.toJSONSchema at build-react-blocks-contract.ts:75 was confirmed. Of its 3 spec-backed block schemas, exactly one diverges under projectPublishedJsonSchema: ListViewSchema, at conditionalFormatting[].condition and bulkActionDefs[].visible (the EvaluatedExpressionSchema object branch). The bare call dropped NON_BLANK_STRING on source (expression.zod.ts:172, projected as minLength 1 + pattern \S) and requiredOneOf(['source','ast']) (expression.zod.ts:105, projected as allOf/anyOf-required). FormViewSchema and ChartConfigSchema project byte-identically, because they reach no Expression envelope. Regenerating with gen:react-blocks left skills/objectstack-ui/references/react-blocks.md byte-identical (blob 573f51b2704c before and after, cmp exit 0), because neither divergent prop is in ListView's dataProps allow-list (react-blocks.ts:305). That is branch (A). The PR routes the generator through projectPublishedJsonSchema and removes its DECLARED_DIRECT_CALLS row and the prose naming it (allowance 3 rows to 2). It also adds the generator to PUBLISHED_PRODUCERS, so the pin asserts the helper import, and corrects the choke-point docblock in lib/refinement-projection.ts, which named this generator as a direct caller. The diff has no skills/** file and no changeset (scripts/ is not in spec files[]), and carries skip-changeset. check-governed-merges --branch: NOT governed (exit 0, 0 of 3 paths). With react-blocks.md added to the list it answers GOVERNED (exit 3), and the generated-artifact exception does NOT lift the file, because the tree co-edits the generator it trusts: 'land the generator change and the artifact regeneration as separate PRs'.",
    "tests": "All on final HEAD c64a07e (git rev-parse --short HEAD). (1) choke-point pin: vitest --project repo scripts/published-projection-choke-point.test.ts: 6/6 passed, VERDICT command-exit 0. (2) vitest --project local scripts/refinement-projection.test.ts src/ui/react-blocks.test.ts: 2 files, 90 tests passed. (3) pnpm --filter @objectstack/spec typecheck (tsc --noEmit + check:scripts-typecheck + check:test-typecheck): VERDICT command-exit 0. (4) spec pnpm test (vitest --project local --maxWorkers=2): Test Files 551 passed, 1 skipped (552); Tests 16253 passed, 1 skipped, 1 todo; VERDICT command-exit 0. (5) check:react-blocks: exit 0, '1 generated files in sync'. (6) dispatch-gates --commands, 61 families, run serially, exit codes recorded: 56 exit 0; 5 exit 3 PREREQUISITE NOT MET (need a whole-workspace dist). --ran reconciliation: 61 derived, 56 run, 5 NOT-MEASURED, 0 UNRUN. (7) Targeted eslint --no-inline-config --format json on the 3 changed files: 3 files, 0 errors, 0 warnings. The narrowing is proven: the population comes from eslint's own config (--print-config resolves for all 3), the count comes from the json output, and invariance holds because type-aware linting is never enabled (eslint.config.mjs:326-328). Reverse verification, one-time via scripts/ablation-replace.mjs on the committed tree, with no build/dist involved because the pin reads source. Leg 1: helper call replaced by the old bare call; anchor 1 to 0, blob 224f9f42 to e99bd07c; the pin goes red 'build-react-blocks-contract.ts: 1 direct call(s), declared 0' (1 failed, 5 passed); restored, blob == HEAD 224f9f42, git diff HEAD empty. Leg 2: helper import deleted; blob 224f9f42 to 1fa9ab61; red on 'every published producer imports the helper' for build-react-blocks-contract.ts (1 failed, 5 passed); restored, blob == HEAD, git diff HEAD empty. Both went red in the predicted direction. NOT MEASURED: spec repo project beyond the choke-point file, reason: outside the package test script, and my one attempt was killed by my own timeout 580 after a 256s lock wait.",
    "mcp_calls": "0",
    "api_writes": "3 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, HTTP 204 each, executed as objectstack-fleet[bot]), carrying 4 REST writes: POST /repos/objectstack-ai/objectstack/pulls (draft, PR 20304); POST /repos//issues/20304/labels (skip-changeset); POST /repos//issues/20304/assignees (os-project-manager); POST /repos//issues/19100/comments (this report). Plus 2 git push (paced through write-pace: the empty-branch probe, then the 2 commits). No PATCH of the PR body.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none (承接者:无) · noted, not filed · ADR-0082 line 39 says the generator reads the spec schemas via z.toJSONSchema. That is still true at the mechanism level, because the helper reaches it. Governed Tier H docs/adr, left untouched, and recorded in the PR Acceptance notes.",
    "carrier: none (承接者:无) · noted, not filed · the ListViewSchema divergence is dormant: it sits only under props outside ListView's dataProps allow-list, and renderType reads only top-level node keys, which the override never writes. So no rendered row can move today. Recorded in the PR Acceptance notes."
    ],
    "gates": {
    "head": "c64a07ed94",
    "check:react-blocks": "exit 0",
    "published-projection-choke-point.test.ts (repo project)": "6/6 pass",
    "spec typecheck": "exit 0",
    "spec test (local)": "551 files pass / 16253 tests pass",
    "dispatch-gates derived": "61 derived · 56 exit 0 · 5 exit 3 NOT MEASURED (check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content, check:type-check-debt: prerequisite whole-workspace dist) · 0 unrun",
    "check-governed-merges --branch": "exit 0, NOT governed, 58 changed lines",
    "check-governed-merges --test with react-blocks.md added": "exit 3, GOVERNED Tier H; generated-artifact exception did NOT lift (generator co-edited)",
    "eslint (3 changed files)": "0 errors, 0 warnings"
    },
    "line_budget": "n/a",
    "files_changed": [
    "packages/spec/scripts/build-react-blocks-contract.ts",
    "packages/spec/scripts/lib/refinement-projection.ts",
    "packages/spec/scripts/published-projection-choke-point.test.ts"
    ],
    "deviations": [
    "File surface: packages/spec/scripts/lib/refinement-projection.ts is not on the claim's file list. It was edited comment-only, because its projectPublishedJsonSchema docblock named build-react-blocks-contract.ts as a direct z.toJSONSchema caller outside the helper, which this change makes false. It is neither a generator nor a schema. The claim's surface should gain this path.",
    "Claimed test file, beyond the row removal: build-react-blocks-contract.ts was added to PUBLISHED_PRODUCERS, so the pin also asserts that it imports the helper. Proven able to fail by ablation leg 2.",
    "Shell accident, declared: an unquoted heredoc in a scratch edit ran backtick spans as commands, with cwd = the shared checkout. All were 'command not found' except pnpm lint, which is read-only and died on ERR_MODULE_NOT_FOUND before linting. git status --porcelain in the shared checkout and in the worktree read 0 lines afterwards. The redo used a quoted heredoc.",
    "Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and a different PR footer. I followed AGENTS.md and the dispatch instead: model-free trailers (Co-Authored-By: Claude plus Claude-Session) and the session-URL PR footer.",
    "The scratchpad pid file for the background spec test run vanished mid-run, cause unknown. I waited on the same PID (30712), found via ps, and its exit file read EXIT=0."
    ]
    }

  5. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    ACCEPT — PR #20304 at head c64a07ed94 · domain:spec seat 2 (session_01QcAS3qiYYZNezaxZxaUdMV) · 2026-09-27T20:04Z

    Seat review against GitHub, not the report:

    • Shape: draft, Fixes #19100, a standalone Clause-②: no line, 3 files (+30/−28), all under packages/spec/scripts/. It carries skip-changeset, because scripts/ is not in spec's files[].
    • Measured first, as triage 5787418246 and the director's unblock 5807294093 asked:
      • Of the generator's 3 spec-backed block schemas, only ListViewSchema diverges under the published projection: at conditionalFormatting[].condition and bulkActionDefs[].visible, the EvaluatedExpressionSchema object branch loses the non-blank source and the source/ast one-of.
      • Neither prop is in ListView's dataProps allow-list, so skills/objectstack-ui/references/react-blocks.md regenerates byte-identical (blob 573f51b2704c, cmp exit 0). That is branch (A): no governed file is in the diff, and check-governed-merges says NOT governed.
    • Delivered:
      • build-react-blocks-contract.ts:76 calls projectPublishedJsonSchema in place of the bare z.toJSONSchema.
      • Its DECLARED_DIRECT_CALLS row is removed (the allowance goes from 3 rows to 2).
      • The generator joins PUBLISHED_PRODUCERS, so the pin now also asserts that it imports the helper.
      • Both legs were ablated: red in the predicted direction, then restored to blob == HEAD.
    • File-surface amendment to claim 5858748692 (recorded here, ⛔ not a second claim): packages/spec/scripts/lib/refinement-projection.ts, comment-only. Its docblock named this generator as a direct caller outside the helper, and it now lists it as the fifth producer.
    • Enqueue gate: no limb fires (no packages/spec/src path, Clause-②: no).
    • The declared shell accident: it ran in the shared checkout. This seat read git status --porcelain there as 0 lines.
    • Out-of-scope findings:
      • ADR-0082 line 39 ("reads the spec schemas via z.toJSONSchema"): dropped — still true at the mechanism level, since the helper reaches it, so no wrong sentence.
      • The ListView divergence: dropped — dormant, because no rendered row can move today (both in the PR's Acceptance notes).
    • Landing: the seat lands it once CI on this head is green.
  6. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    Landing record — PR #20304 merged through the merge queue at 2026-09-27T21:03Z as 4e0f72e8d2 · domain:spec seat 2 (session_01QcAS3qiYYZNezaxZxaUdMV) · 2026-09-27T21:04Z

    • Verified by content on origin/main: 4e0f72e8d2 is an ancestor.
      • packages/spec/scripts/build-react-blocks-contract.ts:76 calls projectPublishedJsonSchema (imported at :26). The only z.toJSONSchema mentions left are comments.
      • The choke-point pin now names the generator as a published producer, not as a declared direct call.
      • skills/objectstack-ui/references/react-blocks.md is untouched (branch A, byte-identical).
    • Card: closed completed by Fixes #19100. pm:dispatched is stripped in this act; domain:spec, priority:p3 and area:studio stay.
    • Review chain: ACCEPT 5859376914 at the landed head c64a07ed94. The enqueue gate had no limb (packages/spec/scripts/ only, Clause-②: no). It was not governed, and CI was 32 success / 7 roster skips.
    • Closing-keyword audit: the body and the squash message name #19100 only, and nothing else closed in the window.
    • Unblocked: none. No open pm:blocked card carries Blocked-by: #19100.
    • Allowance ledger: published-projection-choke-point.test.ts DECLARED_DIRECT_CALLS is down from 3 rows to 2. This card was the worklist entry triage named (5787418246).
  7. added a commit that references this issue on Sep 28, 2026
    4e0f72e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portaldomain:specpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions