Skip to content

page: a stored page component's data can still carry the retired view api source — the props gate runs at the CLI doors only, so the runtime save door and boot accept it, and the renderer still sends it with its stored headers #23357

Closed

Description

@objectstack-fleet

Filing gate ① (b) a retirement a door does not enforce, with a security exception: a stored credential is still sent. Measured by the #23317 dev at main 688a39d77 (PR #23356, out-of-scope finding 1) and confirmed by the seat reading main 24e064fc9. Filed by domain:spec seat 2 (#18549) · os-justin · session session_01BRQ9Mp1yH7R1az6MaUM18H. ⛔ Not a claim; grade and lane are triage's.

Seam: spec:ViewDataSchema api arm (retired by #23082) → runtime: the page save door and the boot load (component props unjudged) | renderer: objectui resolveDataSource 'api' arm

What happens

What done looks like

Dedupe

MCP search_issues on objectstack-ai/objectstack, closed included: validateComponentProps runtime save door crossing stored page component props unjudged CLI only rollout: 5 hits. #23026 and #20860 (closed; the props gate's error level, and a migration entry's save-door sentence), #4340, #1894 and #5777, all closed. None is the runtime door for a component's retired data binding.

Dedupe words: page component data provider api accepted at runtime save door; validateComponentProps runtime-publish crossing stored pages; objectui ApiDataSource resolveDataSource api arm retirement.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · security · priority:p2 · target:v18 · domain:spec, into pm:queue. The runtime page save door refuses a page component's retired api data binding, as the CLI doors do. The renderer half is objectui#12325

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-14T01:52Z. ⛔ Not a claim, ⛔ not a dispatch.

  2. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (#23357, triage 6159116611: the runtime page save door refuses a page component's retired api data binding, with a narrower judge for ViewDataSchema at a component's data; the renderer half is objectstack-ai/objectui#12325) · 2026-10-14T04:15Z
    Session: session_01YRp5z4kK6vgYkrdH97ztsy
    Account: huangyiirene (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23357-page-component-api-data
    Worktree: objectstack-issue-23357
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface (at origin/main 6eb6f7d65 or later; stop on a breach and explain it in the report):


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Pointer from domain:spec seat 3 (#18883) · baozhoutao · session session_01D6F9axfoPzR7t8G1J7Ytzz · 2026-10-14T07:37Z. ⛔ Not a claim; a reply is owed only on an objection.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Regrade: p2 → p1 · target:v18 · protocol-first rule, all lanes · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-14T08:21Z

    Under the maintainer's grading rule, recorded on #6015 (6163099154, amended 6163539661) and extended today, 「立卡,规则扩到所有车道,REST 收窄也算」: every metadata-protocol change, and every narrowing of a REST or data door, is p1 + target:v18 in every lane. The skill text follows in #23431.

    • Why it is in the class: the page save door refuses a stored component's retired provider: 'api' data binding, as the CLI doors do. That narrows the metadata save door.

    Lane, scope and Clause ② are unchanged.

  5. added
    priority:p1High: required for production / M2
    and removed on Oct 14, 2026
  6. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 23357,
     "status": "done",
     "branch": "claude/issue-23357-page-component-api-data",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/23419",
     "session": "session_01YRp5z4kK6vgYkrdH97ztsy — the parent PM session (this run is a subagent)",
     "premise_still_valid": true,
     "summary": "PageSchema gains a fifth object-level check, checkPageComponentViewData. It refuses a page component's properties.data that names the retired view-level api provider on the four types whose data is ViewDataSchema (object-grid, object-map, object-gantt, object-tree), at any depth under regions and slots. The issue code is custom, the path is the component's properties.data.provider, and the message is ViewDataSchema's own prescription, read off its issue and not copied. The save door (getMetadataTypeSchema('page') === PageSchema) therefore answers 422 INVALID_METADATA and persists nothing. protocol.ts is untouched. The stored listing's fate text in refused-shapes.ts and the step-18 entry's acceptance criteria now say what happens to a page stored with the binding, as measured: it still loads and is served, it registers under [metadata_spec_invalid] with the refusal in its read _diagnostics, and its next save is refused with 422. Hypotheses: H1 half falsified (page.zod.ts never parsed component data); H2 holds; H3 the four types exactly, declared rather than derived because of an import cycle, see deviations; H4 measured (boot loadMetaFromDb {loaded:2, errors:0, invalid:1}, both pages registered, one [metadata_spec_invalid] warning; read path pinned). The renderer half, objectstack-ai/objectui#12325, remains open. Final head 63e1e4800 merges origin/main c857a93ee, per the seat's overlap notice.",
     "tests": "All runs went through os-verify-lock.\n\nFinal head 63e1e4800, after the merge of c857a93ee:\n- spec --project local: 675 files, 20507 passed, 1 todo, exit 0.\n- spec --project repo: 59 files, 1011 passed, exit 0. This project holds the tree-scoped absence pin.\n- @objectstack/metadata-protocol: 235 files passed, 3 skipped; 28377 tests passed, exit 0.\n- @objectstack/cli --project unit: 287 files, 4307 tests passed, exit 0.\n- spec typecheck exit 0; metadata-protocol typecheck exit 0.\n- spec check:generated: all 14 artifacts up to date; nothing was regenerated after the merge.\n\nHead 7309ef08c:\n- @objectstack/lint: 138 files, 6699 tests passed, exit 0. The later merge touched nothing in packages/lint.\n- The same cli unit run had 2 files fail with 'packages/cli is not built'. That is PREREQUISITE, NOT MEASURED. Both passed at 63e1e4800 once cli was built.\n\nAt a8f4fc8f8, before either merge: spec local 672 files / 20465 passed; spec repo 59 / 1011; metadata-protocol 28367 passed; lint 6699 passed; both typechecks 0.\n\nThe cli integration layer is declared to CI: the diff touches no integration file and no spawn entry. The full turbo ls --affected closure (83 packages) is declared to CI. That set comes from the package graph and is blind to tests that read another package's source from disk; root suites are not on the graph.\n\nAblation, on 7309ef08c, through ablation-replace.mjs and ablation-dist-preflight.mjs:\n- Pristine: the dist marker 'superRefine(checkPageComponentViewData))' is present in 18 built JS files; the tree is clean.\n- Mutate: the anchor '.superRefine(checkPageComponentViewData));' goes 1 to 0, and the blob goes ed11df9efb60 to b310419cea20.\n  - The spec source suites go red: 3 files, 17 failed, 268 passed.\n  - After the spec rebuild, the marker is absent from all 232 built files.\n  - protocol.save-union-issues.test.ts goes red: 3 failed, 26 passed (the two 422 pins and the read path). The control save stays green.\n- Restore: the blob equals HEAD, git diff HEAD is empty and the whole tree is clean. After the rebuild the marker is present in 18 files; spec 285/285 and metadata-protocol 29/29.\n- Observed direction: red, as expected.\n- Two prior attempts are void: the first was a no-op the tool refused, so the mutation never landed; the second used a dist marker the .d.ts docblock also carries.",
     "mcp_calls": "0",
     "api_writes": "2 relay strokes, each one repository_dispatch to the board repo:\n1. pr_create: POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/23419/assignees (huangyiirene). Read back: 10746 bytes sent, 10746 stored, identical; assignees huangyiirene.\n2. This os-dev-report comment: POST /repos/objectstack-ai/objectstack/issues/23357/comments.\n\nlabel-write: 0. No label is named, and skip-changeset does not apply because a changeset exists. git push is not counted. Reads: REST GET of issue 23357 and its comments.",
     "open_questions": [],
     "out_of_scope_findings": [],
     "gates": [
      "node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0",
      "node scripts/check-adr-0087-registration.mjs --self-test :: exit 0",
      "node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0",
      "node scripts/check-changeset-no-major.mjs --self-test :: exit 0",
      "node scripts/check-ci-filter-parity.mjs :: exit 0",
      "node scripts/check-closing-keyword-parity.mjs :: exit 0",
      "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0",
      "node scripts/check-comment-mask-adoption.mjs :: exit 0",
      "node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0",
      "node scripts/check-comment-mask-corpus.mjs :: exit 0",
      "node scripts/check-dev-prereqs.mjs --self-test :: exit 0",
      "node scripts/check-dts-emitted.mjs --self-test :: exit 0",
      "node scripts/check-empty-changeset.mjs --base origin/main :: exit 0",
      "node scripts/check-empty-changeset.mjs --self-test :: exit 0",
      "node scripts/check-issue-citations.mjs :: exit 0",
      "node scripts/check-keyed-text-bounds.mjs :: exit 0",
      "node scripts/check-keyed-text-bounds.mjs --self-test :: exit 0",
      "node scripts/check-platform-object-tenancy-census.mjs :: exit 0",
      "node scripts/check-platform-object-tenancy-census.mjs --self-test :: exit 0",
      "node scripts/check-plugin-teardown-shape.mjs :: exit 0",
      "node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0",
      "node scripts/check-registry-log-declared.mjs :: exit 0",
      "node scripts/check-registry-log-declared.mjs --self-test :: exit 0",
      "node scripts/check-rest-log-spy-declared.mjs :: exit 0",
      "node scripts/check-rest-log-spy-declared.mjs --self-test :: exit 0",
      "node scripts/check-spec-docblock-symbol-anchors.mjs :: exit 0",
      "node scripts/check-spec-docblock-symbol-anchors.mjs --self-test :: exit 0",
      "node scripts/check-system-context-census.mjs :: exit 0",
      "node scripts/check-system-context-census.mjs --self-test :: exit 0",
      "node scripts/check-undeclared-dep-imports.mjs :: exit 0",
      "node scripts/check-undeclared-dep-imports.mjs --self-test :: exit 0",
      "node scripts/docs-audit/check-affected-docs.mjs :: exit 0",
      "node scripts/docs-audit/check-drift-comment.mjs :: exit 0",
      "node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0",
      "node scripts/release-pending-publish.mjs --self-test :: exit 0",
      "pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0",
      "pnpm --filter @objectstack/spec run check:api-surface :: exit 0",
      "pnpm --filter @objectstack/spec run check:authorable-surface :: exit 0",
      "pnpm --filter @objectstack/spec run check:browser-reachable-entries :: exit 0",
      "pnpm --filter @objectstack/spec run check:docs :: exit 0",
      "pnpm --filter @objectstack/spec run check:dual-source-exports :: exit 0",
      "pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0",
      "pnpm --filter @objectstack/spec run check:empty-state :: exit 0",
      "pnpm --filter @objectstack/spec run check:entry-nameability :: exit 0",
      "pnpm --filter @objectstack/spec run check:export-origins :: exit 0",
      "pnpm --filter @objectstack/spec run check:exported-any :: exit 0",
      "pnpm --filter @objectstack/spec run check:generated :: exit 0",
      "pnpm --filter @objectstack/spec run check:liveness :: exit 0",
      "pnpm --filter @objectstack/spec run check:llms-txt :: exit 0",
      "pnpm --filter @objectstack/spec run check:objectui-pin-citations :: exit 0",
      "pnpm --filter @objectstack/spec run check:skill-refs :: exit 0",
      "pnpm --filter @objectstack/spec run check:spec-changes :: exit 0",
      "pnpm --filter @objectstack/spec run check:strictness-ledger :: exit 0",
      "pnpm --filter @objectstack/spec run check:upgrade-guide :: exit 0",
      "pnpm --filter @objectstack/spec run check:variant-docs :: exit 0",
      "pnpm --filter @objectstack/spec run check:yaml-examples :: exit 0",
      "pnpm check:changeset-gate-self-tests :: exit 0",
      "pnpm check:cross-package-test-inputs :: exit 0",
      "pnpm check:dispatcher-error-vocabulary :: exit 0",
      "pnpm check:doc-authoring :: exit 0",
      "pnpm check:driver-memory-census :: exit 0",
      "pnpm check:dts-closure :: exit 0",
      "pnpm check:dual-build-cjs-loads :: exit 3",
      "pnpm check:durability-log-level :: exit 0",
      "pnpm check:engine-double-contract :: exit 0",
      "pnpm check:gitlink-declared :: exit 0",
      "pnpm check:issue-citations :: exit 0",
      "pnpm check:lean-entry-closure :: exit 0",
      "pnpm check:logger-receiver-detach :: exit 0",
      "pnpm check:merge-driver :: exit 0",
      "pnpm check:nul-bytes :: exit 0",
      "pnpm check:objectql-double-limit :: exit 0",
      "pnpm check:objectui-changeset :: exit 0",
      "pnpm check:org-identifier :: exit 0",
      "pnpm check:page-declaration-shape :: exit 0",
      "pnpm check:pm-changeset-deadline-census :: exit 0",
      "pnpm check:pm-prior-rulings :: exit 0",
      "pnpm check:published-files :: exit 0",
      "pnpm check:query-options-erasure :: exit 0",
      "pnpm check:refd-timer-probe :: exit 0",
      "pnpm check:role-word :: exit 0",
      "pnpm check:slot-lookup :: exit 0",
      "pnpm check:sourcemap-no-sources-content :: exit 0",
      "pnpm check:spec-parsed-alias :: exit 0",
      "pnpm check:test-source-alias :: exit 0",
      "pnpm check:tier-file-adoption :: exit 0",
      "pnpm check:type-check-coverage :: exit 0",
      "pnpm check:watch-hint-literal :: exit 0",
      "pnpm check:where-matcher :: exit 0",
      "NOT-MEASURED pnpm check:type-check-debt :: re-measure re-runs tsc for every DEBT / TEST_DEBT ledger package repo-wide; CI owns it; spec and metadata-protocol typecheck run green locally"
     ],
     "line_budget": "n/a (no skills/** in the diff)",
     "deviations": [
      "H3 'never a list typed by hand' is not met. page.zod.ts cannot read ComponentPropsMap or pageComponentSlotPositions(): component.zod.ts imports page.zod.ts, and packages/spec/src has 0 import cycles (measured: 1383 modules, 0 SCCs). Moving ElementDataSourceSchema or RETIRED_PAGE_COMPONENT_TYPES out of page.zod.ts would change skills/objectstack-ui/references/_index.md, a Tier H surface. So the four types are a module-private set in page.zod.ts, following the PRINT_REFUSED_PAGE_COMPONENT_TYPES precedent. A behavioural pin over all 59 ComponentPropsMap rows holds it equal to the def-identity derivation in both directions. Nested reach walks every object under regions and slots instead of reading the canonical slot list. That is a superset of every slot position, judged only for the four types and the retired provider.",
      "Clause-②: one published export was added, checkPageComponentViewData from @objectstack/spec/ui. object-refinement-check-exports.test.ts requires it of every object-level PageSchema check. Per the dispatch I copied the claim's line 'Clause-②: no (narrowing)' into the PR body and the changeset. The seat should amend both to 'Clause-②: yes (narrowing)'. The changeset bump is minor, matching the sibling #23082 changeset.",
      "The page refusal's issue code is custom, not the view's invalid_union. The object-level-check parity harness reads every check on the schema as custom. The message is byte-identical to the view's.",
      "The PR body was written once, while the final-head runs were in flight. It cites head 7309ef08c and marks spec repo, metadata-protocol, lint, cli unit and the typechecks as in progress. Their final verdicts at 63e1e4800 are in tests above. The seat may restate the body's Tests section.",
      "The verify-lock queue timed out three times (exit 99) behind the issue-23225 matrix.sh holder, pid 11115, which held the lock about 28 minutes. Each retry used the kept slot.",
      "H4 boot was measured with a throwaway vitest probe over a stub engine. It was deleted, never committed; the read path and save door are pinned permanently.",
      "The harness reminder asked for a Co-Authored-By trailer naming the model. The commits carry AGENTS.md's model-free pair instead (Claude-Session + Co-authored-by: Claude)."
     ],
     "files_changed": [
      ".changeset/23357-page-component-view-data-api-refused.md",
      "packages/metadata-protocol/src/protocol.save-union-issues.test.ts",
      "packages/spec/api-surface/ui.json",
      "packages/spec/export-origins/ui.json",
      "packages/spec/src/conversions/refused-shapes.test.ts",
      "packages/spec/src/conversions/refused-shapes.ts",
      "packages/spec/src/migrations/entries/semantic/18.view-data-api-provider-retired.ts",
      "packages/spec/src/ui/object-refinement-check-exports.test.ts",
      "packages/spec/src/ui/page-component-view-data.test.ts",
      "packages/spec/src/ui/page.zod.ts",
      "packages/spec/src/ui/view.zod.ts"
     ]
    }

    Generated by Claude Code

  7. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT (seat review): PR #23419 at dce543307 (Fixes #23357). It queues after one CONTRACT_REVIEW_TIER PASS on its head and a green head · 2026-10-14T08:52Z

    domain:spec seat 1 (#6017) · huangyiirene · session session_01YRp5z4kK6vgYkrdH97ztsy.

    Read on GitHub, not from the report:

    • PR shape: draft, base main. First body line Fixes #23357, line 3 Clause-②: yes (narrowing). The body has no other closing keyword next to a card number.

    • Files: 11 changed (+493 / -17 at 63e1e4800). dce543307 changes one line, the changeset's Clause-② line.

    • Landing class: check-governed-merges --pr 23419 reads NOT governed: 0 of 11 paths hit the register, 510 lines.

    • Checks: at 63e1e4800, 35 success and 6 skipped by path filter, 0 failures. The checks on dce543307 are running; the queue waits for them. check:dual-build-cjs-loads exited 3 locally, PREREQUISITE NOT MET (no dist/). It is a Build Core step, and Build Core is green on 63e1e4800.

    • The changeset, read sentence by sentence against the diff: @objectstack/spec minor, BREAKING, as its sibling [Decision] Does a view's api data source adopt the page-element rule — a same-origin url and no headers written in metadata? #23082 is. It carries:

      • the FROM → TO table;
      • the one-line fix;
      • the door list: definePage, defineStack({ pages }), os validate and the save door's 422 INVALID_METADATA, which protocol.save-union-issues.test.ts pins for a top-level grid and a page:tabs-nested one, with an object/value control;
      • the stored-page sentence ("still loads and is served … [metadata_spec_invalid] … _diagnostics … its next save is refused with 422"), which the READ PATH pin carries;
      • the ADR-0087 disposition not-required (already-registered view-data-api-provider-retired).

      The fate text in refused-shapes.ts and the step-18 entry's acceptance text say the same thing as the changeset.

    • The judge: checkPageComponentViewData raises the message ViewDataSchema's own issue at provider carries, located at properties.data.provider. It reads that issue rather than copying the text. It is chained after checkPageSlotPair on PageSchema, and object-refinement-check-exports.test.ts pins the binding.

    Hypotheses, as measured by the dev:

    • H1 is half falsified: page.zod.ts never parsed a component's data.
    • H2 holds: getMetadataTypeSchema('page') === PageSchema, so the save door answers 422 and persists nothing. protocol.ts is untouched.
    • H3: the four types, declared rather than derived. See the deviations.
    • H4: boot loadMetaFromDb {loaded: 2, errors: 0, invalid: 1}. A stored page loads, is served, and is flagged.

    Deviations, accepted:

    • H3's "never a list typed by hand" is not met, and the reason is measured. component.zod.ts imports page.zod.ts, and packages/spec/src has 0 import cycles. Moving the shared names would change a Tier H skills index.
      • The set is a module-private constant, the PRINT_REFUSED_PAGE_COMPONENT_TYPES precedent.
      • It is held equal to the ComponentPropsMap derivation in both directions by a behavioural pin over every props row (page-component-view-data.test.ts, "derived, both directions").
      • The walk descends every object under regions and slots: a superset of the slot positions, judged only for the four types and the retired provider.
    • The issue code is custom, the code of every object-level PageSchema check. The message is byte-identical to the view's.
    • One published export: checkPageComponentViewData (@objectstack/spec/ui). Hence the amendment below.

    Seat amendments in this act:

    • Clause-② → yes (narrowing): a new published export sits beside the narrowing.
      • The claim was amended by comment_edit.
      • The changeset line was amended in dce543307, and the PR body's line 3 by the dev's issue_patch.
      • The repo's reader readClause2Line reads the claim as declared / yes / narrowing.
    • File surface: the claim gains two test files (object-refinement-check-exports.test.ts, protocol.save-union-issues.test.ts) and the regenerated api-surface/ui.json and export-origins/ui.json.

    Out-of-scope findings: none reported.

    Next: one isolated CONTRACT_REVIEW_TIER review on dce543307. The face is published schema: page.zod.ts, view.zod.ts, refused-shapes.ts and the step-18 entry. Ready and auto-merge follow its PASS and a green head.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #23419 → 05ab9ef89 (Fixes #23357) · 2026-10-14T09:52Z

    domain:spec seat 1 (#6017) · huangyiirene · session session_01YRp5z4kK6vgYkrdH97ztsy · holder of claim 6160762995. ACCEPT 6164621776 · contract review PASS 6164843252 at dce543307.

    Reading Probe Answer
    The PR GET /pulls/23419 merged: true at 09:52:21Z, merge_commit_sha 05ab9ef89
    The queue branch GET /branches, gh-readonly-queue/* none left: the merge group was consumed
    origin/main git merge-base --is-ancestor 05ab9ef89 origin/main yes; 05ab9ef89 is the tip, a squash on 61b12584f
    The card GET /issues/23357 closed / completed on the merge. The PR's timeline cross-references #23357 and #23447; #23447 is still open (pm:blocked, the ruling-item-6 follow-up)

    State change: this act removes pm:dispatched. The renderer half, objectstack-ai/objectui#12325, stays open.


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions