Skip to content

spec(ui): export navItemVisibleDataNeedsDataSource, so mirrors of NavigationItemSchema can attach it by identifier — objectui's NavigationItemSchema accepts a nav entry whose visible reads data with no dataSource, which the spec refuses #24534

Closed

Description

@objectstack-fleet

Filing gate: a class-b finding with a public door. Measured by objectstack-ai/objectui#12971's dev (PR objectstack-ai/objectui#13043, head 8f9f2994). Filed by objectui domain:ui seat 1 (session_0188TsgPV8kQXfuRuKmkj2ks). ⛔ Not a claim; lane and grade are triage's.

Measured

  • 8016a9d9dd attaches navItemVisibleDataNeedsDataSource with .superRefine on the spec's navigation-item union, but does not export it.
  • The spec's NavigationItemSchema refuses { id: 'nav_envs', type: 'object', objectName: 'sys_environment', visible: 'data.total == 1' }, which has no dataSource, with custom at visible.
  • objectui's NavigationItemSchema, and its StrictAnyComponentSchema (an app document carrying that entry, the face objectui validate uses), accept it. Control: the same entry WITH a dataSource is accepted by all three.
  • objectui's rule (objectui#7715) is to attach a spec refinement by its exported identifier, never to restate it. With no export, objectui cannot close this door.

Done when

  1. @objectstack/spec/ui exports navItemVisibleDataNeedsDataSource, the same way it exports checkPageRegionPlacement and checkPageMainRegionWidth.
  2. A follow-up on objectui attaches it to its flat NavigationItemSchema at the next pin bump (filed there when this lands).

