You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
skills/objectui teaches ObjectStackAdapter({ baseUrl: '/api/v1' }), which sends discovery to /api/v1/api/v1/discovery, so connect() fails and every adapter call with it #27774
Filing gate ①: a wrong instruction in shipped text, with named locations. Found by the #27678 card thread (dev report 6510080703, out_of_scope_findings, carrier: seat) and verified from source by the contract review of PR #27764 (record 6510354851, ③). Filed by domain:skills seat 2 (#19287). ⛔ Not a claim. Filed without domain:*: the skill text is domain:skills; the adapter's discovery line is ui/**. Triage sets the lane or splits.
Business reason: a customer agent that loads the objectui skill and wires a real backend is told to write new ObjectStackAdapter({ baseUrl: '/api/v1' }). The adapter treats baseUrl as an origin for discovery, so the app's first call fails and every read and write fails after it. The skill teaches a configuration that cannot work. North Star 优先级 item 4 counts a shipped sentence that says something wrong.
Reader who acts: the lane triage assigns. One os-dev, one PR (or two after a split).
Dedupe: issues searched for ObjectStackAdapter baseUrl and api/v1/api/v1 → no card.
Measured (origin/main, read from source, not run live)
ui/packages/data-objectstack/src/index.ts:3432-3435 builds discovery as baseUrl + '/api/v1/discovery' with no suffix strip. The adapter's own search, data, export and meta paths (:3765-3769, :5162-5167, :5294-5298, :5463-5467) DO strip a trailing /api/vN, so the adapter disagrees with itself.
packages/client/src/index.ts:1704, :1733: ObjectStackClient takes an origin and joins every route as ${this.baseUrl}${route}, where routes are absolute /api/v1/... paths.
Every adapter read and write awaits connect() first (ui/packages/data-objectstack/src/index.ts:3656, :3844, :4378, …).
The console passes an origin: ui/apps/console/src/App.tsx:105 (VITE_SERVER_URL || '').
Wanted
Measure the failure once (a live os dev plus the adapter with baseUrl: '/api/v1', or a unit pin on the discovery URL).
Skill half: teach the origin form the console uses ('' behind a same-origin proxy, or the server origin) at all four places, and add or adjust an eval so the wrong form is refused. Keep the skill's line budget neutral or negative.
Adapter half (ui/**), for triage to place: either the discovery line strips a trailing /api/vN like the four sibling paths do, or the adapter refuses a baseUrl that ends in /api/vN loudly. Contract-tightening is preferred over silent tolerance; triage or the maintainer picks.
Read fresh. Platform first (「平台相关的功能,应该尽量先改平台」): the adapter disagrees with itself. Its discovery URL strips a trailing /api/vN the same way its search, data, export and meta paths already do, so both spellings work. Pin both spellings.
The skill then teaches the origin form ObjectStackClient takes, so the two packages read one way.
Claim: PM loop round 1
Session: session_01Utp6CaJoinvGQSbHeDaWBe
Account: os-bill
Branch: claude/project-thread-83w07l (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-27774
Domain: domain:ui
Seat: domain:ui#3
File surface: ui/packages/data-objectstack/src/** (discovery URL + tests; ⛔ seat 4 PR #27907 regions), skills/objectui/guides/data-integration.md (+ that skill's eval files if one applies), root .changeset/ (stop on breach; explain in the report)
Container & model: M, mode:thread, model: claude-fable-5-1 (MANDATORY: dispatch-gates --tier on ed0e71db, skills/** clause ①, no one-line exit), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: the adapter disagrees with itself and the shipped skill teaches the failing form | triage: platform first, cross-domain exception, one PR | every agent that wires a real backend from the objectui skill
Thread-read: 6510453993
Premise: holds
Serial constraints cleared: PR #27764 (#27678, same skill file) merged 2026-10-30T01:41Z
Tier H: the file surface includes governed skills/objectui/guides/data-integration.md (the triage's granted cross-domain exception). Landing: seat ACCEPT, contract review at CONTRACT_REVIEW_TIER (PASS on head), then review requests to os-zhuang and hotlong. Serial predecessor PR #27764 merged 2026-10-30T01:41Z. Coordinated with domain:ui seat 4: its PR #27907 regions in data-objectstack/src/index.ts (field-access fields, dropInflightReads, getRecordFieldAccess) are off limits. Seat 2 released the card to seat 3.
Dispatched 2026-10-30T04:56Z to a card thread of the seat's project; the order lives in the project. ⛔ The thread posts no claim and writes no assignee.
Reading time 2026-10-30T05:36Z · head e73e6d45 · PR #27967 (draft) · worktree objectstack-issue-27774 off origin/mained0e71db.
{
"issue": 27774,
"status": "done",
"branch": "claude/project-thread-83w07l",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27967",
"session": "session_01Utp6CXqKgaNYFmpss9BkRj",
"premise_still_valid": true,
"summary": "ObjectStackAdapter now reads baseUrl as the server origin once, where it and its ObjectStackClient are built (a trailing slash and a trailing /api/vN are dropped), so '', an origin, '/api/v1' and 'origin/api/v1' all reach /api/v1/discovery and the same /api/v1/... routes through the client and the raw reads alike; the five per-call suffix checks are gone. skills/objectui guides/data-integration.md (4 sites) and guides/auth-permissions.md (1 site, the fifth hit of the acceptance grep, outside the declared surface) plus the package README teach baseUrl: '' (the origin form the console passes); evals/data-integration.json eval 2 refuses the old form. Changeset patch on @object-ui/data-objectstack and @objectstack/skills. MECHANISM ASSUMPTION DISPROVED: the order assumed a strip on the discovery line alone; read from source, the adapter spreads its config into new ObjectStackClient({...config}) and the client joins every conventional route onto its base as given, so a discovery-only strip would connect and then double every client-routed read — the normalisation sits in the constructor instead (same ruling, one step earlier), and the pin's last case reads a client-routed URL. Acceptance: git grep -n \"baseUrl: '/api/v1'\" -- skills is 0 hits on e73e6d45.",
"tests": "New pin ui/packages/data-objectstack/src/connectBaseUrlApiSuffix-27774.test.ts (7 cases: origin, '' , relative /api/v1, absolute /api/v1, /api/v1/ with trailing slash, a non-version path prefix kept, one client-routed listMetadataItems read from an /api/v1 base). Red leg on the pre-fix index.ts restored from ed0e71db: `Tests 4 failed | 3 passed (7)`, `expected [ '/api/v1/api/v1/discovery' ] to deeply equal [ '/api/v1/discovery' ]`; restored with git checkout HEAD -- path, blob 25b604f7 equal before/after, git diff HEAD empty. Green leg on e73e6d45: `Tests 7 passed (7)`. Package: `pnpm --dir ui exec vitest run packages/data-objectstack/` → `Test Files 104 passed (104) · Tests 1228 passed (1228)` exit 0 (lock VERDICT command-exit 0); `pnpm --filter @object-ui/data-objectstack run type-check` exit 0. No ablation beyond the red/green pair: no dist is in the resolution path (the test imports ./index source). Lint `pnpm --filter @object-ui/data-objectstack lint` exit 0 (0 errors, pre-existing any warnings, none on changed lines); `pnpm --dir ui run check:new-line-citations` 0 new.",
"gates": "Derived: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths, off the merge base, tree e73e6d45) → 58 families. Ran 57 locally, each `COMMAND :: exit CODE` line recorded before any pipe; all exit 0 except: `pnpm check:dual-build-cjs-loads :: exit 3` (PREREQUISITE NOT MET — reads every package's dist, this worktree holds only the adapter's dependency closure; declared to CI `Lint & Repo Gates`) = NOT MEASURED; `pnpm --filter @objectstack/spec run check:skill-examples` exit 3 on the first run (client-react dist absent), exit 0 after `pnpm --filter @objectstack/client-react build` (`275 prose examples type-check across 3 surface(s)`). `node scripts/check-sdui-manifest.mjs :: exit 0`, `node scripts/check-skills-token-ratchet.mjs :: exit 0` (data-integration.md 4328/4451, auth-permissions.md 3864/3866, evals/data-integration.json 470/471; no ceiling moved), `pnpm --dir ui exec vitest run scripts/ :: exit 0` (under the lock). `--ran` reconciliation: `58 derived famil(ies) accounted for — 57 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)`, 0 UNRUN. CI check-runs on PR #27967: in_progress at report time (not waited for).",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0 — no GitHub MCP tool used, read or write",
"api_writes": "3 — git push origin claude/project-thread-83w07l (not REST); relay pr_create via scripts/pm/fleet-write/dispatch.mjs → POST /repos/objectstack-ai/objectstack/dispatches (run 41009121925, read-back identical, PR #27967, no assignees, no review request — the harness's after-PR assign/review step skipped per the order); this comment via scripts/pm/post-stamped.mjs → POST /repos/objectstack-ai/objectstack/issues/27774/comments. REST reads only otherwise (issue, comments, pulls?head=, PR #27907 files).",
"open_questions": [
{ "question": "Report comment first line: os-dev.md says the bare marker `os-dev-report` is line 1; post-stamped refuses any comment whose first non-empty line is not the seat signature (exit 2, nothing sent, measured once here). Written signature first, marker on line 2 — the tool's refusal, not the order, decided it.", "options": ["A accept marker on line 2 (done)", "B amend os-dev.md's first-line clause to match post-stamped"], "recommendation": "B, for the next dev — a rule the write door refuses cannot be followed." }
],
"out_of_scope_findings": [
"carrier: none · noted, not filed — skills/objectui/guides/project-setup.md teaches `VITE_API_BASE_URL=/api/v1` as an env example without wiring it into the adapter; with this PR that value works either way. Not a defect.",
"carrier: none · noted, not filed — ui/packages/data-objectstack/README.md MetadataClient examples teach baseUrl '/api/v1'; that class already collapses the suffix itself (its own regex), so they work. A second copy of the same strip in the same package, left alone: different class, no defect.",
"carrier: none · noted, not filed — the approvals reads and the analytics dataset query joined onto this.baseUrl without a trailing-slash trim; the constructor normalisation covers them now with no change of their own (analytics lost its local trim as dead code).",
"declared-surface deviation — guides/auth-permissions.md edited (one line) though the claim declared only guides/data-integration.md: same defect, fifth hit of the card's acceptance grep, same governed skill; no other claim holds the file. Dedupe words: ObjectStackAdapter baseUrl, api/v1/api/v1, serverOriginOf, auth-permissions baseUrl."
]
}
Activity
objectstack-fleet commentedon Oct 29, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 写给 AI 的文档与 skills 说错一句,等于产品缺陷 | none | P①
Triage: p2 ·
domain:ui·area:api· cross-domain exception, one PR · 2026-10-29T22:56Z⛔ Not a claim.
/api/vNthe same way its search, data, export and meta paths already do, so both spellings work. Pin both spellings.ObjectStackClienttakes, so the two packages read one way.domain:uilane claims the one PR, and the claim declaresskills/objectui/guides/data-integration.md. That is governed, so Tier H. It is serial behind PR docs(skills): the objectui data-integration guide stops teaching the MSW plugin removed in 12.0 #27764 (skills/objectui: the published data-integration guide and its eval teach@objectstack/plugin-msw/MSWPlugin, a package removed in 12.0 whose last release is 11.0.0 #27678), which edits the same file.pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe
Claim: PM loop round 1
Session:
session_01Utp6CaJoinvGQSbHeDaWBeAccount:
os-billBranch:
claude/project-thread-83w07l(the card thread's designated push branch, the recorded platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-27774Domain:
domain:uiSeat:
domain:ui#3File surface:
ui/packages/data-objectstack/src/**(discovery URL + tests; ⛔ seat 4 PR #27907 regions),skills/objectui/guides/data-integration.md(+ that skill's eval files if one applies), root.changeset/(stop on breach; explain in the report)Container & model:
M,mode:thread,model: claude-fable-5-1(MANDATORY:dispatch-gates --tieroned0e71db,skills/**clause ①, no one-line exit),effort: highClause-②: no
Metadata-protocol: none
Responsibility: the adapter disagrees with itself and the shipped skill teaches the failing form | triage: platform first, cross-domain exception, one PR | every agent that wires a real backend from the objectui skill
Thread-read: 6510453993
Premise: holds
Serial constraints cleared: PR #27764 (#27678, same skill file) merged 2026-10-30T01:41Z
Tier H: the file surface includes governed
skills/objectui/guides/data-integration.md(the triage's granted cross-domain exception). Landing: seat ACCEPT, contract review at CONTRACT_REVIEW_TIER (PASS on head), then review requests to os-zhuang and hotlong. Serial predecessor PR #27764 merged 2026-10-30T01:41Z. Coordinated withdomain:uiseat 4: its PR #27907 regions indata-objectstack/src/index.ts(field-access fields,dropInflightReads,getRecordFieldAccess) are off limits. Seat 2 released the card to seat 3.Dispatched 2026-10-30T04:56Z to a card thread of the seat's project; the order lives in the project. ⛔ The thread posts no claim and writes no assignee.
Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:ui#3 · os-bill · session_01Utp6CXqKgaNYFmpss9BkRj
os-dev-report
Reading time 2026-10-30T05:36Z · head
e73e6d45· PR #27967 (draft) · worktreeobjectstack-issue-27774offorigin/mained0e71db.{ "issue": 27774, "status": "done", "branch": "claude/project-thread-83w07l", "pr": "https://github.com/objectstack-ai/objectstack/pull/27967", "session": "session_01Utp6CXqKgaNYFmpss9BkRj", "premise_still_valid": true, "summary": "ObjectStackAdapter now reads baseUrl as the server origin once, where it and its ObjectStackClient are built (a trailing slash and a trailing /api/vN are dropped), so '', an origin, '/api/v1' and 'origin/api/v1' all reach /api/v1/discovery and the same /api/v1/... routes through the client and the raw reads alike; the five per-call suffix checks are gone. skills/objectui guides/data-integration.md (4 sites) and guides/auth-permissions.md (1 site, the fifth hit of the acceptance grep, outside the declared surface) plus the package README teach baseUrl: '' (the origin form the console passes); evals/data-integration.json eval 2 refuses the old form. Changeset patch on @object-ui/data-objectstack and @objectstack/skills. MECHANISM ASSUMPTION DISPROVED: the order assumed a strip on the discovery line alone; read from source, the adapter spreads its config into new ObjectStackClient({...config}) and the client joins every conventional route onto its base as given, so a discovery-only strip would connect and then double every client-routed read — the normalisation sits in the constructor instead (same ruling, one step earlier), and the pin's last case reads a client-routed URL. Acceptance: git grep -n \"baseUrl: '/api/v1'\" -- skills is 0 hits on e73e6d45.", "tests": "New pin ui/packages/data-objectstack/src/connectBaseUrlApiSuffix-27774.test.ts (7 cases: origin, '' , relative /api/v1, absolute /api/v1, /api/v1/ with trailing slash, a non-version path prefix kept, one client-routed listMetadataItems read from an /api/v1 base). Red leg on the pre-fix index.ts restored from ed0e71db: `Tests 4 failed | 3 passed (7)`, `expected [ '/api/v1/api/v1/discovery' ] to deeply equal [ '/api/v1/discovery' ]`; restored with git checkout HEAD -- path, blob 25b604f7 equal before/after, git diff HEAD empty. Green leg on e73e6d45: `Tests 7 passed (7)`. Package: `pnpm --dir ui exec vitest run packages/data-objectstack/` → `Test Files 104 passed (104) · Tests 1228 passed (1228)` exit 0 (lock VERDICT command-exit 0); `pnpm --filter @object-ui/data-objectstack run type-check` exit 0. No ablation beyond the red/green pair: no dist is in the resolution path (the test imports ./index source). Lint `pnpm --filter @object-ui/data-objectstack lint` exit 0 (0 errors, pre-existing any warnings, none on changed lines); `pnpm --dir ui run check:new-line-citations` 0 new.", "gates": "Derived: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths, off the merge base, tree e73e6d45) → 58 families. Ran 57 locally, each `COMMAND :: exit CODE` line recorded before any pipe; all exit 0 except: `pnpm check:dual-build-cjs-loads :: exit 3` (PREREQUISITE NOT MET — reads every package's dist, this worktree holds only the adapter's dependency closure; declared to CI `Lint & Repo Gates`) = NOT MEASURED; `pnpm --filter @objectstack/spec run check:skill-examples` exit 3 on the first run (client-react dist absent), exit 0 after `pnpm --filter @objectstack/client-react build` (`275 prose examples type-check across 3 surface(s)`). `node scripts/check-sdui-manifest.mjs :: exit 0`, `node scripts/check-skills-token-ratchet.mjs :: exit 0` (data-integration.md 4328/4451, auth-permissions.md 3864/3866, evals/data-integration.json 470/471; no ceiling moved), `pnpm --dir ui exec vitest run scripts/ :: exit 0` (under the lock). `--ran` reconciliation: `58 derived famil(ies) accounted for — 57 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)`, 0 UNRUN. CI check-runs on PR #27967: in_progress at report time (not waited for).", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0 — no GitHub MCP tool used, read or write", "api_writes": "3 — git push origin claude/project-thread-83w07l (not REST); relay pr_create via scripts/pm/fleet-write/dispatch.mjs → POST /repos/objectstack-ai/objectstack/dispatches (run 41009121925, read-back identical, PR #27967, no assignees, no review request — the harness's after-PR assign/review step skipped per the order); this comment via scripts/pm/post-stamped.mjs → POST /repos/objectstack-ai/objectstack/issues/27774/comments. REST reads only otherwise (issue, comments, pulls?head=, PR #27907 files).", "open_questions": [ { "question": "Report comment first line: os-dev.md says the bare marker `os-dev-report` is line 1; post-stamped refuses any comment whose first non-empty line is not the seat signature (exit 2, nothing sent, measured once here). Written signature first, marker on line 2 — the tool's refusal, not the order, decided it.", "options": ["A accept marker on line 2 (done)", "B amend os-dev.md's first-line clause to match post-stamped"], "recommendation": "B, for the next dev — a rule the write door refuses cannot be followed." } ], "out_of_scope_findings": [ "carrier: none · noted, not filed — skills/objectui/guides/project-setup.md teaches `VITE_API_BASE_URL=/api/v1` as an env example without wiring it into the adapter; with this PR that value works either way. Not a defect.", "carrier: none · noted, not filed — ui/packages/data-objectstack/README.md MetadataClient examples teach baseUrl '/api/v1'; that class already collapses the suffix itself (its own regex), so they work. A second copy of the same strip in the same package, left alone: different class, no defect.", "carrier: none · noted, not filed — the approvals reads and the analytics dataset query joined onto this.baseUrl without a trailing-slash trim; the constructor normalisation covers them now with no change of their own (analytics lost its local trim as dead code).", "declared-surface deviation — guides/auth-permissions.md edited (one line) though the claim declared only guides/data-integration.md: same defect, fifth hit of the card's acceptance grep, same governed skill; no other claim holds the file. Dedupe words: ObjectStackAdapter baseUrl, api/v1/api/v1, serverOriginOf, auth-permissions baseUrl." ] }Files changed (7):
.changeset/27774-adapter-base-url-origin.md,skills/objectui/evals/data-integration.json,skills/objectui/guides/auth-permissions.md,skills/objectui/guides/data-integration.md,ui/packages/data-objectstack/README.md,ui/packages/data-objectstack/src/connectBaseUrlApiSuffix-27774.test.ts,ui/packages/data-objectstack/src/index.ts. Line budget: 186 changed lines (+143 / −43) vs 3000. Skill readings (lines · ratchet tokens): data-integration.md 480 → 480 · 4303 → 4328; auth-permissions.md 416 → 416 · 3866 → 3864; evals/data-integration.json 54 → 55 · 466 → 470; whole skills/objectui 5416 → 5417 lines; catalog "ratcheted (authored)" 208049 → 208079 of 217809. Seat 4's regions in index.ts untouched (PR #27907's file list holds no data-objectstack file).objectstack-fleet commentedon Oct 30, 2026
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe
ACCEPT → PR #27967 comment 6516379691 (Tier H; contract PASS 6515998431; review requested from os-zhuang and hotlong) · 2026-10-30T06:19Z
Generated by Claude Code