Repository navigation
[Decision] Does a view's api data source adopt the page-element rule — a same-origin url and no headers written in metadata? #23082
Description
Ruled: 6134088274 · letter C · 2026-10-12T22:52Z
Filing gate ②: a decision only the maintainer can make (a security boundary, on the human floor). Raised by the CONTRACT_REVIEW_TIER review of PR #23079 (6129353387, ③ item 4), escalated by domain:spec seat 2 (#18549) · session session_01GZSPSQ5ArPjSJdxxuqwGoZ. ⛔ Not a claim.
Reader who acts: the maintainer decides. A domain:spec seat executes the chosen letter.
Background
- The ruling on spec(ui): a page element dataSource can name an API endpoint (provider: 'api'), so a product page composes from a control-plane summary in metadata instead of a product-specific React widget (maintainer ruling 2026-10-12) #23016 gave a page element's
apidata source a hard rule: "Same-origin only. No credentials in metadata; the console's authenticated fetch is reused. A cross-originurlis refused at parse". PR feat(spec): a page element dataSource can name an API endpoint (provider: 'api') #23079 implements it. - The OLDER, view-level
apidata source (ViewDataSchema,provider: 'api', inpackages/spec/src/ui/view.zod.ts) has no such rule.- Its
read/writeareHttpRequestSchema(packages/spec/src/shared/http.zod.ts): anyurlstring andheaders: z.record(...)described as "Custom HTTP headers", plusparams,bodyand a method set.
- Its
- objectui honours both at the pin
7578323a544e:ApiDataSourcemerges the authoredheadersinto the request (packages/core/src/adapters/ApiDataSource.tslines 189–191).- It fetches
urlas written (buildUrl/fetchFn, lines 187 and 219).
Governing text
- The spec(ui): a page element dataSource can name an API endpoint (provider: 'api'), so a product page composes from a control-plane summary in metadata instead of a product-specific React widget (maintainer ruling 2026-10-12) #23016 ruling body (above). It is scoped to the page element.
- AGENTS.md Prime Directive chore: version packages #10 (declared = enforced) and Add comprehensive test suite for Zod schema validation #12 (contract-first: refuse at authoring, not in a consumer).
- No ADR found for view data source origins or credentials. Search:
git grep -il "credential|same-origin|cross-origin" origin/main -- docs/adrgives hits on other surfaces only.
Premises, each with a re-check
- No in-repo producer writes
headersor an absolute URL into a view'sapisource.- Re-check:
git grep -n -A6 "provider: 'api'" origin/main -- ':!packages/spec/src/**' ':!**/CHANGELOG.md' | grep -E "headers|https?://". 0 hits atdf7a137923. - Positive control: the same grep without the second filter hits the generated reference pages.
- Re-check:
- objectui sends authored headers.
- Re-check:
git -C ../objectui show origin/main:packages/core/src/adapters/ApiDataSource.ts | grep -n "base.headers".
- Re-check:
- objectstack-ai/cloud's own view metadata: NOT MEASURED (no read access from this session).
The question
A credential (an API key in headers), or a request to another origin, can be written into a view today. It is stored in metadata, served to every client that reads the view, and sent by the console. Does the view-level api source take the same same-origin / no-credentials rule as the page element's?
Options
| Letter | What | What a customer sees | Work |
|---|---|---|---|
| A | Align: the view api source's read.url / write.url take the page element's same-origin rule (one shared predicate). headers and other credential-shaped keys are refused with the "signed-in fetch" prescription. |
A view that wrote a cross-origin URL or a header now fails os validate / publish with the reason and the fix. No measured producer is affected. |
domain:spec · 1 PR (BREAKING narrowing, FROM → TO). Precedent: PR #23079 (+634/−31) built the page-element version of the same rule. |
| B | Keep: the view api source stays open. |
No change. A key written in headers keeps being stored and served with the view. |
none |
| C | Retire the view api source entirely (zero in-repo producers outside docs). |
Views can only bind objects or static values. The page element binding becomes the one API path. | domain:spec · 1 PR plus docs, and skills/** text (Tier H). No precedent. |
- Business meaning: A = "one door policy for every metadata-declared API call". B = "the page door is locked, the view door is not". C = "close the view door and use the page door".
Analysis (四维分析)
os-decision-facets
- ① 项目长远合理性:A 让「元数据里声明的 API 调用」只有一条同源、无凭据的规则,缩小特例;B 留下两套规则,页面元素和视图同一件事两种答案;C 最彻底,但砍掉文档与技能已经在教的视图 API 能力。
- ② 实际业务拉动:今天在本仓零生产者写跨域 URL 或 headers(实测,见前提 1);拉动来自安全姿态,不是用户需求;cloud 仓未测。
- ③ 防 AI 犯错:schema 现在把
headers描述为「Custom HTTP headers」,等于邀请 AI 把密钥写进元数据,而它会被静默存储并随视图下发;A 在发布时响亮拒绝,B 静默容忍。 - ④ 创业阶段不扩散:A 收窄一个已声明、零使用的面,立即生效、无过渡;C 删得更多,但需要动对外技能文本(Tier H)。
- Prior rulings read:
same-origin credentials metadata api data source→ 1 hit (the spec(ui): a page element dataSource can name an API endpoint (provider: 'api'), so a product page composes from a control-plane summary in metadata instead of a product-specific React widget (maintainer ruling 2026-10-12) #23016 ruling body); ADR none; thread: none.
Recommendation
A.
- Long-term reading first: every major low-code platform keeps credentials out of the page/view definition and routes them through a server-side named credential or proxy. One rule for both binding kinds is that end state here.
- Fallback: B. This is acceptable only if cloud measures a real cross-origin or header-bearing view.
- Confidence gap: cloud's view metadata is not measured.
- Self-check: reading ① alone gives A; ②③④ do not flip it (② is zero pull, which argues for doing A now while the cost is zero).
After the ruling
- A: this card moves to
pm:queuewith the ruling quoted. Adomain:specseat dispatches one PR that reuses PR feat(spec): a page element dataSource can name an API endpoint (provider: 'api') #23079's same-origin predicate onHttpRequestSchemawhereViewDataSchemauses it (not on everyHttpRequestSchemareader; the PR enumerates them). It ships a BREAKING changeset with FROM → TO and an ADR-0087 disposition. - B: closed
not_plannedwith the ruling quoted. - C: a retirement card per the
spec-property-retirementplaybook.
Related
#23016 (the ruling) · PR #23079 (the page-element rule) · objectstack-ai/objectui#12197 (the generic blocks that read the page-element binding).
Dedupe
MCP search_issues on objectstack-ai/objectstack, closed included, for ViewDataSchema api provider headers credentials cross-origin url HttpRequestSchema view data source same-origin: 0 hits.
Activity
objectstack-fleet commentedon Oct 12, 2026
Triage: decision-box entry check, with one completion. The 「维护者速读」 block and a one-letter question are added. Graded
security·priority:p2·domain:spec·area:accessTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-12T18:00Z. ⛔ Not a claim, ⛔ no letter chosen.维护者速读
今天的规则:页面元素用
api数据源时,只能请求本站地址,元数据里也不能写凭据(这是您在 #23016 定的)。但更早就有的「视图」级api数据源没有这条规则:可以写任意外部地址,也可以在headers里写密钥。写进去的密钥会随视图一起存储、发给每个读取这个视图的客户端,控制台还会把它带在请求里发出去。目前本仓没有任何视图这样写,cloud 的还没查。三条路:headers之类可放凭据的键在发布时直接拒绝,并提示改用登录态请求domain:spec1 个 PR(收窄,有先例 PR #23079)api数据源,只留页面元素这一条路立卡席位推荐 A,本席同意。
选 A、B 还是 C?
objectstack-fleet commentedon Oct 12, 2026
Ruling: batch #331 item 5 · letter C · maintainer 「同意」 2026-10-12T22:46Z
Director seat, summon #39,
session_01TJKP6W6UDYEBHtccVdpVoz(GitHubos-steve; written asobjectstack-fleet[bot]through the relay, read back). Presented in this seat's chat as batch #331 item 5 with recommendation C (the filing seat and triage recommended A; this seat's reading differed on the long-term axis and said so); the maintainer's word was 「同意」. Thread-read: 6129766256.C — the view-level
apidata source retires.ViewDataSchema'sprovider: 'api'branch (read/writeasHttpRequestSchema) leaves the authorable face under ADR-0049 enforce-or-remove, with an ADR-0087 disposition and a BREAKING changeset FROM → TO: a view binds an object or static values; a metadata-declared API call is the page element's binding (the #23016 rule, PR #23079), same-origin and credential-free. Governing text: SKILL.md 〈升级与决策〉's second meta-criterion (one operation with two implementations that behave differently: the governed side wins and the other is re-bound and removed, not aligned); the four-axis rule that a published zero-consumer capability is not exempt for sunk cost; ADR-0062 as the home of external data. A (align the view source to the page-element rule) was the fallback and is not taken; B is not taken.domain:spec· 1 PR (the retirement per thespec-property-retirementplaybook; thecontent/docs/**pages that teach it; theskills/**text that teaches it, Tier H, so the PR lands only on an authorized approval) · objectui 1 small follow-up deletingApiDataSourceand itsrelated-count-storeuse once the spec release is installable · no precedent on this face.needs-user-decision→pm:queue(domain:spec) in this act, unassigned; it is the retirement card, no new card. The dev enumerates every reader ofHttpRequestSchemaand touches only theViewDataSchemabranch; the page-elementapibinding is untouched. The objectui card is filed by thedomain:spec@ objectui seat when the spec release carrying the removal is installable (the cross-repo unlock rule).provider: 'api'on a view in objectstack, objectui or hotcrm; the dev measures all three (premise 1 of the card measured objectstack atdf7a137923). cloud is not measured from this session and the maintainer's 「同意」 covers it; if a cloud view with anapisource surfaces, or any producer of thewriteleg, the dev reports the fork and the card returns to the box; ⛔ no silent A.objectstack-fleet commentedon Oct 13, 2026
Claim: PM loop round 1 (#23082, ruling C
6134088274: the view-levelapidata source retires under ADR-0049, per thespec-property-retirementplaybook) · 2026-10-13T01:30ZSession:
session_01BRQ9Mp1yH7R1az6MaUM18HAccount:
os-justin(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch:
claude/issue-23082-retire-view-api-sourceWorktree:
objectstack-issue-23082Domain:
domain:specSeat:
domain:spec#2(seat post #18549)Ruling-ref:
6134088274(batch #331 item 5, letter C), read in this act.File surface (at
origin/mainc9b5b24b0or later; stop on breach and explain in the report):packages/spec/src/ui/view.zod.ts:ViewDataSchema'sprovider: 'api'branch only;HttpRequestSchema(packages/spec/src/shared/http.zod.ts) is not edited where another reader keeps it, and the page-elementapibinding is untouched;packages/spec/liveness/view.json, the ADR-0087 disposition underpackages/spec/src/migrations/entries/**, the generated artifactscheck:generatednames, tests, one.changeset/23082-*.md(BREAKING, FROM → TO);content/docs/**pages and theskills/**text that teach a view'sprovider: 'api'(skills/**is Tier H: the PR lands only on an authorized approval).Container & model:
M(a retirement with docs and published-skill text),mode:subagent,model: CONTRACT_REVIEW_TIER(dispatch-gates --tier: MANDATORY,skills/objectstack-ui/rules/list-views.md ⇢ 'skills/**', clause ①). It owes a review atCONTRACT_REVIEW_TIERbefore the maintainer's approval request.Clause-②: no (a retirement narrows the accept set)
Responsibility: n/a — not a defect card
Thread-read: 6134088274
Serial constraints cleared (all 12 open PRs' file lists read at 2026-10-13T01:26Z): PR chore(objectui): move the console pin to 1fb1ced36243 (objectui main tip, Half 1 of #23104) #23110 (chore(objectui): move the console pin to objectui main (1fb1ced36243 at filing), then run every surface:browser and surface:mixed checklist item against the console built from the new pin #23104) edits
view.zod.tsat:3529–:3662(form fields), and PR fix(metadata-protocol)!: the save door refuses aprotectionblock instead of storing a lock that binds nothing #23115 (metadata-protocol: the Studio save door stores a hand-authoredprotectionblock on an environment item verbatim and never binds it, though the spec says the block is translated into_lockand stripped before persistence #23096) at:5143and:5363; theViewDataSchemaregion (:160–:220) is neither. Ordinary concurrency; the later lander mergesmain. Thepackages/specui generated shards land one PR at a time (landing-operations D), after PR feat(spec)!: the page action rows' url target, a dashboard header action's actionUrl and onSuccess.navigate apply the shared url-target refusal #23101.This act moves the card
pm:queue→pm:dispatchedand assignsos-justin.Generated by Claude Code
feat(spec)!: retire the view-level api data source (#23082) — WIP
feat(spec)!: retire the view-level api data source (#23082) — regen +…
objectstack-fleet commentedon Oct 13, 2026
os-dev-report
{ "issue": 23082, "status": "done", "branch": "claude/issue-23082-retire-view-api-source", "pr": "https://github.com/objectstack-ai/objectstack/pull/23160", "session": "session_01BRQ9Mp1yH7R1az6MaUM18H", "premise_still_valid": true, "summary": "Ruling C executed: the `provider: 'api'` arm of `ViewDataSchema` (its `read`/`write` HttpRequestSchema blocks) is removed as a VALUE retirement on the #17053 route — no retiredKey() tombstone, no RETIRED_KEYS row; the prescription `VIEW_DATA_API_PROVIDER_RETIRED` rides the discriminated union's own `error` map keyed on `input.provider === 'api'`, at path `data.provider` (`invalid_union`), so any other unknown provider keeps zod's report listing the three live arms. ADR-0087: D3 `view-data-api-provider-retired` + STEP18 fragment (order 95); deliberately no D2 (the replacement lives on a page element; deleting a view's `data` would silently re-bind it to its object). Liveness: `list.data`/`form.data` stay `live` with the arm's retirement record and pinned objectui read points; `variant-docs.json` key narrowed; `views.mdx` and `skills/objectstack-ui/rules/list-views.md` point at the page element binding; generated refs/strictness counts regenerated; changeset minor+BREAKING with FROM→TO and `adr-0087: registered`. Measured producers of a view-level `provider: 'api'` outside docs: objectstack bcebd8409 0 (control `provider: 'object'` 150 files), hotcrm 0f84c9c 0 (control 5 view files), objectui f228d710 0 — `approvalRequestsDataSource.ts` builds `ApiDataSource` in code from an `ApiDataSourceConfig`, never a `ViewData` → not a fork; no producer of the `write` leg; cloud NOT MEASURED (ruling covers). `HttpRequestSchema` untouched per the ruling; after this PR no spec schema composes it (orphan reported). Draft PR awaits the maintainer's Tier H approval (`skills/**`), with the `## 维护者速读(草稿)` section; PR body second line `Clause-②: no (narrowing)` (the claim's declaration in the gate's fixed arm spelling, matching the changeset and precedent PR #22990).", "tests": "Head be64fe664 (41045ab6f + merge of origin/main 287fd6e5d via scripts/pm/os-regen-merge.sh + the hand-off regen commit). All builds/tests via scripts/pm/os-verify-lock.sh, exits captured before any pipe. ① `pnpm --filter @objectstack/spec build` → VERDICT command-exit 0 (on this head, three runs; dist stamps 04:08Z; check-dev-prereqs reds only on 53 unbuilt adapters/apps). `pnpm --filter '@objectstack/lint^...' build` + `turbo run build --filter=@objectstack/lint --filter=@objectstack/objectql` → command-exit 0. ② `pnpm --filter @objectstack/spec typecheck` → tsc + scripts-typecheck + check:test-typecheck OK (52 files / 246 errors / 135 pinned signatures held; the new pin compiles clean, 0 errors). `pnpm --filter @objectstack/spec test` → 'Test Files 660 passed (660)'. `pnpm --filter @objectstack/spec test:repo` → 'Test Files 58 passed (58) / Tests 1007 passed'. `pnpm --filter @objectstack/lint typecheck` OK; `pnpm --filter @objectstack/lint test` → 'Test Files 138 passed / Tests 6649 passed | 5 skipped'. Downstream `ViewData` importers outside spec: none in src (git grep; 2 CHANGELOG hits) → no consumer typecheck owed; full closure declared to CI. ③/④ `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on be64fe664 → 135 commands (lead list 100 + 35 new, 0 dropped); every one run with exit recorded; `--ran gates-ran-final.txt` → 'Run reconciliation — 135 derived, 132 run, 3 NOT-MEASURED, 0 UNRUN', reconcile exit 0. 131 exit 0. NOT MEASURED (exit 3, prerequisite): `pnpm --filter @objectstack/spec run check:skill-examples` (client-SDK surface needs @objectstack/client-react built; the shared lock was held by other seats for two full 9-min budgets; narrowing: neither edited block is os:check-marked — list-views.md markers 17/166/221 vs block 38–50, views.mdx markers 13/168/426/472 vs block 295, view.zod.ts has none — so its verdict is invariant under this diff; CI runs it), `pnpm check:type-check-debt` (its own core#build collided with my concurrent lock build; spec/lint tsc ran green directly), `pnpm check:dual-build-cjs-loads` (53/68 packages unbuilt; whole-workspace build is CI's). Exit 1: `pnpm check:platform-checklist` — inherited main-red (see out_of_scope_findings). Four gates refused first only on unbuilt lint/objectql and were re-run exit 0 on this head after the builds: check:doc-formula-expressions, check:doc-security-posture, check:docs-transcript-drift, check:lean-entry-closure. `pnpm --filter @objectstack/spec check:generated` on this head → 'All 14 generated artifacts are up to date' (check:docs ✓, strictness-ledger ✓, liveness ✓, test-typecheck ✓; the four ratchets api-surface/authorable-surface/export-origins/declaration-map byte-identical — the value-retirement shape). The 14 pure source audits run as one group on the built tree: all exit 0 except check:skill-examples (above). Root gates run directly: check:cross-package-test-inputs OK (after registering the pin in vitest.repo-tests.json), check-adr-0087-registration ✓ (BREAKING+bang+clause-②-narrowing, registered view-data-api-provider-retired), check-skills-token-ratchet ✓ (54 files within ceilings), check:nul-bytes OK. skills/** readings: rules/list-views.md 305→303 lines, tokens 3136→3133 (ceiling 3141); all SKILL.md sum 4409→4409; all skills/**/*.md 12570→12568. Ablation: none run — a schema narrowing with refusal pins; the pin's anti-vacuity controls (matcher positives/negatives, visited > 1000, unknown-provider control) stand in; the tsc channel is by construction (z.input loses the arm) and not separately pinned.", "mcp_calls": "0 — no MCP GitHub tool was called; all GitHub reads were `gh api` single-card/PR REST reads (issue 23082, its comments, PR 22990 body, the branch's PR query, PR 23160 read-back)", "api_writes": "2 relay strokes through scripts/pm/fleet-write/dispatch.mjs as objectstack-fleet[bot]: (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/23160/assignees (os-justin) [run 38348003472, read-back byte-identical]; (2) comment → POST /repos/objectstack-ai/objectstack/issues/23082/comments (this report). No label write (spec publishes → no skip-changeset; the dispatch named no label). git pushes (not REST): 4 to origin/claude/issue-23082-retire-view-api-source.", "deviations": [ "Clause-② line: the dispatch said the PR body's second line is `Clause-②: no`; written as `Clause-②: no (narrowing)` — same value, the arm in the gate's fixed spelling, matching the changeset (`no (narrowing)`) and precedent PR #22990; the claim's verbatim parenthetical (`a retirement narrows the accept set`) would read as prose, not as the arm.", "Run interrupted between ~03:57Z and 04:19Z (the usage wall the PM named); background jobs started before it finished on their own (gate batch 04:10Z, A2b spec test 04:19Z) and were read, not re-run; three foreground waits were auto-backgrounded by the harness at the 10-min cap (no polling, no watcher left running).", "Shared verify lock: two of my build attempts hit queue-timeout (exit 99) behind other seats' holders (plugin-security, dogfood, a later holder) — recorded as NOT MEASURED where they gated a gate (check:skill-examples), never retried in a loop.", "A1's nested `pnpm --filter '@objectstack/client-react...' build` failed with 'dist/index.js is not on disk' because the gate batch's own turbo builds (check:type-check-debt) ran concurrently outside the lock — my own concurrency, not a defect; spec dist was rebuilt by A2b's turbo build (stamps 04:08Z) and check:generated is green against it.", "One command was refused by a harness safety check (a `bash -c \"$cmd\"` loop it could not inspect); re-issued as direct commands; nothing ran under the refused form.", "No MCP writes, no PATCH of the PR body, no label writes, no assignee write on the card." ], "open_questions": [], "out_of_scope_findings": [ "class: b · reach: public door `pnpm check:platform-checklist` exits 1 on origin/main 287fd6e5d (and on this branch's base bcebd8409): 8 problems — ABSENT SYMBOL `packages/metadata-protocol/src/protocol.ts#anonymousFormIntakeOrgScopeRefusal`, `#anonymousFormIntakeReopenRefusal`, `#envWideRawViewRows`, `#countable` (all four absent from protocol.ts on main, base and head), `services/service-storage/src/attachment-access-hooks.ts#canEdit` (declared 4× but not resolved by scripts/symbol-anchors.mjs), and `areas/attachments-storage.json` SYMBOL ANCHORS LOST, 27 resolving below the floor of 28 · evidence: gatelogs/109-pnpm_check_platform_checklist.log; main commits that moved protocol.ts since the base: e5f9f0160 (#23115), c8a9783ec (#22900) · this PR touches none of those files · dedupe words: platform-checklist absent symbol anonymousFormIntakeOrgScopeRefusal envWideRawViewRows attachments-storage anchors floor · Seam: spec:docs/qa/platform-checklist/areas/*.json → runtime:scripts/check-platform-checklist.mjs | renderer: none · carrier: the lane's main-red convention (triage files it), not this card", "carrier: the objectui follow-up card (domain:spec @ objectui seat, filed when the spec release is installable) · noted, not filed: after this PR `HttpRequestSchema`/`HttpMethodSubsetSchema`/`HttpRequest`/`HttpRequestParsed` have zero schema readers in @objectstack/spec (remaining readers: the `./shared` and `./ui` re-exports and tests); their describes still say 'what view data sources may request'; objectui `packages/types` re-exports `type HttpRequest` and imports `HttpRequestSchema` in a test, so a def retirement is cross-repo — left per the ruling ('touches only the ViewDataSchema branch')", "carrier: the objectui follow-up card · noted, not filed: objectui reader population at origin/main f228d710 — ApiDataSource, resolveDataSource 'api' arm, ViewDataProvider.resolveApi, useViewData provider==='api' branches, createAuthenticatedFetch's provider:'api' lane, ObjectGantt's adapter arm, docs content/docs/plugins/plugin-gantt.mdx (teaches a gantt `data` api source), plugin-calendar.mdx/plugin-map.mdx mentions, packages/core/src/adapters/README.md; `apps/console/src/services/approvalRequestsDataSource.ts` constructs ApiDataSource directly at three sites and must be kept or re-homed by the 'delete ApiDataSource' step", "carrier: the next .objectui-sha pin bump · noted, not filed: repo-root sdui.manifest.json (generated from objectui's built tree at the pin) still describes the gantt's `data` as accepting `{ provider: 'api', read }`; regenerates with the pin, not here" ] }Generated by Claude Code
fix(spec): patch round 1 on #23082 — bare-major version stamp, four c…
objectstack-fleet commentedon Oct 13, 2026
os-dev-report
{ "issue": 23082, "status": "done", "round": "patch round 1 on PR #23160 (review 6138665801 FAIL → ① items 4, 5, 7)", "branch": "claude/issue-23082-retire-view-api-source", "pr": "https://github.com/objectstack-ai/objectstack/pull/23160", "head": "12f860316", "session": "session_01BRQ9Mp1yH7R1az6MaUM18H", "premise_still_valid": true, "summary": "Three fixes, nothing wider. ① item 4: the prescription `VIEW_DATA_API_PROVIDER_RETIRED`, the pin's `PRESCRIPTION` regex and the changeset's verbatim quotation now stamp the bare major — `was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove)` — measured as the house form: of the six prescriptions added to packages/spec/src since the v18 line opened (a87d8be29, 2026-10-08, `.changeset/pre.json` mode pre / tag next), six stamp `17`; no minor or prerelease minted; the FROM column's '17.7 and earlier' untouched. ① item 5: the four `data` describes in `packages/spec/src/ui/component.zod.ts` (ObjectGrid, ObjectMap, ObjectTree, ObjectGantt — found by the string 'discriminated on `provider`: object | api | value | schema' on the merged base) now read 'object | value | schema'; `gen:docs` regenerated `content/docs/references/ui/component.mdx` (4 lines) and `check:generated` reads 'All 14 generated artifacts are up to date' on the final HEAD; `shared/polarity-axes.ts:100` (a source-comment row) not touched. ① item 7: `packages/spec/liveness/view.json` `list.data.note` now says 'A renderer reader EXISTED in objectui, measured at 7578323a544e — `.objectui-sha` has since moved to 1fb1ced36243 and the next cross-repo re-measure re-reads it there (…)'; the `evidence` string already cited `objectui @7578323a544e …` with no pin label; the changeset says 'A renderer reader existed in objectui, measured at `7578323a544e` (…)'. Then `origin/main` dc93781c1 merged through scripts/pm/os-regen-merge.sh (clean; the seven generated pages kept on the branch's side, regenerated after), spec rebuilt, suites and the 135-gate union re-run on 12f860316. Escalations E, F, G left to the kit owner and the seat as instructed.", "pr_body_replacements_for_the_seat": [ "Line 10, the Liveness bullet — replace the two sentences `… with the pinned objectui read points. **A renderer reader existed at the objectui pin `7578323a544e`** (`ListView.tsx` routed an `api` block to `ApiDataSource`; `ObjectGantt.tsx` built one from the block's `read` / `write`) **and is now unreachable from authored metadata.**` with: `… with objectui read points cited at `7578323a544e`. **A renderer reader existed in objectui, measured at `7578323a544e`** (`.objectui-sha` on `main` is `1fb1ced36243`; the next cross-repo re-measure re-reads `ListView.tsx` / `ObjectGantt.tsx` there; `ListView.tsx` routed an `api` block to `ApiDataSource`, `ObjectGantt.tsx` built one from the block's `read` / `write`) **and is now unreachable from authored metadata.**`", "Optional, the Console Pin Gate bullet (line 25), per the review's added reading: append ` — the gate's `if:` skips every PR head, so this is unmeasured until `main` runs it after merge; the objectui-side `tsc` consequence of the narrowed `ViewData` is the follow-up's first step.`", "Line 57 (`sdui.manifest.json … at the pin`) is accurate as written (the manifest is generated at whatever pin was current) — no change." ], "tests": "HEAD 12f860316 (= be64fe664 + 2c1dd7b97 fixes + merge of origin/main dc93781c1 via os-regen-merge.sh c84246155 + the gen:docs commit). Everything through scripts/pm/os-verify-lock.sh, exits captured before any pipe. Build: `pnpm --filter @objectstack/spec build` → VERDICT command-exit 0 (c84246155 tree; dist stamps current). `pnpm --filter @objectstack/spec check:generated` → exit 1 (only check:docs stale) → `--fix` ran gen:docs → re-check 'All 14 generated artifacts are up to date'; the same command inside the gate union on 12f860316: '✓ All 14 generated artifacts are up to date — measured against packages/spec/dist AS FOUND ON DISK'. Suites on 12f860316: `pnpm --filter @objectstack/spec typecheck` (tsc, check:scripts-typecheck, check:test-typecheck) → OK; `pnpm --filter @objectstack/spec test:repo` → 'Test Files 58 passed (58) / Tests 1007 passed (1007)' (the retirement pin, its re-stamped PRESCRIPTION regex, the absence walk); `pnpm --filter @objectstack/spec test` → 'Test Files 661 passed (661)' (VERDICT command-exit 0, chained with `turbo run build --filter=@objectstack/lint --filter=@objectstack/objectql`: 14 successful). Lint suites not re-run this round: main's 8 incoming commits touch no lint file and my lint diff is unchanged since its green run (138 files / 6649 passed on be64fe664). Gates: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` on 12f860316 → 135 commands (identical set to the be64fe664 derivation); all 135 run on 12f860316 with exits recorded (`COMMAND :: exit N`), four refused first on the re-created worktree's unbuilt lint/objectql and re-run exit 0 after the builds (check:doc-formula-expressions, check:doc-security-posture, check:docs-transcript-drift, check:lean-entry-closure), check:skill-examples re-run exit 0 after `pnpm --filter '@objectstack/client-react...' build` (VERDICT command-exit 0): '✅ 263 prose examples type-check across 3 surface(s)'. `--ran` → 'Run reconciliation — 135 derived, 134 run, 1 NOT-MEASURED, 0 UNRUN', reconcile exit 0. Histogram: 133 exit 0, 1 exit 1, 1 exit 3. The exit 3: `pnpm check:dual-build-cjs-loads` NOT MEASURED (53/68 workspace packages — adapters, apps — unbuilt here; whole-workspace build is CI's). The exit 1: `pnpm check:platform-checklist`, the same 8 inherited problems (see out_of_scope_findings; main's 1ca7a805c re-pointed six other clauses and did not touch these). New this round: `pnpm check:type-check-debt` exit 0 and its `check-type-check-coverage` leg type-checked 80/82 workspace packages (1 ledgered, 2 exempt) on this head — the workspace-wide verdict on the narrowed `ViewData` type that the previous report declared to CI.", "line_budget": "skills/** unchanged this round (no skill file in the patch). Standing readings vs origin/main: skills/objectstack-ui/rules/list-views.md 305 → 303 lines, tokens ceil(bytes/4) 3136 → 3133 against ceiling 3141; all skills/*/SKILL.md sum 4409 → 4409; all hand-authored skills/**/*.md 12570 → 12568. check-skills-token-ratchet exit 0 in the union.", "files_changed": "24 files vs origin/main dc93781c1 (+634 / −250): .changeset/23082-view-data-api-provider-retired.md (A) · content/docs/references/{api/metadata,api/protocol,data/object,system/migration,ui/component,ui/view}.mdx (regenerated) · content/docs/ui/views.mdx · docs/audits/2026-07-unknown-key-strictness-ledger.counts/ui.md (regenerated) · packages/lint/src/validate-list-view-field-refs.test.ts · packages/lint/src/validate-preset-comparands.test.ts · packages/spec/liveness/view.json · packages/spec/src/migrations/entries/semantic/18.view-data-api-provider-retired.ts (A) · packages/spec/src/migrations/registry.ts.template · packages/spec/src/ui/component-props-unknown-members.pin.test.ts · packages/spec/src/ui/component.zod.ts (this round) · packages/spec/src/ui/view-data-api-provider-retirement.test.ts (A) · packages/spec/src/ui/view-strictness-batch18.test.ts · packages/spec/src/ui/view.test.ts · packages/spec/src/ui/view.zod.ts · packages/spec/variant-docs.json · packages/spec/vitest.repo-tests.json · scripts/cross-package-test-inputs.mjs · skills/objectstack-ui/rules/list-views.md. This round's own diff (2c1dd7b97 + 12f860316): view.zod.ts (1 line), view-data-api-provider-retirement.test.ts (regex + 3 comment lines), the changeset (2 lines), component.zod.ts (4 describes), view.json (1 note), content/docs/references/ui/component.mdx (regenerated, 4 lines).", "mcp_calls": "0 — no MCP GitHub tool was called; reads were `gh api` single-record REST reads (review comment 6138665801; the PR read-back from the previous round reused)", "api_writes": "1 relay stroke this round through scripts/pm/fleet-write/dispatch.mjs as objectstack-fleet[bot]: comment → POST /repos/objectstack-ai/objectstack/issues/23082/comments (this report). No PR-body PATCH (the replacement sentences are above for the seat), no label write, no assignee write. git pushes (not REST): 3 to origin/claude/issue-23082-retire-view-api-source (2c1dd7b97, 12f860316 after the merge; be64fe664 → 12f860316 is the delta the PR now carries).", "deviations": [ "The worktree had been removed at the previous round's cleanup (the os-dev cleanup step); re-created from the pushed branch at be64fe664 with `git worktree add` + `pnpm install` — the reason lint/objectql/client-react dist were absent and four gates refused on their first run before being rebuilt and re-run.", "The coordinator's interim CI reading (check:docs out of date on 2c1dd7b97) was already addressed in the working tree when it arrived: gen:docs had regenerated component.mdx and check:generated read all 14 up to date; the commit 12f860316 carries it.", "Lock contention: one build attempt waited 3m55s; no queue-timeout this round. Three foreground waits were auto-backgrounded by the harness at the 10-min cap and waited on with `tail --pid` / the completion notification; no watcher or poll loop left running.", "The gate union ran as one sequential background batch outside the lock (`check:*` commands) with the two workspace-wide gates (type-check-debt, dual-build-cjs-loads) moved last so they could not collide with my lock jobs — they did not.", "No MCP writes, no PR-body PATCH, no label writes, no assignee write on the card." ], "open_questions": [], "out_of_scope_findings": [ "class: b · reach: public door `pnpm check:platform-checklist` exits 1 on origin/main dc93781c1 and on this head alike: the same 8 problems as the previous report — ABSENT SYMBOL `packages/metadata-protocol/src/protocol.ts#anonymousFormIntakeOrgScopeRefusal`, `#anonymousFormIntakeReopenRefusal`, `#envWideRawViewRows`, `#countable`, `services/service-storage/src/attachment-access-hooks.ts#canEdit`, and `areas/attachments-storage.json` SYMBOL ANCHORS LOST, 27 resolving below the floor of 28 · main's 1ca7a805c (#23121) re-pointed six other clauses and left these · this PR touches none of those files · dedupe words: platform-checklist absent symbol anonymousFormIntakeOrgScopeRefusal envWideRawViewRows attachments-storage anchors floor · carrier: the lane's main-red convention (triage files it), not this card", "carrier: the kit owner (spec-property-retirement) · noted, not filed: escalation E (version stamp under pre mode) and F (no discriminated-union-arm helper) from review 6138665801 — followed here by measurement (bare major `17`, the #17053 hand-written `error` map shape), per the coordinator's instruction not to act on them in this PR", "carrier: a Tier H follow-up on skills/objectstack-ui/rules/pages.md (the seat) · noted, not filed: escalation G — the published catalog teaches `dataSource` nowhere; this PR's pointer relies on the prescription and views.mdx for the spelling", "carrier: the objectui follow-up card · noted, not filed (unchanged from the previous report): the HttpRequestSchema/HttpMethodSubsetSchema orphan and the objectui reader population at f228d710; `sdui.manifest.json` regenerates with the next pin bump" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 13, 2026
✅ ACCEPT: PR #23160 at
12f860316(Fixes #23082). Tier H (skills/**): it waits on the maintainer's approval, in draftdomain:specseat 2 (#18549) ·os-justin· sessionsession_01BRQ9Mp1yH7R1az6MaUM18H· 2026-10-13T07:31Z · holder of claim6136106180. Reports:6138457534,6139676792. Thread-read:6139676792.Read on GitHub:
main. Line 1 isFixes #23082and line 2 isClause-②: no (narrowing), with no other closing keyword. It changes 24 files (+634 / −250 = 884 lines). There is nocontent/docs/releases/change.check-governed-merges --pr 23160: Tier H, one path,skills/objectstack-ui/rules/list-views.md.ViewDataSchemabranch only.provider: 'api'is refused atdata.providerwith the prescription, and the three surviving arms are unchanged.HttpRequestSchemaand the page element'sapibinding are untouched. The ADR-0087 disposition is D3view-data-api-provider-retiredwith no D2: deleting a view'sdatawould silently re-bind it to its object.ApiDataSourcein code from anApiDataSourceConfig, never from aViewData. No producer of thewriteleg exists. cloud is not measured, which the maintainer's 「同意」 covers.7578323a544e"),content/docs/ui/views.mdx's pointer to/docs/ui/pages#element-data-sources, and the skill rule's two-provider text plus its one-line pointer.skills/**:list-views.mdgoes 305 → 303 lines (budget ≤ 0 held), and the SKILL.md sum is unchanged.6138665801onbe64fe664(the version stamp, fourcomponent.zod.tsdescribes, the pin label), then patch round 1, then PASS6140601222on12f860316, with all 48 check-runs complete and 0 failures.check:dual-build-cjs-loads, whose whole-workspace build is CI's).Report items, one line each:
check:platform-checklistexits 1 onmain(8 inherited anchors): not in per-PR CI by maintainer decision; the daily watchdog carries it.HttpRequestSchemaorphan, objectui's reader population and the approvals route: the carrier is the objectui follow-up, filed by thedomain:spec@ objectui seat once the spec release is installable.spec-property-retirementkit owner, and G (the skill catalog teaches the page element'sdataSourcenowhere: a Tier H follow-up onskills/objectstack-ui/rules/pages.md): recorded on the seat post for the skills lane.Tier H end-game, in this act: the PR stays draft, gains the
needs-user-decisionlabel, and carries the final 维护者速读 comment. Review is requested fromos-zhuangandhotlong. On an authorized APPROVED review, this seat runs the pre-landing checks, clears the label, and lands it through the queue. The card stayspm:dispatchedwith its assignee until MERGED.Generated by Claude Code
objectstack-fleet commentedon Oct 13, 2026
PR #23160 approved and armed by the maintainer:
os-zhuangAPPROVED at12f860316, then readied it and enabled auto-mergedomain:specseat 2 (#18549) ·os-justin· sessionsession_01BRQ9Mp1yH7R1az6MaUM18H· 2026-10-13T08:47Z · holder of claim6136106180. Thread-read:6140625376.5500991584,os-zhuang,APPROVED, on12f860316(an account inGOVERNED_APPROVERS,scripts/pm/check-governed-queue-guard.mjs). The timeline then showsready_for_reviewandauto_merge_enabledbyos-zhuangat 2026-10-13T08:46Z. These are the maintainer's own landing acts on the Tier H PR. This seat did not flip or arm it.needs-user-decisionlabel leaves the PR. The approval it waited on is in.12f860316at this read: 42 success, 10 skipped (all on the expected-skip roster), andGoverned Surface Queue Guardstill running.ApiDataSourcedeletion, which keeps or re-homes the approvals route; the cross-repo unlock rule says that waits until a spec release carrying this removal is installable. The card stayspm:dispatchedwith its assignee until MERGED.Generated by Claude Code
objectstack-fleet commentedon Oct 13, 2026
Landed: PR #23160 →
1912af47b(Fixes #23082), merged through the queue on the maintainer's approvaldomain:specseat 2 (#18549) ·os-justin· sessionsession_01BRQ9Mp1yH7R1az6MaUM18H· 2026-10-13T09:19Z · holder of claim6136106180, closed by this landing. Thread-read:6141843308.1912af47b, an ancestor oforigin/main.os-zhuangAPPROVED on12f860316, an account inGOVERNED_APPROVERS.Fixes #23082. In the merge window the one issue closed is this card,completed. Nothing else closed.pm:dispatched, anddomain:spec,area:access,priority:p2andsecuritystay. The PR'sneeds-user-decisionleft when the approval came in (6141843308).6134088274;6136106180;6138457534and6139676792;6140601222;6140625376, with the final quick-read6140642905on the PR;6141843308.ViewDataSchemarefusesprovider: 'api'with the prescriptionVIEW_DATA_API_PROVIDER_RETIRED. A metadata-declared API call is the page element'sdataSourcebinding (the spec(ui): a page element dataSource can name an API endpoint (provider: 'api'), so a product page composes from a control-plane summary in metadata instead of a product-specific React widget (maintainer ruling 2026-10-12) #23016 rule).Carried, one line each:
resolveDataSource,ListView,ObjectGantt,useViewData, theHttpRequestSchema/HttpMethodSubsetSchemare-exports): filed the view-levelapidata source is retired in @objectstack/spec (objectstack#23082): delete theViewData.provider === 'api'readers, keep the approvals inbox's code-builtApiDataSourceobjectui#12325. It ispm:on-holduntil a@objectstack/spec@nextrelease built from1912af47bor later is installable. The approvals inbox's code-builtApiDataSourceis named there as unaffected. This corrects the ACCEPT's line, which left that card to the objectui seat; cross-repo rule 3 makes it the accepting seat's to file at landing.dataSourceteaching): the skills lane's. They are noted on this seat's post ([PM seat] domain:spec · seat 2 — 🟢 os-justin · session_01BRQ9Mp1yH7R1az6MaUM18H #18549) for the round report.Generated by Claude Code