Dedupe words: navItemVisibleDataNeedsDataSource export, nav visible data dataSource refused, NavigationItemSchema object-level check.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: p1 + target:v18 (protocol-first, widening) · domain:spec · area:api · pm:queue · put to the maintainer for pulling forward · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-19T12:53Z

    Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.

    • Fresh read on origin/main 5b14b7f3ad.

      • packages/spec/src/ui/app.zod.ts:1041 declares function navItemVisibleDataNeedsDataSource, with no export, and :1107 attaches it by .superRefine.
      • Its siblings are exported: checkPageRegionPlacement and checkPageMainRegionWidth (page.zod.ts:1766, :1846).

      The premise holds.

    • Grade. A new export from @objectstack/spec, so protocol-first applies: p1 + target:v18. It completes spec(ui): a navigation entry with no dataSource whose visible reads data.* is refused at parse (BREAKING, ADR-0087), question 2 of #24332's ruling #24450's narrowing on the consumer face, so objectui validate refuses what the server refuses.

    • Put to the maintainer for pulling forward (6261447528):

      • kind: widening (an added export, no shape change);
      • consequence of not pulling it: it can ship in any 18.x minor. Until then, objectui's validator admits a nav entry the server refuses, because the parse still refuses it at the door;
      • workload: S, one export plus a test that the exported function is the attached one. No PR yet;
      • lean: in 18.0, while objectui#12971's pin is moving now.

      Until the maintainer answers, nothing on this card moves on that question.

    • finding comes off with this grade.


    Generated by Claude Code

  2. added
    area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobs
    priority:p1High: required for production / M2
    and removed on Oct 19, 2026
  3. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Maintainer decision: pull into 18.0 · labels unchanged (p1 + target:v18) · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-19T15:46Z

    Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.

    • Provenance. This seat put the pull-forward question to the maintainer in chat under the standing rule 6261447528 (widening, S, lean: in 18.0 while objectui#12971's pin is moving). The maintainer answered 「24534 同意提前」.
    • What it binds:
      • the export lands before the 18.0 cut if a domain:spec seat claims it in time;
      • it never holds the release (gate 6261853191: 8b, then F1);
      • the objectui follow-up attaches the exported refinement to objectui's flat NavigationItemSchema at the next pin bump, as the card's Done-when 2 says.
    • Labels: none change. The card already carries p1 + target:v18 and pm:queue, so a domain:spec seat may claim it now.

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-19T15:59Z · @objectstack/spec/ui exports navItemVisibleDataNeedsDataSource, the refinement NavigationItemSchema already attaches, so a mirror attaches it by identifier
    Pulled forward on the maintainer's word in this session's chat at 2026-10-19T15:59Z, verbatim: 「一、两张协议卡要不要赶进 18.0 同意」. It answers the triage seat's pull-forward question (6261447528, card 6267689111) as 18.0. The seat's batch 2 (「并发2」) holds it beside #24563.
    Session: session_019oFY6Hi35J7atvgVFnmoaK (the seat; the dev is an os-dev subagent of this session)
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-24534-export-nav-visible-data-check
    Worktree: objectstack-issue-24534
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549)
    File surface (paths on origin/main 5a871e4e41 or later; stop on a breach and explain it in the report):

    • packages/spec/src/ui/app.zod.ts: navItemVisibleDataNeedsDataSource (about :1041) gains export and the TSDoc its exported siblings carry (checkPageRegionPlacement, page.zod.ts:1766). The .superRefine at :1107 stays the same function;
    • one test that pins the exported function as the attached one, and the export's identity on @objectstack/spec/ui;
    • the generated ui shards (api-surface/ui.json, export-origins/ui.json and any other the generator names), by their own tools only; one .changeset/24534-*.md (minor on @objectstack/spec).
    • ⛔ No change to what the refinement accepts or refuses. Not content/docs/releases/.
      Container & model: S, mode:subagent, model: default tier for the draft (dispatch-gates --tier: no path-derived mandate). The review before the queue runs at CONTRACT_REVIEW_TIER (the schema face: a public export is added).
      Clause-②: yes (widening)
      Responsibility: n/a — not a defect card (an unexported refinement, which keeps mirrors from attaching it by identifier, objectui#7715's rule)
      Thread-read: 6267689111
      Serial constraints cleared:
    • The file lists of all open PRs were read in this act. None touches packages/spec/src/ui/app.zod.ts or the ui generated shards.
    • A list view bound to an object outside the writing package's dependency closure skips the field-reference check: unknown columns fields are accepted (200 active, draft → publish) where the same body is refused 422 list-view-field-unknown #24563 (this seat, dispatched beside it) is in packages/lint/** and a metadata-protocol test file, which are disjoint.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatched · domain:spec seat 2 · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-19T16:21Z · for claim 6271491852.

    mode:subagent: the dev is an os-dev subagent of this session, on branch claude/issue-24534-export-nav-visible-data-check, at the default tier. batch 2: it runs beside #24563.

    The ruling is the card's "Done when" item 1: export the refinement from @objectstack/spec/ui as its siblings are exported, with no change to what it accepts or refuses. objectui's attach is that repository's follow-up, filed when this lands.

    It reports here as an os-dev-report comment and opens a draft PR. The seat subscribes to that PR the moment it exists.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
    "issue": 24534,
    "status": "done",
    "branch": "claude/issue-24534-export-nav-visible-data-check",
    "pr": "#24628",
    "session": "session_019oFY6Hi35J7atvgVFnmoaK — the seat's session (this dev is an os-dev subagent of it)",
    "premise_still_valid": true,
    "summary": "@objectstack/spec/ui now exports navItemVisibleDataNeedsDataSource, the refinement NavigationItemSchema already attaches, the same way as objectNavTargetExclusivity / checkPageRegionPlacement / checkPageMainRegionWidth. The diff adds export, the sibling docblock paragraph, a 5-leg export pin, the two regenerated ui shards and a minor changeset. Nothing an author writes is accepted or refused differently, and the issue code, path and message are unchanged. P1 holds (app.zod.ts:1041 had no export; :1107 attaches it; siblings page.zod.ts:1766 / :1846 reach @objectstack/spec/ui via src/ui/index.ts export *, package.json exports[\"./ui\"], and the api-surface / export-origins ui shards). P2 holds for the signature only. The function judges the spec's PARSED entry (visible as the { dialect, source } envelope). Measured: on the card's entry as written (bare-string visible) the export raises nothing, and on the same entry with visible parsed it raises the door's identical issue. objectui's mirror declares visible: z.union([z.boolean(), z.string()]), so chaining the export there as it is would refuse nothing on the card's entry. Per the dispatch's prohibition this PR writes only the honest export. The docblock, the changeset and pin leg 5 state the input contract, and the difference is open_questions[0]. files_changed: packages/spec/src/ui/app.zod.ts; packages/spec/src/ui/app-nav-visible-data-needs-data-source-export.test.ts (new); packages/spec/api-surface/ui.json; packages/spec/export-origins/ui.json; .changeset/24534-export-nav-visible-data-check.md. deviations: (1) the first ablation attempt was a no-op: its replacement was a substring of its anchor and ablation-replace.mjs refused before running anything. It was re-run with a distinct marker, and that reading is the one cited. (2) On the pre-merge head 3 derived gates exited 3 (PREREQUISITE NOT MET). After builds, all 89 exited 0 on the final head. (3) origin/main c3954057fe was merged before opening the PR, through os-regen-merge.sh. Its merge commit is the script's own message and carries no Claude-Session trailer pair. Since then origin/main has moved to 65a8eeb7d4 (5 commits, no file overlap with this diff), and it was not merged again. (4) If the seat wants open_questions[0] answered on this card rather than a new one, line 1 of the PR body should become Part of #24534. Dev bodies are write-once, so that edit is the seat's.",
    "tests": "Final head 50c3ba8. Every run went through os-verify-lock.sh, and each VERDICT line read command-exit 0. pnpm --filter @objectstack/spec test: "Test Files 702 passed (702) / Tests 21339 passed | 1 todo (21340)". pnpm --filter @objectstack/spec typecheck: tsc --noEmit + check:scripts-typecheck + "check:test-typecheck: OK — 52 file(s) / 242 error(s) / 132 pinned signature(s) held" (unchanged; the new test adds none). New pin alone (vitest run --maxWorkers=2 src/ui/app-nav-visible-data-needs-data-source-export.test.ts): "Tests 27 passed (27)". Pre-merge, with siblings app-nav-visible-data-needs-data-source / app-nav-target-exclusivity-export / object-refinement-check-exports: "Tests 352 passed (352)". Ablation at 42945c2, with the implementation committed: node scripts/ablation-replace.mjs replaced export function navItemVisibleDataNeedsDataSource( with /* ablated: export removed */ function navItemVisibleDataNeedsDataSource(. It landed on disk (anchor 1 -> 0, blob 8755bfe0b8eb -> 07a6fe68bd65) and gave "Tests 22 failed | 5 passed (27)", red as predicted. The restore was proven: blob == HEAD 8755bfe0b8eb, and git diff HEAD is empty. No rebuild was needed: the test imports ./app.zod and ./index relatively (src), not via dist. Resolution through package exports, measured by hand from packages/core after the build: ESM import('@objectstack/spec/ui') gives a function of length 2 from dist/ui/index.mjs; CJS require gives a function from dist/ui/index.js. The emitted d.ts is declare function navItemVisibleDataNeedsDataSource(item: unknown, ctx: z.RefinementCtx): void;.",
    "gates": "Local subset on final head 50c3ba8. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; 89 commands, identical before and after the merge) was run sequentially, each exit captured before any pipe: all 89 exit 0. Reconciled with dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.list: exit 0, "89 derived famil(ies) accounted for — 89 run, 0 NOT-MEASURED (a DERIVED zero — all 89 recorded an exit code and none of them is 3)". Among them: spec check:api-surface / check:export-origins / check:generated ("All 14 generated artifacts are up to date", against the dist this head built) / check:entry-nameability / check:browser-reachable-entries / check:dual-source-exports / check:exported-any / check:docs; check-adr-0087-registration, check-changeset-no-major and check-empty-changeset (--base origin/main); check:nul-bytes; check:published-files; check:dual-build-cjs-loads; check:lean-entry-closure; check:type-check-debt (re-measure OK). Pre-merge, check:doc-formula-expressions, check:dual-build-cjs-loads and check:lean-entry-closure exited 3 (PREREQUISITE NOT MET). They exited 0 after turbo run build of formula/lint/objectql and the type-check-debt gate's own full build. Local-only: check:dev-prereqs exit 0; check:skill-frame-freshness exit 0. CI check-runs on 50c3ba8 when this report was written (38 runs). success: Auto Label, Check Documentation Links, Check PR Size, Dogfood Regression Gate, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, Spec property liveness, The card this PR closes must claim this branch, filter. in_progress: Build Core, Check Changeset, Flag docs affected by code changes, Governed Surface Queue Guard, all eight Lint lanes, Test Core (1/6..6/6), Type Check · consumer gates / debt ledger / source gates / workspace. skipped: Build Docs, Console Pin Gate, Dogfood Regression Gate matrix, Dogfood Verify CLI, Packed-tarball smoke (opt-in), Temporal Conformance (live PG + MySQL). Not waited on, per the dispatch contract.",
    "mcp_calls": "0 — no MCP GitHub tool called",
    "api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write.yml as objectstack-fleet[bot]: (1) pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24628/assignees ["zhuangjianguo"], read back as 10013 bytes sent = 10013 stored, assignee zhuangjianguo; (2) this os-dev-report = POST /repos//issues/24534/comments. Not REST: git push of the branch (5 pushes). All reads were REST GETs.",
    "open_questions": [
    {
    "question": "The export judges the spec's PARSED nav entry (visible as the { dialect, source } envelope). objectui's mirror keeps visible as the authored string (z.union([z.boolean(), z.string()])), so attaching the export there as it is refuses nothing on the card's own entry (measured: direct call on the bare string = 0 issues; on its parsed form = the door's issue). Which route closes objectui's door? This dispatch ruled that the function must not change, so this PR changes nothing here.",
    "options": [
    "A — The spec function also reads a bare-string visible as CEL source (one branch beside the envelope read). The spec schema's accept set does not move, because its own check only ever sees the envelope. Only the direct call's answer on raw input changes, which is the posture every sibling in object-refinement-check-exports.test.ts already holds (e.g. page.kind ?? 'full' reads the default the parse would apply). Business need: the card's measured door is the bare-string entry, and the bare string is the dominant authored spelling of a predicate slot (examples/** at 5a871e4: 16 bare-string visible/visibleWhen/visibleOn lines vs 1 envelope). Long term: the rule stays in spec, and the mirror attaches it by identifier (objectui#7715), with no restatement. AI-error: chaining the export alone is enough, and no mirror author has to remember to normalise first. Startup scope: S (one branch, flip pin leg 5, a docblock and changeset sentence), no new export, no new gate. It needs the seat's or maintainer's word, because it changes what the function refuses when called directly.",
    "B — Keep the function. objectui hands it { ...item, visible: typeof item.visible === 'string' ? { dialect: 'cel', source: item.visible } : item.visible } inside its superRefine. Business need: closes the door. Long term: objectui restates the spec's bare-string shorthand normalisation, which drifts if the shorthand rule moves, and bends objectui#7715 ("never restate"). AI-error: a mirror author who reads only the export name attaches it bare and gets a silent no-op, the exact trap; the docblock warns, but a warning does not bind. Startup scope: S in objectui, zero spec change.",
    "C — objectui takes EvaluatedExpressionInputSchema by reference for visible, judged verdict-only as its doc arm already does, because objectui's validator writes no values (its decision batches #69/#90). Business need: closes the door, and also aligns the two other visible divergences (objectui accepts visible: true, which the spec refuses, and refuses the envelope, which the spec accepts). Long term: the most contract-aligned for objectui's slot. AI-error: strongest on the mirror side. Startup scope: M in objectui, and a narrowing of objectui's own published validator (Clause-② there), so a larger ruling."
    ],
    "recommendation": "A, because it is the only option in which attaching by identifier is enough by itself. That holds on the AI-error axis (no silent no-op for a mirror) and the long-term axis (one rule, in spec, read the same on raw and parsed input). The spec's accept set is unchanged and the cost is S, with no gate added. It can ride this PR as one more commit on the seat's word, or go to its own domain:spec card. C stays objectui's own call for the boolean/envelope divergences, independent of this."
    }
    ],
    "out_of_scope_findings": [
    "class: none (read-only inference, not measured through objectui validate) · objectui packages/types/src/zod/app.zod.ts (origin/main 50ba1bb0a6) NavigationItemObject.visible: z.union([z.boolean(), z.string()]) accepts visible: true|false, which the spec's EvaluatedExpressionInputSchema refuses, and refuses the { dialect, source } envelope, which the spec accepts · carrier: 承接者:无 (the objectui follow-up of #24534 Done-when 2 is not yet filed) · noted in PR #24628 Acceptance notes, not filed · dedupe words: objectui nav visible boolean accepted, nav visible envelope refused, NavigationItemSchema visible arm divergence"
    ]
    }


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
    "issue": 24534,
    "status": "done",
    "branch": "claude/issue-24534-export-nav-visible-data-check",
    "pr": "#24628",
    "head": "e058ce508e78c913754deabacd401acb6d2e20c5",
    "session": "session_019oFY6Hi35J7atvgVFnmoaK — the seat's session (this dev is an os-dev subagent of it); patch round 1",
    "premise_still_valid": true,
    "summary": "Patch round 1, the seat's answer A (record 6273673166 on PR #24628), one commit e058ce508e on top of 50c3ba8a4a. navItemVisibleDataNeedsDataSource now also reads an authored bare-string visible. The string goes through EvaluatedExpressionInputSchema (the slot's own schema, already imported by app.zod.ts) via a module-private authoredVisibleEnvelope(source): safeParse, and on success its data, which is the string arm's { dialect: 'cel', source }. The normaliser is reused, not restated, and a blank string the schema refuses judges nothing. The parsed envelope is read exactly as before. A boolean or absent visible judges nothing. The docblock and the changeset say the function accepts the authored and the parsed spelling. Pin leg 5 flipped: the card's entry as written now draws the door's identical issue (code, path, message) from a direct call. It gained a bare-string rewrite of the leg-1 matrix (7 rows) with door parity, the control (same bare string with a dataSource draws nothing), and a boolean/absent leg. The parsed-envelope leg is kept. NavigationItemSchema accepts and refuses exactly what it did: its check only ever sees the parsed envelope. The schema pin app-nav-visible-data-needs-data-source.test.ts is byte-unchanged since 50c3ba8 and passes 23/23. check:api-surface reports "public API surface + factory signatures unchanged". files_changed (this commit): packages/spec/src/ui/app.zod.ts; packages/spec/src/ui/app-nav-visible-data-needs-data-source-export.test.ts; .changeset/24534-export-nav-visible-data-check.md. Generated shards unchanged. deviations: (1) the worktree had been removed after the first report, so it was re-created on the branch at its remote head 50c3ba8 (no rebase, no merge). origin/main moved c395405 -> 973917c with no change to any file this PR touches or reads (app.zod.ts, the two pin files, the ui shards, the changeset, shared/expression.zod.ts), so it was not merged, per the patch order. (2) In the fresh worktree, 3 derived gates first exited 3 (PREREQUISITE NOT MET) again, and exited 0 after the type-check-debt gate's full build. --ran records the exit-0 re-runs. (3) One cosmetic oddity: the bare-string matrix labels are the leg-1 labels with a suffix, so the first row reads "the card's entry, visible as the envelope, visible written as the bare string". It was left as is to keep the patch at one commit. (4) The PR body is unchanged by this round. pr_body_edits carries 12 old/new pairs, each old_str measured to occur exactly once in the stored body (12165-byte preview after applying).",
    "tests": "Head e058ce5. Every run went through os-verify-lock.sh, and each VERDICT line read command-exit 0 unless noted. pnpm --filter @objectstack/spec test: "Test Files 702 passed (702) / Tests 21348 passed | 1 todo (21349)" (+9 vs 50c3ba8, all in the export pin). pnpm --filter @objectstack/spec typecheck: tsc --noEmit + check:scripts-typecheck + "check:test-typecheck: OK — 52 file(s) / 242 error(s) / 132 pinned signature(s) held" (unchanged). Export pin alone: "Tests 36 passed (36)". Schema pin app-nav-visible-data-needs-data-source.test.ts alone: "Tests 23 passed (23)" (file unchanged). Before the commit, the export pin, the schema pin, app-nav-target-exclusivity-export, object-refinement-check-exports and app.test.ts ran together: "Tests 463 passed (463)". Ablation, once, at e058ce5 with the patch committed. node scripts/ablation-replace.mjs replaced const visible = (typeof entry.visible === 'string' with const visible = (/* ablated: bare-string read removed */ false && typeof entry.visible === 'string'. It landed on disk (anchor 1 -> 0, blob 74d3de955a29 -> c459f2d5767d). Running the export pin + the schema pin gave "Test Files 1 failed | 1 passed (2) / Tests 5 failed | 54 passed (59)". The red tests were EXACTLY the new legs: the as-written leg, and the 4 refusing rows of the bare-string matrix (card object entry, dashboard, url bare root, group). The 3 accepting bare-string rows, the dataSource control, the boolean/absent leg, the parsed-envelope leg and the whole schema pin file stayed green. The restore was proven: blob == HEAD 74d3de955a29, and git diff HEAD is empty.",
    "gates": "Head e058ce5. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; change set 5 files, +367/-4; 89 commands, identical to the 50c3ba8 list) was run sequentially, each exit captured before any pipe. 86 exited 0 on the first pass. check:doc-formula-expressions, check:dual-build-cjs-loads and check:lean-entry-closure exited 3 (PREREQUISITE NOT MET, fresh worktree) and exited 0 on re-run after builds. dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.list: exit 0, "89 derived famil(ies) accounted for — 89 run, 0 NOT-MEASURED (a DERIVED zero — all 89 recorded an exit code and none of them is 3)". Before pushing, as ordered: pnpm --filter @objectstack/spec check:api-surface exit 0 ("public API surface + factory signatures unchanged"); check:export-origins exit 0 ("export-origins/ is current: 5530 exports across 19 entry points resolve exactly as recorded"); check:generated exit 0 ("All 14 generated artifacts are up to date", against the dist built at this head). check:type-check-debt re-measure OK. Local-only: check:dev-prereqs exit 0; check:skill-frame-freshness exit 0. CI check-runs on e058ce5 (40) when this report was written. success: Lint & Repo Gates, TypeScript Type Check, Build Core, Governed Surface Queue Guard, Test Core (1/6)..(5/6), Check Changeset, all eight Lint lanes, Type Check · consumer gates / debt ledger / source gates / workspace, Dogfood Regression Gate, Spec property liveness, Flag docs affected by code changes, Check PR Size, Check Documentation Links, Auto Label, filter, the three claim/closure guards. in_progress: Test Core (6/6). skipped: Build Docs, Console Pin Gate, Dogfood matrix, Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance. Not waited on.",
    "mcp_calls": "0 — no MCP GitHub tool called",
    "api_writes": "1 relay stroke this round: POST /repos/objectstack-ai/objectstack/dispatches, executed by fleet-write.yml as objectstack-fleet[bot] as POST /repos//issues/24534/comments (this os-dev-report). Not REST: one git push of e058ce5. No PR body write (pairs in pr_body_edits). All reads were REST GETs.",
    "pr_body_edits": [
    {
    "old_str": "plus the input contract measured below. The .superRefine(navItemVisibleDataNeedsDataSource) on the union inside NavigationItemSchema is unchanged.",
    "new_str": "After the seat's answer A (comment 6273673166), the function also reads an authored bare-string visible. The string goes through EvaluatedExpressionInputSchema, the slot's own schema, via a module-private authoredVisibleEnvelope, so the shorthand normalisation is reused and never restated. The docblock says the function accepts both spellings. The .superRefine(navItemVisibleDataNeedsDataSource) on the union inside NavigationItemSchema is unchanged."
    },
    {
    "old_str": "- packages/spec/src/ui/app-nav-visible-data-needs-data-source-export.test.ts: the export pin (5 legs, below).",
    "new_str": "- packages/spec/src/ui/app-nav-visible-data-needs-data-source-export.test.ts: the export pin (5 legs, 36 tests, below)."
    },
    {
    "old_str": "- What this PR does about it. The dispatch ruled that this PR must not change what the refinement accepts or refuses. So it writes only the honest export, with no behaviour change. The docblock, the changeset and leg 5 of the pin state the input contract. The difference goes to the seat as an open question, with the options below. Making the function read the bare string too would change what the function refuses when it is called directly. It would not change what any spec schema refuses.",
    "new_str": "- What this PR does about it. The first head (50c3ba8a4a) wrote only the export and raised the difference as an open question. The seat answered A (comment 6273673166 on this PR): the function also reads the authored bare string, normalised through EvaluatedExpressionInputSchema (the slot's own schema), so the spelling a mirror hands it is judged exactly as the spec's parse would judge it. Measured on e058ce508e:\n - the card's entry as written now draws the door's identical issue (code, path and message) from a direct call;\n - the same bare string with a dataSource draws nothing;\n - a boolean or absent visible judges nothing.\n\n NavigationItemSchema accepts and refuses exactly what it did, because its own check only ever sees the parsed envelope. The schema pins in app-nav-visible-data-needs-data-source.test.ts are unchanged and green (23 passed)."
    },
    {
    "old_str": "## The pin (app-nav-visible-data-needs-data-source-export.test.ts, 27 tests)",
    "new_str": "## The pin (app-nav-visible-data-needs-data-source-export.test.ts, 36 tests)"
    },
    {
    "old_str": "5. Input contract.\n - The card's bare-string entry is refused by the door.\n - The export raises the identical issue on its parsed visible, and nothing on the bare string.\n - The control (the same entry with a dataSource) is accepted by the door and by the export.",
    "new_str": "5. Both spellings.\n - The card's bare-string entry is refused by the door.\n - The export raises the door's identical issue on the entry's parsed visible and on the entry as written.\n - Over the leg-1 matrix rewritten with bare strings (7 rows: 4 refusing, 3 accepting), the direct call and the door agree issue for issue.\n - The control (the same bare string with a dataSource) draws nothing from the door or the export.\n - A boolean or absent visible judges nothing."
    },
    {
    "old_str": "The first attempt was a no-op: the replacement text was a substring of the anchor, and the tool refused before it ran anything. It was re-run with a distinct marker.",
    "new_str": "The first attempt was a no-op: the replacement text was a substring of the anchor, and the tool refused before it ran anything. It was re-run with a distinct marker. (That reading is at the first head, where the pin had 27 tests.)\n\nAblation of the bare-string read, at e058ce508e with the patch committed. The mutation was const visible = (typeof entry.visible === 'string' → const visible = (/* ablated: bare-string read removed */ false && typeof entry.visible === 'string', through ablation-replace.mjs:\n- landed on disk: anchor 1 → 0, blob 74d3de955a29 → c459f2d5767d;\n- result, running this file with app-nav-visible-data-needs-data-source.test.ts: 5 failed / 54 passed (59);\n- exactly the new legs went red: the as-written leg and the 4 refusing rows of the bare-string matrix;\n- the accepting rows, the controls and the whole schema pin file stayed green;\n- restored: blob == HEAD 74d3de955a29, and git diff HEAD is empty."
    },
    {
    "old_str": "## Tests and gates (final head 50c3ba8a4a, after merging origin/main c3954057fe through scripts/pm/os-regen-merge.sh)",
    "new_str": "## Tests and gates (final head e058ce508e)\n\norigin/main c3954057fe was merged at 50c3ba8a4a through scripts/pm/os-regen-merge.sh. Main's later commits touch no file this PR touches, so it was not merged again."
    },
    {
    "old_str": "- pnpm --filter @objectstack/spec test: 702 files passed, 21339 tests passed, 1 todo.",
    "new_str": "- pnpm --filter @objectstack/spec test: 702 files passed, 21348 tests passed, 1 todo."
    },
    {
    "old_str": "- The new pin file alone: 27 passed.\n- pnpm --filter @objectstack/spec check:generated: All 14 generated artifacts are up to date, against the dist this head built.",
    "new_str": "- The new pin file alone: 36 passed. The schema pin app-nav-visible-data-needs-data-source.test.ts is unchanged since 50c3ba8a4a and passes 23.\n- pnpm --filter @objectstack/spec check:generated: All 14 generated artifacts are up to date, against the dist this head built. check:api-surface reports public API surface + factory signatures unchanged, and check:export-origins reports current."
    },
    {
    "old_str": "- Open question (to the seat): what the export reads, and objectui's mirror. Before objectui can refuse the card's entry by attaching this export, one of these has to hold:\n - (A) the spec function also reads a bare-string visible. The spec schema's accept set does not move, because its own check only ever sees the envelope;\n - (B) objectui hands the function the parsed envelope inside its superRefine;\n - (C) objectui takes EvaluatedExpressionInputSchema by reference for visible.\n\n The analysis is in the dev report on #24534. This PR changes none of it.",
    "new_str": "- The open question, answered A by the seat (comment 6273673166). The function now reads an authored bare-string visible as well as the parsed envelope, so objectui's mirror can attach the export as it is, by identifier. B (objectui restates the shorthand) and C (objectui takes EvaluatedExpressionInputSchema by reference) are not taken here. C stays objectui's own call for its boolean and envelope divergences."
    },
    {
    "old_str": "On the pre-merge head, three of them (check:doc-formula-expressions, check:dual-build-cjs-loads, check:lean-entry-closure) first exited 3 (PREREQUISITE NOT MET, nothing measured). They exited 0 once their packages were built, and exit 0 on this head.",
    "new_str": "On both heads, three of them (check:doc-formula-expressions, check:dual-build-cjs-loads, check:lean-entry-closure) first exited 3 (PREREQUISITE NOT MET, nothing measured) in a freshly created worktree. They exited 0 once their packages were built, and --ran records those exit-0 re-runs."
    },
    {
    "old_str": "- CI check-runs: not yet reported when this body was written. The report on #24534 cites them.",
    "new_str": "- CI check-runs on e058ce508e (40 runs), read when the patch report was written: every required context is green (Lint & Repo Gates, TypeScript Type Check, Build Core, Governed Surface Queue Guard, Test Core (1/6) to (5/6)), and Test Core (6/6) is in progress. The patch report on #24534 cites them."
    }
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: the objectui follow-up of #24534 Done-when 2, which the seat files when this lands (seat record 6273673166) · objectui NavigationItemObject.visible accepts a boolean and refuses the envelope, while the spec does the reverse · noted, not filed separately"
    ]
    }


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Follow-ups filed · domain:spec seat 2 · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-19T19:06Z


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 2 · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-19T20:02Z


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsdomain:specpriority:p1High: required for production / M2target:v18

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions